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的宽高等值。

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能够知道压缩后图片的宽高:

我们再看看效果图:

时间: 2024-11-05 12:20:20

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

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

开始的时候是在ScrollView中显示ImageView的时候出现这样的问题,以为是要对ScrollView进行设置的,后来发现单独显示一个ImageView的时候也会出现这样的问题,由此才知道是应该对ImageView进行设置啦- 解决办法如下喽- 1.在XML文件中设置: android:adjustViewBounds="true" 2.在Java代码中进行设置: mImageView.setAdjustViewBounds(true);

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

Android中ListView异步加载图片错位.重复.闪烁问题分析及解决方案 我们在使用ListView异步加载图片的时候,在快速滑动或者网络不好的情况下,会出现图片错位.重复.闪烁等问题,其实这些问题总结起来就是一个问题,我们需要对这些问题进行ListView的优化. 比如ListView上有100个Item,一屏只显示10个Item,我们知道getView()中convertView是用来复用View对象的,因为一个Item的对应一个View对象,而ImageView控件就是View对象通

Android中使用databinding编译时出现的error:Execution failed for task &#39;:app:dataBindingProcessLayoutsDebug&#39;

Windows环境下使用svn对AndroidStudio更新代码时,总会在源文件中出现一堆乱码,尤其是xml文件中的乱码,不仅找起来费劲,改起来更费劲. 最近从svn更新代码之后,编译时出现了下面这个提示,而且AS中没有错误提示,这可真是捉急了. databinding error:Execution failed for task ':app:dataBindingProcessLayoutsDebug' 后来,多亏这篇帖子提示,自己写了段代码来尝试下,http://stackoverflo

Android中的Glide加载图片

注意:在Android Studio的项目的build.gradle中添加: compile 'com.github.bumptech.glide:glide:3.6.1' 然后同步一下 目录: 使用Glide结合列表的样式进行图片加载 如果使用的是RecyclerView,可以在Adapter的onBindViewHolder方法中使用 当加载网络图片时,由于加载过程中图片未能及时显示,此时可能需要设置等待时的图片,通过placeHolder()方法 当加载图片失败时,通过error(Draw

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

在鼠标经过图片时,图片被放大,而且还有个过渡的效果.... 1 <!DOCTYPE html> 2 <html> 3 <head> 4 <link href="css/prodInfo.css" rel="stylesheet" type="text/css"> 5 </head> 6 <style> 7 div img{ 8 border:1px soild red; 9

android 在图库中进行幻灯片播放时图片不会全屏显示

1.在 Slideshowview.java 2.        @Override public void apply(GLCanvas canvas) { int viewWidth = getWidth(); int viewHeight = getHeight(); float initScale = Math.min((float) viewWidth / mWidth, (float) viewHeight / mHeight); // M: if special SUB_TYPE,

android中Canvas使用drawBitmap绘制图片

1.主要的绘制图片方法 //Bitmap:图片对象,left:偏移左边的位置,top: 偏移顶部的位置 drawBitmap(Bitmap bitmap, float left, float top, Paint paint) 2.对图片剪接和限定显示区域 drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint): Rect src: 是对图片进行裁截,若是空null则显示整个图片 RectF dst:是图片在Canvas画布中显示的

Android 中 Movie 类显示GIF图片

1.Movie类简介 2.代码实现 import android.app.Activity; import android.content.Context; import android.graphics.Canvas; import android.graphics.Movie; import android.graphics.Paint; import android.os.Bundle; import android.util.AttributeSet; import android.vi

Android中获取网络数据时的分页加载

//此实在Fragment中实现的,黄色部分为自动加载,红色部分是需要注意的和手动加载,    蓝色部分是睡眠时间,自我感觉不用写  ,还有就是手动加载时,不知道为什么进去后显示的就是最后一行,求大神指教 public class Fragment1 extends Fragment{               //加载的第几页        private int index = 0;            private List<News> news=new ArrayList<