Android中处理大图片时图片压缩
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的宽高等值。
 - If set to true, the decoder will return null (no bitmap), but
 
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中处理大图片时图片压缩的更多相关文章
- Android中 在显示ImageView时图片上面和下面都出现一段空白区间的解决办法
		
开始的时候是在ScrollView中显示ImageView的时候出现这样的问题,以为是要对ScrollView进行设置的,后来发现单独显示一个ImageView的时候也会出现这样的问题,由此才知道是应 ...
 - Android 中Activity生命周期分析:Android中横竖屏切换时的生命周期过程
		
最近在面试Android,今天出了一个这样的题目,即如题: 我当时以为生命周期是这样的: onCreate --> onStart -- ---> onResume ---> onP ...
 - Android ListView分页加载时图片显示问题
		
场景:Android ListView需要分页加载,每个item中会有图片,图片又是从网络下载的. 问题:在滑动加载下一页时,上一页的图片明明已经下载完成了,但是无法显示出来. Bug重现: 1,加载 ...
 - Android中的Glide加载图片
		
注意:在Android Studio的项目的build.gradle中添加: compile 'com.github.bumptech.glide:glide:3.6.1' 然后同步一下 目录: 使用 ...
 - CSS3实现鼠标经过图片时图片放大
		
在鼠标经过图片时,图片被放大,而且还有个过渡的效果.... <!DOCTYPE html> <html> <head> <link href="cs ...
 - wpf RenderTargetBitmap保存控件为图片时图片尺寸不对的问题
		
使用RenderTargetBitmap渲染图片时,必须在需要渲染的控件外层包含一个border控件,不然渲染的图片返回就会出现问题. 如下: <Grid> <Grid.RowDef ...
 - Android中实现照片滑动时左右进出的动画的xml代码
		
场景 Android中通过ImageSwitcher实现相册滑动查看照片功能(附代码下载): https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/det ...
 - Android中ListView异步加载图片错位、重复、闪烁问题分析及解决方案
		
我们在使用ListView异步加载图片的时候,在快速滑动或者网络不好的情况下,会出现图片错位.重复.闪烁等问题,其实这些问题总结起来就是一个问题,我们需要对这些问题进行ListView的优化. 比如L ...
 - 百度ueditor中复制word图文时图片转存任然保持灰色不可用
		
官网地址http://ueditor.baidu.com Git 地址 https://github.com/fex-team/ueditor 参考博客地址 http://blog.ncmem.com ...
 
随机推荐
- DOS界面下的翻译软件制作
			
准备 素材 依赖 接口 地址 参数 返回值解析 编码及测试 功能代码 运行脚本 环境变量 结果展示 英语转汉语 汉语转英语 总结 昨天看到一篇关于Linux下的桌面词典的文章,于是就想实现一个Wind ...
 - 理解性能的奥秘——应用程序中慢,SSMS中快(3)——不总是参数嗅探的错
			
本文属于<理解性能的奥秘--应用程序中慢,SSMS中快>系列 接上文:理解性能的奥秘--应用程序中慢,SSMS中快(2)--SQL Server如何编译存储过程 在我们开始深入研究如何处理 ...
 - Java异常处理-----程序中的异常处理.启蒙
			
1.当除数是非0,除法运算完毕,程序继续执行. 2.当除数是0,程序发生异常,并且除法运算之后的代码停止运行.因为程序发生异常需要进行处理. class Demo { public static vo ...
 - Leetcode解题-链表(2.2.1)AddTwoNumbers
			
1 题目:2.2.1 Add Two Numbers You are given two linked lists representing two non-negative numbers. The ...
 - 这一次,VR离我们真的很近
			
从高考作文开始 今年号称是VR元年,虽然目前VR还没能像手机一样走进千家万户,但关于VR设备的关讨论是层出不穷.而今年高考,浙江省的作文题就与VR相关.网上购物.视频聊天等在 ...
 - [Mysql]由Data truncated for column联想到的sql_mode配置
			
系统日志中出现了 ata truncated for column 'agent' at row 1 mysql出现这个问题的原因,无非就是字符集设置 或者是 字段过长导致的. mysql在初始化的时 ...
 - SQLite AND/OR 运算符(http://www.w3cschool.cc/sqlite/sqlite-and-or-clauses.html)
			
SQLite AND/OR 运算符 SQLite 的 AND 和 OR 运算符用于编译多个条件来缩小在 SQLite 语句中所选的数据.这两个运算符被称为连接运算符. 这些运算符为同一个 SQLite ...
 - 微软Telnet的回显功能开启
			
win7和XP系统默认telnet的回显功能是关闭的.启用telnet回显功能:(1)首先进入命令行界面:输入telnet(2)进入Microsoft Telnet>命令提示符下,输入:set ...
 - android 特卖列表倒计时卡顿问题
			
在Android的开发中,我们经常遇见倒计时的操作,通常使用Timer和Handler共同操作来完成.当然也可以使用Android系统控件CountDownTimer,这里我们封装成一个控件,也方便大 ...
 - Android开发学习之路--Android系统架构初探
			
环境搭建好了,最简单的app也运行过了,那么app到底是怎么运行在手机上的,手机又到底怎么能运行这些应用,一堆的电子元器件最后可以运行这么美妙的界面,在此还是需要好好研究研究.这里从芯片及硬件模块-& ...