android大图、高清图片处理

Android大图、高清图片处理


Android中,系统分配给手机app的内存是有限的,现阶段根据不同的手机分配的最大内存也不一样,少的只有几十M。当我们Bitmap的形式把高清的大图加载到内存当中时,它占用的内存会成倍数的增加。占用的内存超过了系统能够提供给app的内存时,会产生OOM。


1、图片占用内存的估计计算(并非实际值):

占用的内存 = 图片长度 * 图片宽度 * 单位像素占用的字节数


图片格式:

ALPHA_8 :      1byte            只存储alpha

ARGB_4444:   2byte       图片有可能会被破坏,效果差

ARGB_8888:    4byte      主流的存储方式

RGB_565:        2byte       不考虑alpha时推荐使用


2、pngjpg图片的选择

png:能用png最好是用png,32位的png颜色过渡平滑且支持透明。

jpg:是像素化压缩过的图片,质量已经下降了,一般不拿来做.9path的平铺拉伸的控件。

对于颜色繁杂的,比如照片墙纸,启动页面之类的图片,可用jpg。如果保存成png体积将是jpg的几倍甚至几十倍,严重浪费体积。其他的资源文件使用png


3、像素压缩法

可以按照当前view的大小进行压缩,压缩成缩略图显示在view中,减少内存的消耗,防止OOM,同时保证图片不失真。

设置opts.inJustDecodeBounds= true时,图片的读取不会写入内存,可以获取图片的大小,从而设置需要压缩的Optios参数;opts.inJustDecodeBounds= false时图片的读取会写入内存中。


/**
 * 对资源中的大图片进行分辨率大小的压缩
 * @param context
 * @param resourceId   资源的id
 * @param view          显示图片的控件Imageview
 */
public static void setImageResource(Context context, int resourceId, ImageView view)
{
    BitmapFactory.Options opts = new BitmapFactory.Options();
    // 不读取像素数组到内存中,仅读取图片的信息
    opts.inJustDecodeBounds = true;
    BitmapFactory.decodeResource(context.getResources(), resourceId,opts);
    // 从Options中获取图片的分辨率
    int imageHeight = opts.outHeight;
    int imageWidth = opts.outWidth;

    int scaleX;
    int scaleY;

    // 计算采样率
    if(view.getWidth() > 0 && view.getHeight() > 0)
    {
        //采用view的尺寸对应得大小进行压缩
        scaleX = imageWidth / view.getWidth();
        scaleY = imageHeight / view.getHeight();
    }
    else
    {
        //view未初始化完成,获得的宽高为0,采用屏幕的分辨率尺寸来进行压缩
        WindowManager wm = (WindowManager) context.getSystemService(context.WINDOW_SERVICE); 
        scaleX = imageWidth / wm.getDefaultDisplay().getWidth();
        scaleY = imageHeight / wm.getDefaultDisplay().getHeight();
    }
    int scale = 1;
    // 采样率依照最大的方向为准
    if (scaleX > scaleY && scaleY >= 1) {
        scale = scaleX;
    }
    if (scaleX < scaleY && scaleX >= 1) {
        scale = scaleY;
    }
    Log.e("measure","scale = "+scale);
    // false表示读取图片像素数组到内存中,依照设定的采样率
    opts.inJustDecodeBounds = false;
    // 采样率
    opts.inSampleSize = scale;
    opts.inPreferredConfig = Bitmap.Config.ARGB_8888;
    Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),R.mipmap.larg,opts);
    view.setImageBitmap(bitmap);
}

opts.inSampleSize= scale;为设置采样率,scale的最终等级为2的n次方,如1,2,4,8....;如果是scale为2,3,最终系统都会取2作为采样率;如果是4,5,6,7系统会自动取4作为采样率....



如上图所示,opts.inSampleSize设置为2则占用内存约为未压缩前的1/4,设置为4则为未压缩前的1/16 ..... 对应的压缩率最好是通过view在手机上的显示大小进行计算,这样可以更好的适配到手机上,不影响显示效果。


2、质量压缩法

用于压缩后保存在disk下,会破坏图片的质量,不会改变图片的大小尺寸。但占用的内存不会减少,通常用于压缩上传服务器的图片。

    /**
     * 质量压缩方法
     *
     * @param image
     * @return
     */
    private static Bitmap compressImage(Bitmap image) {

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
        int options = 100;
        while (baos.toByteArray().length / 1024 > 100 && options > 50) {
            baos.reset();
            image.compress(Bitmap.CompressFormat.JPEG, options, baos);
            options -= 10;
        }
        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
        Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);

        return bitmap;
    }

图片上传服务器:

1、图片进行像素压缩

2、图片进行质量压缩

3、本地保存

4、上传服务器

5、上传成功后删除本地图片




  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值