Android中图片压缩方案详解.doc

上传人:李司机 文档编号:1163782 上传时间:2022-07-11 格式:DOC 页数:14 大小:65.50KB
返回 下载 相关 举报
Android中图片压缩方案详解.doc_第1页
第1页 / 共14页
Android中图片压缩方案详解.doc_第2页
第2页 / 共14页
Android中图片压缩方案详解.doc_第3页
第3页 / 共14页
Android中图片压缩方案详解.doc_第4页
第4页 / 共14页
Android中图片压缩方案详解.doc_第5页
第5页 / 共14页
点击查看更多>>
资源描述

《Android中图片压缩方案详解.doc》由会员分享,可在线阅读,更多相关《Android中图片压缩方案详解.doc(14页珍藏版)》请在三一办公上搜索。

1、-Android中图片压缩方案详解1、质量压缩法设置bitmap options属性,降低图片的质量,像素不会减少 第一个参数为需要压缩的bitmap图片对象,第二个参数为压缩后图片保存的位置 设置options 属性0-100,来实现压缩。private Bitmap pressImage(Bitmap image) ByteArrayOutputStream baos = new ByteArrayOutputStream(); image.press(Bitmap.pressFormat.JPEG, 100, baos);/质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos

2、中 int options = 100; while ( baos.toByteArray().length / 1024100) /循环判断如果压缩后图片是否大于100kb,大于继续压缩 baos.reset();/重置baos即清空baos image.press(Bitmap.pressFormat.JPEG, options, baos);/这里压缩options%,把压缩后的数据存放到baos中 options -= 10;/每次都减少10 ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray();

3、/把压缩后的数据baos存放到ByteArrayInputStream中 Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);/把ByteArrayInputStream数据生成图片 return bitmap; 质量压缩不会减少图片的像素。它是在保持像素不变的前提下改变图片的位深及透明度等,来到达压缩图片的目的。进过它压缩的图片文件大小会有改变,但是导入成bitmap后占得存是不变的。因为要保持像素不变,所以它就无法无限压缩,到达一个值之后就不会继续变小了。显然这个方法并不适用于缩略图,其实也不适用于想通过压缩图片减少存的

4、适用,仅仅适用于想在保证图片质量的同时减少文件大小的情况而已。2、采样率压缩法private Bitmap getimage(String srcPath) BitmapFactory.Options newOpts = new BitmapFactory.Options(); /开场读入图片,此时把options.inJustDecodeBounds 设回true了 newOpts.inJustDecodeBounds = true; Bitmap bitmap = BitmapFactory.decodeFile(srcPath,newOpts);/此时返回bm为空 newOpts.inJ

5、ustDecodeBounds = false; int w = newOpts.outWidth; int h = newOpts.outHeight; /现在主流手机比拟多是1280*720分辨率,所以高和宽我们设置为 float hh = 1280f;/这里设置高度为1280f float ww = 720f;/这里设置宽度为720f /缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进展计算即可 int be = 1;/be=1表示不缩放 if (w h & w ww) /如果宽度大的话根据宽度固定大小缩放 be = (int) (newOpts.outWidth / ww); e

6、lse if (w hh) /如果高度高的话根据宽度固定大小缩放 be = (int) (newOpts.outHeight / hh); if (be size * 1024) System.out.println(out.toByteArray().length); matri*.setScale(0.9f, 0.9f); result = Bitmap.createBitmap(result, 0, 0, result.getWidth(), result.getHeight(), matri*, true); out.reset(); result.press(Bitmap.press

7、Format.JPEG, 85, out); 缩放法其实很简单,设定好matri*,在createBitmap就可以了。但是我们并不知道缩放比例,而是要求了图片的最终大小。直接用大小的比例来做的话肯定是有问题的,用大小比例的开方来做会比拟接近,但是还是有差距。但是只要再做一下微调应该就可以了,微调的话就是修改正的图片大小比最终大小还大的话,就进展0.8的压缩再比拟,循环直到大小适宜。这样就能得到适宜大小的图片,而且也能比拟保证质量。4、JNI调用libjpeg库压缩JNI静态调用 bitherlibjni.c 中的方法来实现压缩Java_net_bither_util_NativeUtil_p

8、ressBitmap net_bither_util为包名,NativeUtil为类名,pressBitmap为native方法名,我们只需要调用saveBitmap()方法就可以,bmp 需要压缩的Bitmap对象, quality压缩质量0-100, fileName 压缩后要保存的文件地址, optimize 是否采用哈弗曼表数据计算 品质相差5-10倍。jstring Java_net_bither_util_NativeUtil_pressBitmap(JNIEnv* env, jobject thiz, jobject bitmapcolor, int w, int h, int

9、quality, yteArray fileNameStr, oolean optimize) AndroidBitmapInfo infocolor; BYTE* pi*elscolor; int ret; BYTE * data; BYTE *tmpdata; char * fileName = jstrinTostring(env, fileNameStr); if (ret = AndroidBitmap_getInfo(env, bitmapcolor, &infocolor) NewStringUTF(env, 0); if (ret = AndroidBitmap_lockPi*

10、els(env, bitmapcolor, &pi*elscolor) 0) LOGE(AndroidBitmap_lockPi*els() failed ! error=%d, ret); BYTE r, g, b; data = NULL; data = malloc(w * h * 3); tmpdata = data; int j = 0, i = 0; int color; for (i = 0; i h; i+) for (j = 0; j 16); g = (color & 0*0000FF00) 8); b = color & 0*000000FF; *data = b; *(

11、data + 1) = g; *(data + 2) = r; data = data + 3; pi*elscolor += 4; AndroidBitmap_unlockPi*els(env, bitmapcolor); int resultCode= generateJPEG(tmpdata, w, h, quality, fileName, optimize); free(tmpdata); if(resultCode=0) jstring result=(*env)-NewStringUTF(env, error); error=NULL; return result; return

12、 (*env)-NewStringUTF(env, 1); /success5、质量压缩+采样率压缩+JNI调用libjpeg库压缩结合使用首先通过尺寸压缩,压缩到手机常用的一个分辨率(1280*960 微信好似是压缩到这个分辨率),然后我们要把图片压缩到一定大小以(比方说200k),然后通过循环进展质量压缩来计算options需要设置为多少,最后调用JNI压缩。 + 计算缩放比 /* * 计算缩放比 * param bitWidth 当前图片宽度 * param bitHeight 当前图片高度 * return int 缩放比 */ public static int getRatioSi

13、ze(int bitWidth, int bitHeight) / 图片最大分辨率 int imageHeight = 1280; int imageWidth = 960; / 缩放比 int ratio = 1; / 缩放比,由于是固定比例缩放,只用高或者宽其中一个数据进展计算即可 if (bitWidth bitHeight & bitWidth imageWidth) / 如果图片宽度比高度大,以宽度为基准 ratio = bitWidth / imageWidth; else if (bitWidth imageHeight) / 如果图片高度比宽度大,以高度为基准 ratio =

14、bitHeight / imageHeight; / 最小比率为1 if (ratio ma*Size) / 重置baos即清空baos baos.reset(); / 每次都减少10 quality -= 10; / 这里压缩quality,把压缩后的数据存放到baos中 result.press(Bitmap.pressFormat.JPEG, quality, baos); / JNI保存图片到SD卡 这个关键 NativeUtil.saveBitmap(result, quality, targetFilePath, true); / 释放Bitmap if (!result.isRe

15、cycled() result.recycle(); JNI图片压缩工具类package net.bither.util;import android.graphics.Bitmap;import android.graphics.Bitmap.Config;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Matri*;import android.graphics.Rect;import android.media.E*ifInterface;import

16、 java.io.ByteArrayOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundE*ception;import java.io.IOE*ception;/* * JNI图片压缩工具类 * * Description TODO * Class NativeUtil */public class NativeUtil private static int DEFAULT_QUALITY = 95; /* * Description: JNI根本压缩 * par

17、am bit * bitmap对象 * param fileName * 指定保存目录名 * param optimize * 是否采用哈弗曼表数据计算 品质相差5-10倍 */ public static void pressBitmap(Bitmap bit, String fileName, boolean optimize) saveBitmap(bit, DEFAULT_QUALITY, fileName, optimize); /* * Description: 通过JNI图片压缩把Bitmap保存到指定目录 * param image * bitmap对象 * param fil

18、ePath * 要保存的指定目录 */ public static void pressBitmap(Bitmap image, String filePath) / 最大图片大小 150KBint ma*Size = 150; / 获取尺寸压缩倍数 int ratio = NativeUtil.getRatioSize(image.getWidth(),image.getHeight(); / 压缩Bitmap到对应尺寸 Bitmap result = Bitmap.createBitmap(image.getWidth() / ratio,image.getHeight() / ratio

19、, Config.ARGB_8888); Canvas canvas = new Canvas(result); Rect rect = new Rect(0, 0, image.getWidth() / ratio, image.getHeight() / ratio); canvas.drawBitmap(image,null,rect,null); ByteArrayOutputStream baos = new ByteArrayOutputStream(); / 质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中 int options = 100; result.p

20、ress(Bitmap.pressFormat.JPEG, options, baos); / 循环判断如果压缩后图片是否大于100kb,大于继续压缩 while (baos.toByteArray().length / 1024 ma*Size) / 重置baos即清空baos baos.reset(); / 每次都减少10 options -= 10; / 这里压缩options%,把压缩后的数据存放到baos中 result.press(Bitmap.pressFormat.JPEG, options, baos); / JNI保存图片到SD卡 这个关键 NativeUtil.saveB

21、itmap(result, options, filePath, true); / 释放Bitmap if (!result.isRecycled() result.recycle(); /* * Description: 通过JNI图片压缩把Bitmap保存到指定目录 * param curFilePath * 当前图片文件地址 * param targetFilePath * 要保存的图片文件地址 */ public static void pressBitmap(String curFilePath, String targetFilePath) / 最大图片大小 500KB int m

22、a*Size = 500; /根据地址获取bitmap Bitmap result = getBitmapFromFile(curFilePath); ByteArrayOutputStream baos = new ByteArrayOutputStream(); / 质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中 int quality = 100; result.press(Bitmap.pressFormat.JPEG, quality, baos); / 循环判断如果压缩后图片是否大于500kb,大于继续压缩 while (baos.toByteArray().l

23、ength / 1024 ma*Size) / 重置baos即清空baos baos.reset(); / 每次都减少10 quality -= 10; / 这里压缩quality,把压缩后的数据存放到baos中 result.press(Bitmap.pressFormat.JPEG, quality, baos); / JNI保存图片到SD卡 这个关键 NativeUtil.saveBitmap(result, quality, targetFilePath, true); / 释放Bitmap if (!result.isRecycled() result.recycle(); /* *

24、 计算缩放比 * param bitWidth 当前图片宽度 * param bitHeight 当前图片高度 * return int 缩放比 */ public static int getRatioSize(int bitWidth, int bitHeight) / 图片最大分辨率 int imageHeight = 1280; int imageWidth = 960; / 缩放比 int ratio = 1; / 缩放比,由于是固定比例缩放,只用高或者宽其中一个数据进展计算即可 if (bitWidth bitHeight & bitWidth imageWidth) / 如果图片

25、宽度比高度大,以宽度为基准 ratio = bitWidth / imageWidth; else if (bitWidth imageHeight) / 如果图片高度比宽度大,以高度为基准 ratio = bitHeight / imageHeight; / 最小比率为1 if (ratio = 0) ratio = 1; return ratio; /* * 通过文件路径读获取Bitmap防止OOM以及解决图片旋转问题 * param filePath * return */ public static Bitmap getBitmapFromFile(String filePath) B

26、itmapFactory.Options newOpts = new BitmapFactory.Options(); newOpts.inJustDecodeBounds = true;/只读边,不读容 BitmapFactory.decodeFile(filePath, newOpts); int w = newOpts.outWidth; int h = newOpts.outHeight; / 获取尺寸压缩倍数 newOpts.inSampleSize = NativeUtil.getRatioSize(w,h); newOpts.inJustDecodeBounds = false;

27、/读取所有容 newOpts.inDither = false; newOpts.inPurgeable=true; newOpts.inInputShareable=true; newOpts.inTempStorage = new byte32 * 1024; Bitmap bitmap = null; File file = new File(filePath); FileInputStream fs = null; try fs = new FileInputStream(file); catch (FileNotFoundE*ception e) e.printStackTrace(

28、); try if(fs!=null) bitmap = BitmapFactory.decodeFileDescriptor(fs.getFD(),null,newOpts); /旋转图片 int photoDegree = readPictureDegree(filePath); if(photoDegree != 0) Matri* matri* = new Matri*(); matri*.postRotate(photoDegree); / 创立新的图片 bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bit

29、map.getHeight(), matri*, true); catch (IOE*ception e) e.printStackTrace(); finally if(fs!=null) try fs.close(); catch (IOE*ception e) e.printStackTrace(); return bitmap; /* * * 读取图片属性:旋转的角度 * param path 图片绝对路径 * return degree旋转的角度 */ public static int readPictureDegree(String path) int degree = 0; t

30、ry E*ifInterface e*ifInterface = new E*ifInterface(path); int orientation = e*ifInterface.getAttributeInt( E*ifInterface.TAG_ORIENTATION, E*ifInterface.ORIENTATION_NORMAL); switch (orien.sm136.tation) case E*ifInterface.ORIENTATION_ROTATE_90: degree = 90; break; case E*ifInterface.ORIENTATION_ROTATE_180: degree = 180; break; case E*ifInterface.ORIENTATION_ROTATE_270: degree = 270;

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号