Android中的图片压缩

摘要:
例如,480*320映像占用的堆内存大小为480*320*4/1024=600kB。它乘以4的原因是Android中使用的ARGB图像每像素使用四个字节。

1、android中计算图片占用堆内存的kB大小跟图片本身的kB大小无关,而是根据图片的尺寸来计算的。

      比如一张 480*320大小的图片占用的堆内存大小为:

      480*320*4/1024=600kB  之所以要乘以4,是因为在android中使用的ARGB图片,图片一个像素占用四个字节。

2、手机出厂时 堆内存(Heap)是固定的,所以为了不造成OOM,我们就需要生成bitmap时对图片进行压缩处理。

         实际使用中我们压缩图片的标准是手机屏幕大小作为参照的,这个主要是因为,即便是图片尺寸跟屏幕尺寸相同,换算出来所占的内存大小也要远小于手机堆存。

         为了讲解方便,我们就以 480*320大小的手机为例,图片压缩为同手机屏幕同尺寸时,所占的大小为 600kb,也就是0.6M,而480*320的手机的出厂heap一般是16M,这个数字根据每个厂商有所差异。

3、压缩方式:通过bitmap的options

       首先大家要知道,当图片太大造成加载时,报OOM异常是在哪个地方报的?

       打印测试知道是在:Bitmap bitmap =  BitmapFactory.decodeFile(url)这行就报错。所以我们的处理如下:

        

/**
     * 压缩图片
     *
     * @param photoPath
     */
    public static Bitmap compressImage(Activity act, String photoPath) {
        int screenWidth = act.getWindowManager().getDefaultDisplay().getWidth();
        int screenHeight = act.getWindowManager().getDefaultDisplay().getHeight();
        LogUtils.logInfoStar("screenWidth为" + screenWidth + "------screenHeight" + screenHeight);
        BitmapFactory.Options opts = new BitmapFactory.Options();
        opts.inJustDecodeBounds = true;//设置为true的目的,拿到图片的一些附属信息
        BitmapFactory.decodeFile(photoPath, opts);
        int imgWidth = opts.outWidth;
        int imgHeight = opts.outHeight;
//获取屏幕尺寸的方式二:支持13以上版本,就是使用point存储宽高,然后再取出来。  
// Point point=new Point();
// getWindowManager().getDefaultDisplay().getSize(point);
// screenWidth=point.x; 8 // screenHeight=point.y;
LogUtils.logInfoStar(
"图片原大小" + "imgWidth为:" + imgWidth + "imgHeight" + imgHeight); //按屏幕大小获取的压缩比例,加入判断,只有图片尺寸大于屏幕尺寸时才压缩 if (imgHeight > screenHeight || imgWidth > screenWidth) { int sizeByScreenSize = imgWidth / screenWidth > imgHeight / screenHeight ? imgWidth / screenWidth : imgHeight / screenHeight; //再在此基础把压缩比例增大10倍 opts.inSampleSize = sizeByScreenSize * 10; LogUtils.logInfoStar("inSampleSize" + sizeByScreenSize); } else { opts.inSampleSize = 1; } opts.inJustDecodeBounds = false; Bitmap mImage = BitmapFactory.decodeFile(photoPath, opts); return mImage; }

 总结:

     

##缩放加载大图片
1.获取你想显示的图片应该有的大小,如果是全屏,就获取屏幕大小

2.获取图片的原始大小,不将图片真正加载到内存,只拿到图片的附属信息
Options opts = new Options();
设置为true,不加在内存,只拿信息
opts.inJustDecodeBounds = true;
3.对图片做压缩处理,压缩的前提是图片的大小大于你要显示的区域大小
按照宽或者高的比例进行计算,选择比例大的那个进行压缩
压缩的比例值最后复制给
opts.inSampleSize = scale;
4.比例设置完之后,这时候才是真正的去加载图片到内存当中
opts.inJustDecodeBounds = false;
5.最后一部才是加载图片
Bitmap bitmap = BitmapFactory.decodeFile("/mnt/sdcard/dog.jpg", opts);

我们做这么多操作的最终目的其实就是为了要opts.inSampleSize = scale这个值。

免责声明:文章转载自《Android中的图片压缩》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇MessageBox、::MessageBox 、AfxMessageBox三者的区别 .UWP 应用获取各类系统、用户信息 (2)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

C#实现图片的无损压缩

/// <summary> /// 图像缩略图处理 /// </summary> /// <param name="bytes">图像源数据</param> /// <param name="compression">压缩质量 1-100</param> /// <param...

vue Base64图片压缩上传OSS

this.compress(result, 800, 0.5).then(val => { //得到压缩图片 let data = val; that.file = that.dataURLtoFile(data, that.file_name); //上传 that.up...

GIF/PNG/JPG和WEBP/base64/apng图片优点和缺点整理

  GIF/PNG/JPG/WEBP/APNG都是属于位图(位图 ,务必区别于矢量图);   GIF/PNG和JPG这三种格式的图片被广泛应用在现今的互联网中,gif曾在过去互联网初期慢速的情况下几乎是做到了大一统的地位,而现如今随着互联网技术应用和硬件条件的提高,png和jpg格式的图片越来越多的被应用,gif昔日的辉煌一去不复, webp图片格式现在还...

iOS图片压缩

项目中常会遇到,上传图片的操作,由于iPhone手机直接拍照的图片往往比较大,一般3-4M,如果直接上传不做处理会浪费用户很多流量,再者有很多场景并不需要高清图片,所以在上传图片前对图片进行压缩,是很有必要的。 1.OC中的UIKit中提供了现成的压缩函数UIImageJPEGRepresentation(UIImage * __nonnull image...

移动端 H5 拍照 从手机选择图片,移动端预览,图片压缩,图片预览,再上传服务器

前言:最近公司的项目在做全网营销,要做非微信浏览器的wap 站 的改版,其中涉及到的一点技术就是采用H5 选择手机相册中的图片,或者拍照,再将获取的图片进行压缩之后上传。 这个功能模块主要有这5点比较难:   1手机获取相册的图片文件,拍照的图片文件,通过js 的自带的img对象,获取图片对象。     2.图片的压缩,采用canvas 画布进行压缩图片,...

前端开发中常用的几种图片格式及其使用规范

在介绍图片格式之前,首先说一些额外的东西。 矢量图与位图。 矢量图是通过组成图形的一些基本元素,如点、线、面,边框,填充色等信息通过计算的方式来显示图形的。一般来说矢量图表示的是几何图形,文件相对较小,并且放大缩小不会失真。 这里有一点要注意的是web开发中用到的图片都不是矢量图,即使是一个三角形,只有一个边框,都是位图。 那么矢量图在哪里有用到呢? 我目...