图片的压缩(二次采样)

  1 package com.qianfeng.bitmapdisplay.tasks;
  2
  3 import android.graphics.Bitmap;
  4 import android.graphics.BitmapFactory;
  5 import android.graphics.drawable.Drawable;
  6 import android.os.AsyncTask;
  7 import android.widget.ImageView;
  8 import com.qianfeng.bitmapdisplay.cache.FileCache;
  9 import com.qianfeng.bitmapdisplay.utils.HttpTools;
 10
 11 import java.lang.ref.WeakReference;
 12
 13 /**
 14  * Created
 15  * Author: vhly[FR]
 16  * Email: [email protected]
 17  * Date: 2015/10/12
 18  */
 19 public class ImageLoadTask extends AsyncTask<String, Integer, Bitmap> {
 20
 21     /**
 22      * 使用弱引用来进行ImageView对象的引用,当UI销毁,任务不再使用ImageView
 23      */
 24     private final WeakReference<ImageView> imageViewReference;
 25
 26     /**
 27      * 加载的图片,最终显示的宽度
 28      */
 29     private int requestWidth;
 30
 31     private int requestHeight;
 32
 33     /**
 34      * 异步任务的构造
 35      *
 36      * @param imageView ImageView 需要显示的ImageView
 37      * @param reqWidth  请求的宽度 0 代表显示原始图像,> 0 将图像缩小
 38      * @param reqHeight 请求的高度 0 代表显示原始图像,> 0 将图像缩小
 39      */
 40     public ImageLoadTask(ImageView imageView, int reqWidth, int reqHeight) {
 41         imageViewReference = new WeakReference<ImageView>(imageView);
 42
 43         requestWidth = reqWidth;
 44
 45         requestHeight = reqHeight;
 46     }
 47
 48     @Override
 49     protected Bitmap doInBackground(String... params) {
 50         Bitmap ret = null;
 51
 52         if (params != null && params.length > 0) {
 53
 54             String url = params[0];
 55
 56             // 获取 url 对应的文件缓存
 57             byte[] data = FileCache.getInstance().load(url);
 58
 59             if (data != null) {
 60                 // TODO 有文件数据,那么不需要联网
 61             } else {
 62                 // TODO 联网下载图片
 63                 data = HttpTools.doGet(url);
 64                 FileCache.getInstance().save(url, data);
 65             }
 66
 67             if (data != null) {
 68
 69
 70                 // 按照原始的图片尺寸,进行Bitmap的生成,
 71                 // 按照Bitmap生成,是按照 图片原始宽高,进行生成,并且每一个像素占用四个字节 也就是 ARGB
 72                 // ret = BitmapFactory.decodeByteArray(data, 0, data.length);
 73
 74
 75                 // 采用二次采样(缩小图片尺寸的方式)
 76
 77                 // 1. 步骤1 获取原始图片的宽高信息,用于进行采样的计算
 78
 79                 // 1.1 创建 Options ,给BitmapFactory 的内部解码器传递参数
 80                 BitmapFactory.Options options = new BitmapFactory.Options();
 81
 82                 // 1.2 设置 inJustDecodeBounds 来控制解码器,只进行图片宽高的获取,不会加载 Bitmap
 83                 //     不占用内存,当使用这个参数,代表 BitmapFactory.decodeXxxx 类似的方法,不会返回 Bitmap
 84                 options.inJustDecodeBounds = true;
 85
 86                 // 解码,使用 Options 参数设置 解码方式
 87                 BitmapFactory.decodeByteArray(data, 0, data.length, options);
 88
 89                 //------------------------------------------
 90
 91                 // 2. 步骤2 根据图片的真实尺寸,与当前需要显示的尺寸,进行计算,生成图片采样率。
 92
 93                 // 2.1
 94
 95                 int picW = options.outWidth;   // 6000
 96                 int picH = options.outHeight;  // 4000
 97
 98                 // 2.2 准备 显示在 手机上的尺寸。 256x128   128x64
 99                 //     尺寸是根据程序需要来设置的。
100
101                 // maxWidth, maxHeight
102                 int reqW = requestWidth;
103
104                 int reqH = requestHeight;  // 测试数据
105
106                 // 2.3 计算、设置 图片采样率
107
108                 options.inSampleSize =
109                         calculateInSampleSize(options, reqW, reqH);  // 宽度的 1/32  高度的 1/32
110
111                 // 2.4 开放 解码,实际生成Bitmap
112                 options.inJustDecodeBounds = false;
113
114                 // 2.4.1 Bitmap.Config 的说明
115                 // 要求解码器对于每一个采样的像素,使用 RGB_565 存储方式
116                 // 一个像素,占用两个 字节;比 ARGB_8888 小了一半。
117                 // 如果解码器不能够使用指定配置,就自动使用 ARGB_8888
118                 options.inPreferredConfig = Bitmap.Config.RGB_565;
119
120                 // 2.4.2 是一个过时的设置
121                 options.inPurgeable = true;
122
123                 // 2.5 使用设置采样的参数,来进行 解码,获取 Bitmap
124                 ret = BitmapFactory.decodeByteArray(data, 0, data.length, options);
125
126                 // data 需要显示释放
127                 data = null;
128
129             }
130         }
131
132         return ret;
133     }
134
135     @Override
136     protected void onPostExecute(Bitmap bitmap) {
137         if (bitmap != null) {
138
139             // 获取弱引用包含的对象,可能为null
140             ImageView imageView = imageViewReference.get();
141
142             if (imageView != null) {
143                 // 每一个图片都可以包含 AsyncDrawable对象
144                 // 这个对象用于处理图片错位的
145                 Drawable drawable = imageView.getDrawable();
146
147                 if (drawable != null && drawable instanceof AsyncDrawable) {
148                     // 用于检测图片错位
149
150                     AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
151
152                     ImageLoadTask task = asyncDrawable.getImageLoadTask();
153
154                     // 当前ImageView 内部包含的 AsyncDrawable和当前
155                     // 任务是对应的,代表 当前任务可以设置图片
156                     if (this == task) {
157                         imageView.setImageBitmap(bitmap);
158                     }
159
160                 } else { // 不用检测 图片错位的情况
161                     imageView.setImageBitmap(bitmap);
162                 }
163             }
164
165         }
166     }
167
168     /**
169      * 计算图片二次采样的采样率,使用获取图片宽高之后的 Options 作为第一个参数;
170      * 并且,通过请求的 宽度、高度尺寸,进行采样率的计算;
171      *
172      * @param options
173      * @param reqWidth  请求的宽度
174      * @param reqHeight 请求的高度
175      * @return int 采样率
176      */
177     public static int calculateInSampleSize(
178             BitmapFactory.Options options, int reqWidth, int reqHeight) {
179         // Raw height and width of image
180         final int height = options.outHeight;
181         final int width = options.outWidth;
182         int inSampleSize = 1;
183
184         // 当请求的宽度、高度 > 0 时候,进行缩放,
185         // 否则,图片不进行缩放;
186         if (reqWidth > 0 && reqHeight > 0) {
187             if (height > reqHeight || width > reqWidth) {
188
189                 final int halfHeight = height / 2;
190                 final int halfWidth = width / 2;
191
192                 // Calculate the largest inSampleSize value that is a power of 2 and keeps both
193                 // height and width larger than the requested height and width.
194                 while ((halfHeight / inSampleSize) >= reqHeight
195                         && (halfWidth / inSampleSize) >= reqWidth) {
196                     inSampleSize *= 2;
197                 }
198             }
199         }
200
201         return inSampleSize;
202     }
203
204 }

上面的是  比较正规具体的压缩方式  decodeByteArray

下边的是比较快捷的方式   decodeFile

private void resizePhoto() {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;

BitmapFactory.decodeFile(mcurrentPhotoPath, options);

double ratio = Math.max(options.outWidth*1.0d/1024 , options.outHeight*1.0d/1024);

options.inSampleSize = (int)Math.ceil(ratio);

options.inJustDecodeBounds = false;

mphotoImage = BitmapFactory.decodeFile(mcurrentPhotoPath, options);
}

时间: 2024-10-05 12:33:44

图片的压缩(二次采样)的相关文章

Bitmap 图片二次采样 【转载】

1.bitmap概述 Android系统支持几种图片(.png (preferred), .jpg (acceptable), .gif (discouraged)), 其中Bitmap位图#ffffffff,包括图片透明度Alpha和RGB,图片质量很好,每一个像素位占4个字节,如果图片很大将会占据很大的内存空间.存储在SDCard的image很小,加载进内存可能就会很大.因此,对bitmap图像进行操作,应该特别小心,可能出现内存溢出问题.为此对于大图片,应该引入该图片的二次采样生成缩略图.

Android BitmapFactory图片压缩处理(大位图二次采样压缩处理)

Android实际开发中,在加载大量图片的时候,比如ViewPager.GridView.ListView中,加载了大量的比较大图片就容易出现OOM(内存溢出)的异常,这是因为一个应用的最大内存使用只有16M,超过了这个值,就会出现OOM.所以我们实际开发中,要想避免OOM出现就要对相应的图片进行压缩处理. 本文即使用了BitmapFactory和BitmapFactory.Option这两个类,对图片进行相应的尺寸压缩处理.经测试,成功解决了未压缩图片之前出现的OOM异常. 实现效果图: 本D

Android开发之大位图二次采样压缩处理(源代码分享)

图片有各种形状和大小.在许多情况下这些图片是远远大于我们的用户界面(UI)且占据着极大的内存空间,如果我们不对位图进行压缩处理,我们的程序会发生内存泄露的错误. MainActivity的代码 package com.example.g08_bitmap; import android.os.Bundle; import android.app.Activity; import android.content.res.Resources; import android.graphics.Bitm

Android加载大图片(压缩)

转载自http://blog.csdn.net/junjx/article/details/7798604 在Android开发中,我们经常需要加载图片.但是图片的尺寸往往会很大,如果我们要的是比较小的图片,在Android有限的内存下,我们显然不能把大尺寸的图片放到内存里,这样不但效率降低,而且会导致java.lang.OutOfMemory异常,相信很多朋友都遇到过这样的问题,那么该怎么解决这一问题呢?其实在Android官方文档中早已给出了解决的方案. 一.读Bitmap的尺寸和类型   

iOS 使用AFN 进行单图和多图上传 摄像头/相册获取图片,压缩图片

图片上传时必要将图片进行压缩,不然会上传失败 首先是同系统相册选择图片和视频.iOS系统自带有UIImagePickerController,可以选择或拍摄图片视频,但是最大的问题是只支持单选,由于项目要求需要支持多选,只能自己自定义.获取系统图库的框架有两个,一个是ALAssetsLibrary,兼容iOS低版本,但是在iOS9中是不建议使用的:另一个是PHAsset,但最低要求iOS8以上.兼容到iOS7,可以选择了ALAssetsLibrary 现在我们先说选择一张图的情况 一.单图多图上

图片的压缩

我们从网上获取图片有时太大我们的手机分辨率不够所以我们就得把图片压缩 下面就是从网上获取图片直接压缩的代码 package com.example.tupian; import java.io.BufferedInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; imp

如何将图片批量压缩?全面盘点这几种小方法

写在前面:现在的人们都喜欢用自己手机里的相机来记录自己生活中的点滴美好,而拍照成为人们记录自己生活的最常用的一个方式,这样当时间过去也会记得自己之前曾去过哪些地方,可是照片多了之后也很烦恼,图片太多,就容易出现体积过大的,在传输的时候特别麻烦,这就需要将图片进行压缩,如果图片过多,就需要进行批量压缩,那么如何将图片批量压缩?今天就来为大家爱全面盘点这几种小方法.一.软件压缩推荐指数:★★★★★借助工具:迅捷压缩软件介绍:迅捷压缩软件是一款操作简单,快捷高效的图片压缩,视频压缩,PDF压缩软件,能

如何将图片进行压缩?实现多张图片压缩技巧讲解

压缩图片在我们的日常生活中运用的十分广泛,压缩图片的方法其实有很多种,不知道大家平时在上传图片的时候有没有遇到过像我一样的问题就是图片过大发送特别慢,甚至有些还发送不出去,这时候我们就需要将图片压缩变小,那么,如何压缩图片大小呢?下面一起里看看方法吧! 步骤讲解: 步骤一:首先,在电脑桌面上新建一个文件夹,将需要进行压缩的图片放进去: 步骤二:双击打开压缩工具,在跳转的页面有五个功能选项,点击选择图片压缩,随后会进入图片压缩界面: 步骤三:打开图片压缩界面后,可以看到有两种添加方式,分别是添加文

怎样使用电脑将图片进行压缩?有没有简单的步骤

电脑压缩图片的软件怎样操作?我们在进行图片压缩的时候,对于压缩软件的选择及压缩的具体操作过程是很不熟悉的,电脑中的图片需要压缩,也不知道该如何下手,下面将方法分享给大家,一起来看看吧! 操作步骤: 步骤一:在电脑上新建一个文件夹,将需要进行压缩的图片放进去: 步骤二:双击打开压缩工具,在跳转的页面有五个功能选项,点击选择图片压缩: 步骤三:进入图片压缩页面通过添加文件将需要进行压缩的图片添加至指定区域即可: 步骤四:图片上传过程中需要继续上传图片点击添加文件或添加文件夹即可: 步骤五:上传过程中