Android中圖片壓縮方案詳解_第1頁(yè)
Android中圖片壓縮方案詳解_第2頁(yè)
Android中圖片壓縮方案詳解_第3頁(yè)
Android中圖片壓縮方案詳解_第4頁(yè)
Android中圖片壓縮方案詳解_第5頁(yè)
免費(fèi)預(yù)覽已結(jié)束,剩余11頁(yè)可下載查看

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

Android中圖片壓縮方案詳解1、質(zhì)量壓縮法設(shè)置bitmap options屬性,降低圖片的質(zhì)量,像素不會(huì)減少 第一個(gè)參數(shù)為需要壓縮的bitmap圖片對(duì)象,第二個(gè)參數(shù)為壓縮后圖片保存的位置 設(shè)置options 屬性0-100,來(lái)實(shí)現(xiàn)壓縮。private Bitmap compressImage(Bitmap image) ByteArrayOutputStream baos = new ByteArrayOutputStream(); press(Bitmap.CompressFormat.JPEG, 100, baos);/質(zhì)量壓縮方法,這里100表示不壓縮,把壓縮后的數(shù)據(jù)存放到baos中 int options = 100; while ( baos.toByteArray().length / 1024100) /循環(huán)判斷如果壓縮后圖片是否大于100kb,大于繼續(xù)壓縮 baos.reset();/重置baos即清空baos press(Bitmap.CompressFormat.JPEG, options, baos);/這里壓縮options%,把壓縮后的數(shù)據(jù)存放到baos中 options -= 10;/每次都減少10 ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray();/把壓縮后的數(shù)據(jù)baos存放到ByteArrayInputStream中 Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);/把ByteArrayInputStream數(shù)據(jù)生成圖片 return bitmap; 質(zhì)量壓縮不會(huì)減少圖片的像素。它是在保持像素不變的前提下改變圖片的位深及透明度等,來(lái)達(dá)到壓縮圖片的目的。進(jìn)過(guò)它壓縮的圖片文件大小會(huì)有改變,但是導(dǎo)入成bitmap后占得內(nèi)存是不變的。因?yàn)橐3窒袼夭蛔儯运蜔o(wú)法無(wú)限壓縮,到達(dá)一個(gè)值之后就不會(huì)繼續(xù)變小了。顯然這個(gè)方法并不適用于縮略圖,其實(shí)也不適用于想通過(guò)壓縮圖片減少內(nèi)存的適用,僅僅適用于想在保證圖片質(zhì)量的同時(shí)減少文件大小的情況而已。2、采樣率壓縮法private Bitmap getimage(String srcPath) BitmapFactory.Options newOpts = new BitmapFactory.Options(); /開(kāi)始讀入圖片,此時(shí)把options.inJustDecodeBounds 設(shè)回true了 newOpts.inJustDecodeBounds = true; Bitmap bitmap = BitmapFactory.decodeFile(srcPath,newOpts);/此時(shí)返回bm為空 newOpts.inJustDecodeBounds = false; int w = newOpts.outWidth; int h = newOpts.outHeight; /現(xiàn)在主流手機(jī)比較多是1280*720分辨率,所以高和寬我們?cè)O(shè)置為 float hh = 1280f;/這里設(shè)置高度為1280f float ww = 720f;/這里設(shè)置寬度為720f /縮放比。由于是固定比例縮放,只用高或者寬其中一個(gè)數(shù)據(jù)進(jìn)行計(jì)算即可 int be = 1;/be=1表示不縮放 if (w h & w ww) /如果寬度大的話根據(jù)寬度固定大小縮放 be = (int) (newOpts.outWidth / ww); else if (w hh) /如果高度高的話根據(jù)寬度固定大小縮放 be = (int) (newOpts.outHeight / hh); if (be size * 1024) System.out.println(out.toByteArray().length); matrix.setScale(0.9f, 0.9f); result = Bitmap.createBitmap(result, 0, 0, result.getWidth(), result.getHeight(), matrix, true); out.reset(); press(Bitmap.CompressFormat.JPEG, 85, out); 縮放法其實(shí)很簡(jiǎn)單,設(shè)定好matrix,在createBitmap就可以了。但是我們并不知道縮放比例,而是要求了圖片的最終大小。直接用大小的比例來(lái)做的話肯定是有問(wèn)題的,用大小比例的開(kāi)方來(lái)做會(huì)比較接近,但是還是有差距。但是只要再做一下微調(diào)應(yīng)該就可以了,微調(diào)的話就是修改過(guò)的圖片大小比最終大小還大的話,就進(jìn)行0.8的壓縮再比較,循環(huán)直到大小合適。這樣就能得到合適大小的圖片,而且也能比較保證質(zhì)量。4、JNI調(diào)用libjpeg庫(kù)壓縮JNI靜態(tài)調(diào)用 bitherlibjni.c 中的方法來(lái)實(shí)現(xiàn)壓縮Java_net_bither_util_NativeUtil_compressBitmap net_bither_util為包名,NativeUtil為類名,compressBitmap為native方法名,我們只需要調(diào)用saveBitmap()方法就可以,bmp 需要壓縮的Bitmap對(duì)象, quality壓縮質(zhì)量0-100, fileName 壓縮后要保存的文件地址, optimize 是否采用哈弗曼表數(shù)據(jù)計(jì)算 品質(zhì)相差5-10倍。jstring Java_net_bither_util_NativeUtil_compressBitmap(JNIEnv* env, jobject thiz, jobject bitmapcolor, int w, int h, int quality, jbyteArray fileNameStr, jboolean optimize) AndroidBitmapInfo infocolor; BYTE* pixelscolor; int ret; BYTE * data; BYTE *tmpdata; char * fileName = jstrinTostring(env, fileNameStr); if (ret = AndroidBitmap_getInfo(env, bitmapcolor, &infocolor) NewStringUTF(env, 0); if (ret = AndroidBitmap_lockPixels(env, bitmapcolor, &pixelscolor) 0) LOGE(AndroidBitmap_lockPixels() 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 & 0x0000FF00) 8); b = color & 0x000000FF; *data = b; *(data + 1) = g; *(data + 2) = r; data = data + 3; pixelscolor += 4; AndroidBitmap_unlockPixels(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 (*env)-NewStringUTF(env, 1); /success5、質(zhì)量壓縮+采樣率壓縮+JNI調(diào)用libjpeg庫(kù)壓縮結(jié)合使用首先通過(guò)尺寸壓縮,壓縮到手機(jī)常用的一個(gè)分辨率(1280*960 微信好像是壓縮到這個(gè)分辨率),然后我們要把圖片壓縮到一定大小以內(nèi)(比如說(shuō)200k),然后通過(guò)循環(huán)進(jìn)行質(zhì)量壓縮來(lái)計(jì)算options需要設(shè)置為多少,最后調(diào)用JNI壓縮。 + 計(jì)算縮放比 /* * 計(jì)算縮放比 * param bitWidth 當(dāng)前圖片寬度 * param bitHeight 當(dāng)前圖片高度 * return int 縮放比 */ public static int getRatioSize(int bitWidth, int bitHeight) / 圖片最大分辨率 int imageHeight = 1280; int imageWidth = 960; / 縮放比 int ratio = 1; / 縮放比,由于是固定比例縮放,只用高或者寬其中一個(gè)數(shù)據(jù)進(jìn)行計(jì)算即可 if (bitWidth bitHeight & bitWidth imageWidth) / 如果圖片寬度比高度大,以寬度為基準(zhǔn) ratio = bitWidth / imageWidth; else if (bitWidth imageHeight) / 如果圖片高度比寬度大,以高度為基準(zhǔn) ratio = bitHeight / imageHeight; / 最小比率為1 if (ratio maxSize) / 重置baos即清空baos baos.reset(); / 每次都減少10 quality -= 10; / 這里壓縮quality,把壓縮后的數(shù)據(jù)存放到baos中 press(Bitmap.CompressFormat.JPEG, quality, baos); / JNI保存圖片到SD卡 這個(gè)關(guān)鍵 NativeUtil.saveBitmap(result, quality, targetFilePath, true); / 釋放Bitmap if (!result.isRecycled() 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.Matrix;import android.graphics.Rect;import android.media.ExifInterface;import java.io.ByteArrayOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;/* * JNI圖片壓縮工具類 * * Description TODO * Package net.bither.util * Class NativeUtil */public class NativeUtil private static int DEFAULT_QUALITY = 95; /* * Description: JNI基本壓縮 * param bit * bitmap對(duì)象 * param fileName * 指定保存目錄名 * param optimize * 是否采用哈弗曼表數(shù)據(jù)計(jì)算 品質(zhì)相差5-10倍 */ public static void compressBitmap(Bitmap bit, String fileName, boolean optimize) saveBitmap(bit, DEFAULT_QUALITY, fileName, optimize); /* * Description: 通過(guò)JNI圖片壓縮把Bitmap保存到指定目錄 * param image * bitmap對(duì)象 * param filePath * 要保存的指定目錄 */ public static void compressBitmap(Bitmap image, String filePath) / 最大圖片大小 150KB int maxSize = 150; / 獲取尺寸壓縮倍數(shù) int ratio = NativeUtil.getRatioSize(image.getWidth(),image.getHeight(); / 壓縮Bitmap到對(duì)應(yīng)尺寸 Bitmap result = Bitmap.createBitmap(image.getWidth() / ratio,image.getHeight() / ratio, 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(); / 質(zhì)量壓縮方法,這里100表示不壓縮,把壓縮后的數(shù)據(jù)存放到baos中 int options = 100; press(Bitmap.CompressFormat.JPEG, options, baos); / 循環(huán)判斷如果壓縮后圖片是否大于100kb,大于繼續(xù)壓縮 while (baos.toByteArray().length / 1024 maxSize) / 重置baos即清空baos baos.reset(); / 每次都減少10 options -= 10; / 這里壓縮options%,把壓縮后的數(shù)據(jù)存放到baos中 press(Bitmap.CompressFormat.JPEG, options, baos); / JNI保存圖片到SD卡 這個(gè)關(guān)鍵 NativeUtil.saveBitmap(result, options, filePath, true); / 釋放Bitmap if (!result.isRecycled() result.recycle(); /* * Description: 通過(guò)JNI圖片壓縮把Bitmap保存到指定目錄 * param curFilePath * 當(dāng)前圖片文件地址 * param targetFilePath * 要保存的圖片文件地址 */ public static void compressBitmap(String curFilePath, String targetFilePath) / 最大圖片大小 500KB int maxSize = 500; /根據(jù)地址獲取bitmap Bitmap result = getBitmapFromFile(curFilePath); ByteArrayOutputStream baos = new ByteArrayOutputStream(); / 質(zhì)量壓縮方法,這里100表示不壓縮,把壓縮后的數(shù)據(jù)存放到baos中 int quality = 100; press(Bitmap.CompressFormat.JPEG, quality, baos); / 循環(huán)判斷如果壓縮后圖片是否大于500kb,大于繼續(xù)壓縮 while (baos.toByteArray().length / 1024 maxSize) / 重置baos即清空baos baos.reset(); / 每次都減少10 quality -= 10; / 這里壓縮quality,把壓縮后的數(shù)據(jù)存放到baos中 press(Bitmap.CompressFormat.JPEG, quality, baos); / JNI保存圖片到SD卡 這個(gè)關(guān)鍵 NativeUtil.saveBitmap(result, quality, targetFilePath, true); / 釋放Bitmap if (!result.isRecycled() result.recycle(); /* * 計(jì)算縮放比 * param bitWidth 當(dāng)前圖片寬度 * param bitHeight 當(dāng)前圖片高度 * return int 縮放比 */ public static int getRatioSize(int bitWidth, int bitHeight) / 圖片最大分辨率 int imageHeight = 1280; int imageWidth = 960; / 縮放比 int ratio = 1; / 縮放比,由于是固定比例縮放,只用高或者寬其中一個(gè)數(shù)據(jù)進(jìn)行計(jì)算即可 if (bitWidth bitHeight & bitWidth imageWidth) / 如果圖片寬度比高度大,以寬度為基準(zhǔn) ratio = bitWidth / imageWidth; else if (bitWidth imageHeight) / 如果圖片高度比寬度大,以高度為基準(zhǔn) ratio = bitHeight / imageHeight; / 最小比率為1 if (ratio ACTION_GET_CONTENT 4.4以下默認(rèn)打開(kāi)縮略圖 。 以上打開(kāi)文件管理器 供選擇,選擇圖庫(kù)打開(kāi)為縮略圖頁(yè)面,選擇圖片打開(kāi)為原圖瀏覽。 從圖庫(kù)獲取到的uri格式為:content:/media/external/images/media/666666ACTION_PICK 都可用,打開(kāi)默認(rèn)是縮略圖界面,還需要進(jìn)一步點(diǎn)開(kāi)查看。 參考代碼:public void pickFromGallery() if (Build.VERSION.SDK_INT Build.VERSION_CODES.KITKAT) startActivityForResult(new Intent(Intent.ACTION_GET_CONTENT).setType(image/*), REQUEST_PICK_IMAGE); else Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); intent.addCategory(Intent.CATEGORY_OPENABLE); intent.setType(image/*); startActivityForResult(intent, REQUEST_KITKAT_PICK_IMAGE); 根據(jù)URI獲取對(duì)應(yīng)的文件路徑 在我們從圖庫(kù)中選擇圖片后回調(diào)給我們的data.getData()可能是URI,我們平時(shí)對(duì)文件的操作基本上都是基于路徑然后進(jìn)行各種操作與轉(zhuǎn)換,如今我們需要將URI對(duì)應(yīng)的文件路徑找出來(lái),具體參考代碼如下:public static String getPathByUri(Context context, Uri data) if (Build.VERSION.SDK_INT = Build.VERSION_CODES.KITKAT; / DocumentProvider i

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論