1、BitmapFactory.Options中的属性

在进行图片压缩时,是通过设置BitmapFactory.Options的一些值来改变图片的属性的,下面我们来看看BitmapFactory.Options中常用的属性意思:

  • options.inPreferredConfig - 设置Bitmap的偏好配置,值有Bitmap.Config.ARGB_8888,Bitmap.Config.ARGB_4444,Bitmap.Config.ARGB_8888,Bitmap.Config.RGB_565。默认为ARGB_8888,顾名思义,这是设置Bitmap的显示质量的。
  • options.outHeight - 得到该Bitmap的高。
  • options.outWidth - 得到该Bitmap的宽。
  • options.outMimeType - 得到该Bitmap的MIME值。
  • options.inSampleSize - 压缩比例,如果options.inSampleSize = 4;那么压缩后的图片的宽和高都为原来图片的1/4,压缩后的图片的像素为原来图片的1/16。
  • options.inJustDecodeBounds  - 官方文档上是这样介绍的:
      • If set to true, the decoder will return null (no bitmap), but

        the out... fields will still be set, allowing the caller to query

        the bitmap without having to allocate the memory for its pixels.
      • 意思就是:如果设置为true,那么使用BitmapFactory.decodeStream(InputStream is, Rect outPadding, 

        Options opts)或BitmapFactory.decodeXXX(....,Options opts)方法并不会真的返回一个Bitmap对象,而是返回null,虽然返回null,但是我们却可以通过options来获得该Bitmap的一些值,如它的宽、高、MimeType等值。这样就不必为Bitmap对象分配内存空间也可以获得它的Width和Height,从而节约内存。所以这个属性对我们压缩图片前进行检查大有帮助。常用的技巧就是为了避免图片过大而导致OOM,所以在我们加载图片之前就通过设置它为true,获取到图片的宽、高等值,然后进行一些判断检查等,决定图片是否压缩。我们来看看加载一张405x579图片的例子:
      • final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        Bitmap bitmap = BitmapFactory.decodeResource(getResource(), R.mipmap.two, options);
        Log.v("zxy","bitmap="+bitmap);
        int height = options.outHeight;
        int width = options.outWidth;
        String mimeType = options.outMimeType;
        Log.v("zxy","mimeType="+mimeType+",height="+height+",width="+width);

        上述代码输出的是:可以知道确实是返回null了,而且还获得了该Bitmap的宽高等值。

2、通过实例来看看怎么压缩图片

public class MainActivity extends ActionBarActivity {
    private ImageView mImageView, mResizeImageView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mImageView = (ImageView) findViewById(R.id.imageView);
        mResizeImageView = (ImageView) findViewById(R.id.resize_imageView);
        mImageView.setImageBitmap(BitmapFactory.decodeResource(getResources(),R.mipmap.two));

        Bitmap bitmap = compressBitmap(getResources(), R.mipmap.two, 100, 100);
        Log.v("zxy", "compressBitmap,width=" + bitmap.getWidth() + ",height=" + bitmap.getHeight());
        mResizeImageView.setImageBitmap(bitmap);
    }

    /**
     * @param res Resource
     * @param resId 资源id
     * @param targetWidth 目标图片的宽,单位px
     * @param targetHeight 目标图片的高,单位px
     * @return 返回压缩后的图片的Bitmap
     */
    public Bitmap compressBitmap(Resources res, int resId, int targetWidth, int targetHeight) {
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;//设为true,节约内存
        BitmapFactory.decodeResource(res, resId, options);//返回null
        int height = options.outHeight;//得到源图片height,单位px
        int width = options.outWidth;//得到源图片的width,单位px
        //计算inSampleSize
        options.inSampleSize = calculateInSampleSize(width,height,targetWidth,targetHeight);
        options.inJustDecodeBounds = false;//设为false,可以返回Bitmap
        return BitmapFactory.decodeResource(res,resId,options);
    }

    /**
     * 计算压缩比例
     * @param width  源图片的宽
     * @param height 源图片的高
     * @param targetWidth  目标图片的宽
     * @param targetHeight 目标图片的高
     * @return inSampleSize 压缩比例
     */
    public int calculateInSampleSize(int width,int height, int targetWidth, int targetHeight) {
        int inSampleSize = 1;
        if (height > targetHeight || width > targetWidth) {
            //计算图片实际的宽高和目标图片宽高的比率
            final int heightRate = Math.round((float) height / (float) targetHeight);
            final int widthRate = Math.round((float) width / (float) targetWidth);
            //选取最小的比率作为inSampleSize
            inSampleSize = heightRate < widthRate ? heightRate : widthRate;
        }
        return inSampleSize;
    }
}

我们通过看Log可以知道压缩后图片的宽高:



我们再看看效果图:

Android中处理大图片时图片压缩的更多相关文章

  1. Android中 在显示ImageView时图片上面和下面都出现一段空白区间的解决办法

    开始的时候是在ScrollView中显示ImageView的时候出现这样的问题,以为是要对ScrollView进行设置的,后来发现单独显示一个ImageView的时候也会出现这样的问题,由此才知道是应 ...

  2. Android 中Activity生命周期分析:Android中横竖屏切换时的生命周期过程

    最近在面试Android,今天出了一个这样的题目,即如题: 我当时以为生命周期是这样的: onCreate --> onStart -- ---> onResume ---> onP ...

  3. Android ListView分页加载时图片显示问题

    场景:Android ListView需要分页加载,每个item中会有图片,图片又是从网络下载的. 问题:在滑动加载下一页时,上一页的图片明明已经下载完成了,但是无法显示出来. Bug重现: 1,加载 ...

  4. Android中的Glide加载图片

    注意:在Android Studio的项目的build.gradle中添加: compile 'com.github.bumptech.glide:glide:3.6.1' 然后同步一下 目录: 使用 ...

  5. CSS3实现鼠标经过图片时图片放大

    在鼠标经过图片时,图片被放大,而且还有个过渡的效果.... <!DOCTYPE html> <html> <head> <link href="cs ...

  6. wpf RenderTargetBitmap保存控件为图片时图片尺寸不对的问题

    使用RenderTargetBitmap渲染图片时,必须在需要渲染的控件外层包含一个border控件,不然渲染的图片返回就会出现问题. 如下: <Grid> <Grid.RowDef ...

  7. Android中实现照片滑动时左右进出的动画的xml代码

    场景 Android中通过ImageSwitcher实现相册滑动查看照片功能(附代码下载): https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/det ...

  8. Android中ListView异步加载图片错位、重复、闪烁问题分析及解决方案

    我们在使用ListView异步加载图片的时候,在快速滑动或者网络不好的情况下,会出现图片错位.重复.闪烁等问题,其实这些问题总结起来就是一个问题,我们需要对这些问题进行ListView的优化. 比如L ...

  9. 百度ueditor中复制word图文时图片转存任然保持灰色不可用

    官网地址http://ueditor.baidu.com Git 地址 https://github.com/fex-team/ueditor 参考博客地址 http://blog.ncmem.com ...

随机推荐

  1. Swift运行时简介

    因为Swift的操作在高层并且也得与Objc联合起来干活,用Swift写的程序一般会被Objc和Swift运行时处理.因为Swift的本性--换句话说,它是一门静态语言--Swift运行时在一些关键地 ...

  2. OpenCV+OpenGL 双目立体视觉三维重建

    0.绪论 这篇文章主要为了研究双目立体视觉的最终目标--三维重建,系统的介绍了三维重建的整体步骤.双目立体视觉的整体流程包括:图像获取,摄像机标定,特征提取(稠密匹配中这一步可以省略),立体匹配,三维 ...

  3. Xcode8出现的一些常见问题

    消除无用输出语句问题:Xcode8之后,新创建的项目在手机上运行后,就会在输出窗口,输出一大堆乱七八糟的日志,对我们几乎没有用,如图: 解决办法: [product]-[scheme]-[Edit S ...

  4. Intellij IDEA 插件开发之自建插件仓库

    Intellij IDEA 有一个自己的官方的插件仓库,但是当我们的开发的 Intellij IDEA 的插件不能够对外公开时,我们就需要搭建自己的 Intellij IDEA 的插件仓库.前不久我们 ...

  5. Cocos2D中节点Z序的计算规则

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 免责申明:本博客提供的所有翻译文章原稿均来自互联网,仅供学习交 ...

  6. 关于MT8127中sdk的编译出错问题

    今天在看MTK提供的SDK编译文档,按照步骤做,结果出错了,文档如下: 2- Building an SDK for MacOS and Linux ------------------------- ...

  7. JDBC编程-事务编程(四)

    事务的概念 事务的概念在我看来是指的是一组sql序列,这个序列是一块执行的单位,要么全部执行,要不全部执行,这样可以很好的对数据库进行并发控制. 因为数据库是多个用户都可以同时操作的,如果多个用户同时 ...

  8. 关闭Win10自动更新

    使用过Windows10系统的小伙伴们都清楚,在Windows10中强制开启了自动更新功能,我们无法通过常规的办法关闭自动更新功能,那么我们该怎么去关闭自动更新呢?欢迎速来围观我的经验啦. 工具/原料 ...

  9. Linux下which、whereis、locate、find 命令查找文件

     转自:http://blog.csdn.net/gh320/article/details/17411743 我们经常在linux要查找某个文件,但不知道放在哪里了,可以使用下面的一些命令来搜索 ...

  10. Xcode中使用数据(硬件)断点调试

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 在Xcode的GUI界面中只能添加软断点,而无法增加硬断点.但 ...