android的图片缩放,Android图片缩放总结及比较
在Android中對大圖片進行縮放真的很不盡如人意,不知道是不是我的方法不對。下面我列出3種對圖片縮放的方法,并給出相應速度。請高人指教。
第一種是BitmapFactory和BitmapFactory.Options。
首先,BitmapFactory.Options有幾個Fields很有用:
inJustDecodeBounds:If set to true, the decoder will return null (no bitmap), but the out...
也就是說,當inJustDecodeBounds設成true時,bitmap并不加載到內存,這樣效率很高哦。而這時,你可以獲得bitmap的高、寬等信息。
outHeight:The resulting height of the bitmap, set independent of the state of inJustDecodeBounds.
outWidth:The resulting width of the bitmap, set independent of the state of inJustDecodeBounds.
看到了吧,上面3個變量是相關聯的哦。
inSampleSize : If set to a value > 1, requests the decoder to subsample the original p_w_picpath, returning a smaller p_w_picpath to save memory.
這就是用來做縮放比的。這里有個技巧:
inSampleSize=(outHeight/Height+outWidth/Width)/2
實踐證明,這樣縮放出來的圖片還是很好的。
最后用BitmapFactory.decodeFile(path, options)生成。
由于只是對bitmap加載到內存一次,所以效率比較高。解析速度快。
第二種是使用Bitmap加Matrix來縮放。
首先要獲得原bitmap,再從原bitmap的基礎上生成新圖片。這樣效率很低。
第三種是用2.2新加的類ThumbnailUtils來做。
讓我們新看看這個類,從API中來看,此類就三個靜態方法:createVideoThumbnail、extractThumbnail(Bitmap source, int width, int height, int options)、extractThumbnail(Bitmap source, int width, int height)。
我這里使用了第三個方法。再看看它的源碼,下面會附上。是上面我們用到的BitmapFactory.Options和Matrix等經過人家一陣加工而成。
效率好像比第二種方法高一點點。
下面是我的例子:
1. <?xml version="1.0" encoding="utf-8"?>
2.
3. android:orientation="vertical"
4. android:layout_;fill_parent"
5. android:layout_height="fill_parent"
6. >
7.
8.
9. android:id="@+id/p_w_picpathShow"
10. android:layout_;wrap_content"
11. android:layout_height="wrap_content"
12. />
13.
14. android:id="@+id/p_w_picpath2"
15. android:layout_;wrap_content"
16. android:layout_height="wrap_content"
17. />
18.
19. android:id="@+id/text"
20. android:layout_;fill_parent"
21. android:layout_height="wrap_content"
22. android:text="@string/hello"
23. />
24.
1. package com.linc.ResolvePicture;
2.
3. import java.io.File;
4. import java.io.FileNotFoundException;
5. import java.io.FileOutputStream;
6. import java.io.IOException;
7.
8. import android.app.Activity;
9. import android.graphics.Bitmap;
10. import android.graphics.BitmapFactory;
11. import android.graphics.Matrix;
12. import android.graphics.drawable.BitmapDrawable;
13. import android.graphics.drawable.Drawable;
14. import android.media.ThumbnailUtils;
15. import android.os.Bundle;
16. import android.util.Log;
17. import android.widget.ImageView;
18. import android.widget.TextView;
19.
20. public class ResolvePicture extends Activity {
21. private static String tag="ResolvePicture";
22.???? Drawable bmImg;
23.???? ImageView imView;
24.???? ImageView imView2;
25.???? TextView text;
26.???? String theTime;
27. long start, stop;
28. /** Called when the activity is first created. */
29. @Override
30. public void onCreate(Bundle savedInstanceState) {
31. super.onCreate(savedInstanceState);
32.???????? setContentView(R.layout.main);
33.
34.???????? text=(TextView)findViewById(R.id.text);
35.
36.???????? imView=(ImageView) findViewById(R.id.p_w_picpathShow);
37.???????? imView2=(ImageView) findViewById(R.id.p_w_picpath2);
38.
39.???????? Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
40.???????????????? R.drawable.pic);
41.
42.???????? start=System.currentTimeMillis();
43.
44. //??????? imView.setImageDrawable(resizeImage(bitmap, 300, 100));
45.
46.???????? imView2.setImageDrawable(resizeImage2("/sdcard/2.jpeg", 200, 100));
47.
48.???????? stop=System.currentTimeMillis();
49.
50.???????? String theTime= String.format("\n1 iterative: (%d msec)",
51.???????????????? stop - start);
52.
53.???????? start=System.currentTimeMillis();
54.???????? imView.setImageBitmap(ThumbnailUtils.extractThumbnail(bitmap,200,100));//2.2才加進來的新類,簡單易用
55. //??????? imView.setImageDrawable(resizeImage(bitmap, 30, 30));
56.???????? stop=System.currentTimeMillis();
57.
58.????????? theTime+= String.format("\n2 iterative: (%d msec)",
59.???????????????? stop - start);
60.
61.???????? text.setText(theTime);
62.???? }
63.
64. //使用Bitmap加Matrix來縮放
65. public static Drawable resizeImage(Bitmap bitmap, int w, int h)
66.???? {
67.???????? Bitmap BitmapOrg = bitmap;
68. int width = BitmapOrg.getWidth();
69. int height = BitmapOrg.getHeight();
70. int newWidth = w;
71. int newHeight = h;
72.
73. float scaleWidth = ((float) newWidth) / width;
74. float scaleHeight = ((float) newHeight) / height;
75.
76.???????? Matrix matrix = new Matrix();
77.???????? matrix.postScale(scaleWidth, scaleHeight);
78. // if you want to rotate the Bitmap
79. // matrix.postRotate(45);
80.???????? Bitmap resizedBitmap = Bitmap.createBitmap(BitmapOrg, 0, 0, width,
81.???????????????????????? height, matrix, true);
82. return new BitmapDrawable(resizedBitmap);
83.???? }
84.
85. //使用BitmapFactory.Options的inSampleSize參數來縮放
86. public static Drawable resizeImage2(String path,
87. int width,int height)
88.???? {
89.???????? BitmapFactory.Options options = new BitmapFactory.Options();
90.???????? options.inJustDecodeBounds = true;//不加載bitmap到內存中
91.???????? BitmapFactory.decodeFile(path,options);
92. int outWidth = options.outWidth;
93. int outHeight = options.outHeight;
94.???????? options.inDither = false;
95.???????? options.inPreferredConfig = Bitmap.Config.ARGB_8888;
96.???????? options.inSampleSize = 1;
97.
98. if (outWidth != 0 && outHeight != 0 && width != 0 && height != 0)
99.???????? {
100. int sampleSize=(outWidth/width+outHeight/height)/2;
101.???????????? Log.d(tag, "sampleSize = " + sampleSize);
102.???????????? options.inSampleSize = sampleSize;
103.???????? }
104.
105.???????? options.inJustDecodeBounds = false;
106. return new BitmapDrawable(BitmapFactory.decodeFile(path, options));
107.???? }
108.
109. //圖片保存
110. private void saveThePicture(Bitmap bitmap)
111.???? {
112.???????? File file=new File("/sdcard/2.jpeg");
113. try
114.???????? {
115.???????????? FileOutputStream fos=new FileOutputStream(file);
116. if(bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos))
117.???????????? {
118.???????????????? fos.flush();
119.???????????????? fos.close();
120.???????????? }
121.???????? }
122. catch(FileNotFoundException e1)
123.???????? {
124.???????????? e1.printStackTrace();
125.???????? }
126. catch(IOException e2)
127.???????? {
128.???????????? e2.printStackTrace();
129.???????? }
130.???? }
131. }
ThumbnailUtils源碼:
1. /*
2.? * Copyright (C) 2009 The Android Open Source Project
3.? *
4.? * Licensed under the Apache License, Version 2.0 (the "License");
5.? * you may not use this file except in compliance with the License.
6.? * You may obtain a copy of the License at
7.? *
8.? *????? http://www.apache.org/licenses/LICENSE-2.0
9.? *
10.? * Unless required by applicable law or agreed to in writing, software
11.? * distributed under the License is distributed on an "AS IS" BASIS,
12.? * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13.? * See the License for the specific language governing permissions and
14.? * limitations under the License.
15.? */
16.
17. package android.media;
18.
19. import android.content.ContentResolver;
20. import android.content.ContentUris;
21. import android.content.ContentValues;
22. import android.database.Cursor;
23. import android.graphics.Bitmap;
24. import android.graphics.BitmapFactory;
25. import android.graphics.Canvas;
26. import android.graphics.Matrix;
27. import android.graphics.Rect;
28. import android.media.MediaMetadataRetriever;
29. import android.media.MediaFile.MediaFileType;
30. import android.net.Uri;
31. import android.os.ParcelFileDescriptor;
32. import android.provider.BaseColumns;
33. import android.provider.MediaStore.Images;
34. import android.provider.MediaStore.Images.Thumbnails;
35. import android.util.Log;
36.
37. import java.io.FileInputStream;
38. import java.io.FileDescriptor;
39. import java.io.IOException;
40. import java.io.OutputStream;
41.
42. /**
43.? * Thumbnail generation routines for media provider.
44.? */
45.
46. public class ThumbnailUtils {
47. private static final String TAG = "ThumbnailUtils";
48.
49. /* Maximum pixels size for created bitmap. */
50. private static final int MAX_NUM_PIXELS_THUMBNAIL = 512 * 384;
51. private static final int MAX_NUM_PIXELS_MICRO_THUMBNAIL = 128 * 128;
52. private static final int UNCONSTRAINED = -1;
53.
54. /* Options used internally. */
55. private static final int OPTIONS_NONE = 0x0;
56. private static final int OPTIONS_SCALE_UP = 0x1;
57.
58. /**
59.????? * Constant used to indicate we should recycle the input in
60.????? * {@link #extractThumbnail(Bitmap, int, int, int)} unless the output is the input.
61.????? */
62. public static final int OPTIONS_RECYCLE_INPUT = 0x2;
63.
64. /**
65.????? * Constant used to indicate the dimension of mini thumbnail.
66.????? * @hide Only used by media framework and media provider internally.
67.????? */
68. public static final int TARGET_SIZE_MINI_THUMBNAIL = 320;
69.
70. /**
71.????? * Constant used to indicate the dimension of micro thumbnail.
72.????? * @hide Only used by media framework and media provider internally.
73.????? */
74. public static final int TARGET_SIZE_MICRO_THUMBNAIL = 96;
75.
76. /**
77.????? * This method first examines if the thumbnail embedded in EXIF is bigger than our target
78.????? * size. If not, then it'll create a thumbnail from original p_w_picpath. Due to efficiency
79.????? * consideration, we want to let MediaThumbRequest avoid calling this method twice for
80.????? * both kinds, so it only requests for MICRO_KIND and set saveImage to true.
81.????? *
82.????? * This method always returns a "square thumbnail" for MICRO_KIND thumbnail.
83.????? *
84.????? * @param filePath the path of p_w_picpath file
85.????? * @param kind could be MINI_KIND or MICRO_KIND
86.????? * @return Bitmap
87.????? *
88.????? * @hide This method is only used by media framework and media provider internally.
89.????? */
90. public static Bitmap createImageThumbnail(String filePath, int kind) {
91. boolean wantMini = (kind == Images.Thumbnails.MINI_KIND);
92. int targetSize = wantMini
93.???????????????? ? TARGET_SIZE_MINI_THUMBNAIL
94.???????????????? : TARGET_SIZE_MICRO_THUMBNAIL;
95. int maxPixels = wantMini
96.???????????????? ? MAX_NUM_PIXELS_THUMBNAIL
97.???????????????? : MAX_NUM_PIXELS_MICRO_THUMBNAIL;
98.???????? SizedThumbnailBitmap sizedThumbnailBitmap = new SizedThumbnailBitmap();
99.???????? Bitmap bitmap = null;
100.???????? MediaFileType fileType = MediaFile.getFileType(filePath);
101. if (fileType != null && fileType.fileType == MediaFile.FILE_TYPE_JPEG) {
102.???????????? createThumbnailFromEXIF(filePath, targetSize, maxPixels, sizedThumbnailBitmap);
103.???????????? bitmap = sizedThumbnailBitmap.mBitmap;
104.???????? }
105.
106. if (bitmap == null) {
107. try {
108.???????????????? FileDescriptor fd = new FileInputStream(filePath).getFD();
109.???????????????? BitmapFactory.Options options = new BitmapFactory.Options();
110.???????????????? options.inSampleSize = 1;
111.???????????????? options.inJustDecodeBounds = true;
112.???????????????? BitmapFactory.decodeFileDescriptor(fd, null, options);
113. if (options.mCancel || options.outWidth == -1
114.???????????????????????? || options.outHeight == -1) {
115. return null;
116.???????????????? }
117.???????????????? options.inSampleSize = computeSampleSize(
118.???????????????????????? options, targetSize, maxPixels);
119.???????????????? options.inJustDecodeBounds = false;
120.
121.???????????????? options.inDither = false;
122.???????????????? options.inPreferredConfig = Bitmap.Config.ARGB_8888;
123.???????????????? bitmap = BitmapFactory.decodeFileDescriptor(fd, null, options);
124.???????????? } catch (IOException ex) {
125.???????????????? Log.e(TAG, "", ex);
126.???????????? }
127.???????? }
128.
129. if (kind == Images.Thumbnails.MICRO_KIND) {
130. // now we make it a "square thumbnail" for MICRO_KIND thumbnail
131.???????????? bitmap = extractThumbnail(bitmap,
132.???????????????????? TARGET_SIZE_MICRO_THUMBNAIL,
133.???????????????????? TARGET_SIZE_MICRO_THUMBNAIL, OPTIONS_RECYCLE_INPUT);
134.???????? }
135. return bitmap;
136.???? }
137.
138. /**
139.????? * Create a video thumbnail for a video. May return null if the video is
140.????? * corrupt or the format is not supported.
141.????? *
142.????? * @param filePath the path of video file
143.????? * @param kind could be MINI_KIND or MICRO_KIND
144.????? */
145. public static Bitmap createVideoThumbnail(String filePath, int kind) {
146.???????? Bitmap bitmap = null;
147.???????? MediaMetadataRetriever retriever = new MediaMetadataRetriever();
148. try {
149.???????????? retriever.setMode(MediaMetadataRetriever.MODE_CAPTURE_FRAME_ONLY);
150.???????????? retriever.setDataSource(filePath);
151.???????????? bitmap = retriever.captureFrame();
152.???????? } catch (IllegalArgumentException ex) {
153. // Assume this is a corrupt video file
154.???????? } catch (RuntimeException ex) {
155. // Assume this is a corrupt video file.
156.???????? } finally {
157. try {
158.???????????????? retriever.release();
159.???????????? } catch (RuntimeException ex) {
160. // Ignore failures while cleaning up.
161.???????????? }
162.???????? }
163. if (kind == Images.Thumbnails.MICRO_KIND && bitmap != null) {
164.???????????? bitmap = extractThumbnail(bitmap,
165.???????????????????? TARGET_SIZE_MICRO_THUMBNAIL,
166.???????????????????? TARGET_SIZE_MICRO_THUMBNAIL,
167.???????????????????? OPTIONS_RECYCLE_INPUT);
168.???????? }
169. return bitmap;
170.???? }
171.
172. /**
173.????? * Creates a centered bitmap of the desired size.
174.????? *
175.????? * @param source original bitmap source
176.????? * @param width targeted width
177.????? * @param height targeted height
178.????? */
179. public static Bitmap extractThumbnail(
180.???????????? Bitmap source, int width, int height) {
181. return extractThumbnail(source, width, height, OPTIONS_NONE);
182.???? }
183.
184. /**
185.????? * Creates a centered bitmap of the desired size.
186.????? *
187.????? * @param source original bitmap source
188.????? * @param width targeted width
189.????? * @param height targeted height
190.????? * @param options options used during thumbnail extraction
191.????? */
192. public static Bitmap extractThumbnail(
193.???????????? Bitmap source, int width, int height, int options) {
194. if (source == null) {
195. return null;
196.???????? }
197.
198. float scale;
199. if (source.getWidth() < source.getHeight()) {
200.???????????? scale = width / (float) source.getWidth();
201.???????? } else {
202.???????????? scale = height / (float) source.getHeight();
203.???????? }
204.???????? Matrix matrix = new Matrix();
205.???????? matrix.setScale(scale, scale);
206.???????? Bitmap thumbnail = transform(matrix, source, width, height,
207.???????????????? OPTIONS_SCALE_UP | options);
208. return thumbnail;
209.???? }
210.
211. /*
212.????? * Compute the sample size as a function of minSideLength
213.????? * and maxNumOfPixels.
214.????? * minSideLength is used to specify that minimal width or height of a
215.????? * bitmap.
216.????? * maxNumOfPixels is used to specify the maximal size in pixels that is
217.????? * tolerable in terms of memory usage.
218.????? *
219.????? * The function returns a sample size based on the constraints.
220.????? * Both size and minSideLength can be passed in as IImage.UNCONSTRAINED,
221.????? * which indicates no care of the corresponding constraint.
222.????? * The functions prefers returning a sample size that
223.????? * generates a smaller bitmap, unless minSideLength = IImage.UNCONSTRAINED.
224.????? *
225.????? * Also, the function rounds up the sample size to a power of 2 or multiple
226.????? * of 8 because BitmapFactory only honors sample size this way.
227.????? * For example, BitmapFactory downsamples an p_w_picpath by 2 even though the
228.????? * request is 3. So we round up the sample size to avoid OOM.
229.????? */
230. private static int computeSampleSize(BitmapFactory.Options options,
231. int minSideLength, int maxNumOfPixels) {
232. int initialSize = computeInitialSampleSize(options, minSideLength,
233.???????????????? maxNumOfPixels);
234.
235. int roundedSize;
236. if (initialSize <= 8 ) {
237.???????????? roundedSize = 1;
238. while (roundedSize < initialSize) {
239.???????????????? roundedSize <<= 1;
240.???????????? }
241.???????? } else {
242.???????????? roundedSize = (initialSize + 7) / 8 * 8;
243.???????? }
244.
245. return roundedSize;
246.???? }
247.
248. private static int computeInitialSampleSize(BitmapFactory.Options options,
249. int minSideLength, int maxNumOfPixels) {
250. double w = options.outWidth;
251. double h = options.outHeight;
252.
253. int lowerBound = (maxNumOfPixels == UNCONSTRAINED) ? 1 :
254.???????????????? (int) Math.ceil(Math.sqrt(w * h / maxNumOfPixels));
255. int upperBound = (minSideLength == UNCONSTRAINED) ? 128 :
256.???????????????? (int) Math.min(Math.floor(w / minSideLength),
257.???????????????? Math.floor(h / minSideLength));
258.
259. if (upperBound < lowerBound) {
260. // return the larger one when there is no overlapping zone.
261. return lowerBound;
262.???????? }
263.
264. if ((maxNumOfPixels == UNCONSTRAINED) &&
265.???????????????? (minSideLength == UNCONSTRAINED)) {
266. return 1;
267.???????? } else if (minSideLength == UNCONSTRAINED) {
268. return lowerBound;
269.???????? } else {
270. return upperBound;
271.???????? }
272.???? }
273.
274. /**
275.????? * Make a bitmap from a given Uri, minimal side length, and maximum number of pixels.
276.????? * The p_w_picpath data will be read from specified pfd if it's not null, otherwise
277.????? * a new input stream will be created using specified ContentResolver.
278.????? *
279.????? * Clients are allowed to pass their own BitmapFactory.Options used for bitmap decoding. A
280.????? * new BitmapFactory.Options will be created if options is null.
281.????? */
282. private static Bitmap makeBitmap(int minSideLength, int maxNumOfPixels,
283.???????????? Uri uri, ContentResolver cr, ParcelFileDescriptor pfd,
284.???????????? BitmapFactory.Options options) {
285.???????????? Bitmap b = null;
286. try {
287. if (pfd == null) pfd = makeInputStream(uri, cr);
288. if (pfd == null) return null;
289. if (options == null) options = new BitmapFactory.Options();
290.
291.???????????? FileDescriptor fd = pfd.getFileDescriptor();
292.???????????? options.inSampleSize = 1;
293.???????????? options.inJustDecodeBounds = true;
294.???????????? BitmapFactory.decodeFileDescriptor(fd, null, options);
295. if (options.mCancel || options.outWidth == -1
296.???????????????????? || options.outHeight == -1) {
297. return null;
298.???????????? }
299.???????????? options.inSampleSize = computeSampleSize(
300.???????????????????? options, minSideLength, maxNumOfPixels);
301.???????????? options.inJustDecodeBounds = false;
302.
303.???????????? options.inDither = false;
304.???????????? options.inPreferredConfig = Bitmap.Config.ARGB_8888;
305.???????????? b = BitmapFactory.decodeFileDescriptor(fd, null, options);
306.???????? } catch (OutOfMemoryError ex) {
307.???????????? Log.e(TAG, "Got oom exception ", ex);
308. return null;
309.???????? } finally {
310.???????????? closeSilently(pfd);
311.???????? }
312. return b;
313.???? }
314.
315. private static void closeSilently(ParcelFileDescriptor c) {
316. if (c == null) return;
317. try {
318.?????????? c.close();
319.?????? } catch (Throwable t) {
320. // do nothing
321.?????? }
322.???? }
323.
324. private static ParcelFileDescriptor makeInputStream(
325.???????????? Uri uri, ContentResolver cr) {
326. try {
327. return cr.openFileDescriptor(uri, "r");
328.???????? } catch (IOException ex) {
329. return null;
330.???????? }
331.???? }
332.
333. /**
334.????? * Transform source Bitmap to targeted width and height.
335.????? */
336. private static Bitmap transform(Matrix scaler,
337.???????????? Bitmap source,
338. int targetWidth,
339. int targetHeight,
340. int options) {
341. boolean scaleUp = (options & OPTIONS_SCALE_UP) != 0;
342. boolean recycle = (options & OPTIONS_RECYCLE_INPUT) != 0;
343.
344. int deltaX = source.getWidth() - targetWidth;
345. int deltaY = source.getHeight() - targetHeight;
346. if (!scaleUp && (deltaX < 0 || deltaY < 0)) {
347. /*
348.???????????? * In this case the bitmap is smaller, at least in one dimension,
349.???????????? * than the target.? Transform it by placing as much of the p_w_picpath
350.???????????? * as possible into the target and leaving the top/bottom or
351.???????????? * left/right (or both) black.
352.???????????? */
353.???????????? Bitmap b2 = Bitmap.createBitmap(targetWidth, targetHeight,
354.???????????? Bitmap.Config.ARGB_8888);
355.???????????? Canvas c = new Canvas(b2);
356.
357. int deltaXHalf = Math.max(0, deltaX / 2);
358. int deltaYHalf = Math.max(0, deltaY / 2);
359.???????????? Rect src = new Rect(
360.???????????? deltaXHalf,
361.???????????? deltaYHalf,
362.???????????? deltaXHalf + Math.min(targetWidth, source.getWidth()),
363.???????????? deltaYHalf + Math.min(targetHeight, source.getHeight()));
364. int dstX = (targetWidth? - src.width())? / 2;
365. int dstY = (targetHeight - src.height()) / 2;
366.???????????? Rect dst = new Rect(
367.???????????????????? dstX,
368.???????????????????? dstY,
369.???????????????????? targetWidth - dstX,
370.???????????????????? targetHeight - dstY);
371.???????????? c.drawBitmap(source, src, dst, null);
372. if (recycle) {
373.???????????????? source.recycle();
374.???????????? }
375. return b2;
376.???????? }
377. float bitmapWidthF = source.getWidth();
378. float bitmapHeightF = source.getHeight();
379.
380. float bitmapAspect = bitmapWidthF / bitmapHeightF;
381. float viewAspect?? = (float) targetWidth / targetHeight;
382.
383. if (bitmapAspect > viewAspect) {
384. float scale = targetHeight / bitmapHeightF;
385. if (scale < .9F || scale > 1F) {
386.???????????????? scaler.setScale(scale, scale);
387.???????????? } else {
388.???????????????? scaler = null;
389.???????????? }
390.???????? } else {
391. float scale = targetWidth / bitmapWidthF;
392. if (scale < .9F || scale > 1F) {
393.???????????????? scaler.setScale(scale, scale);
394.???????????? } else {
395.???????????????? scaler = null;
396.???????????? }
397.???????? }
398.
399.???????? Bitmap b1;
400. if (scaler != null) {
401. // this is used for minithumb and crop, so we want to filter here.
402.???????????? b1 = Bitmap.createBitmap(source, 0, 0,
403.???????????? source.getWidth(), source.getHeight(), scaler, true);
404.???????? } else {
405.???????????? b1 = source;
406.???????? }
407.
408. if (recycle && b1 != source) {
409.???????????? source.recycle();
410.???????? }
411.
412. int dx1 = Math.max(0, b1.getWidth() - targetWidth);
413. int dy1 = Math.max(0, b1.getHeight() - targetHeight);
414.
415.???????? Bitmap b2 = Bitmap.createBitmap(
416.???????????????? b1,
417.???????????????? dx1 / 2,
418.???????????????? dy1 / 2,
419.???????????????? targetWidth,
420.???????????????? targetHeight);
421.
422. if (b2 != b1) {
423. if (recycle || b1 != source) {
424.???????????????? b1.recycle();
425.???????????? }
426.???????? }
427.
428. return b2;
429.???? }
430.
431. /**
432.????? * SizedThumbnailBitmap contains the bitmap, which is downsampled either from
433.????? * the thumbnail in exif or the full p_w_picpath.
434.????? * mThumbnailData, mThumbnailWidth and mThumbnailHeight are set together only if mThumbnail
435.????? * is not null.
436.????? *
437.????? * The width/height of the sized bitmap may be different from mThumbnailWidth/mThumbnailHeight.
438.????? */
439. private static class SizedThumbnailBitmap {
440. public byte[] mThumbnailData;
441. public Bitmap mBitmap;
442. public int mThumbnailWidth;
443. public int mThumbnailHeight;
444.???? }
445.
446. /**
447.????? * Creates a bitmap by either downsampling from the thumbnail in EXIF or the full p_w_picpath.
448.????? * The functions returns a SizedThumbnailBitmap,
449.????? * which contains a downsampled bitmap and the thumbnail data in EXIF if exists.
450.????? */
451. private static void createThumbnailFromEXIF(String filePath, int targetSize,
452. int maxPixels, SizedThumbnailBitmap sizedThumbBitmap) {
453. if (filePath == null) return;
454.
455.???????? ExifInterface exif = null;
456. byte [] thumbData = null;
457. try {
458.???????????? exif = new ExifInterface(filePath);
459. if (exif != null) {
460.???????????????? thumbData = exif.getThumbnail();
461.???????????? }
462.???????? } catch (IOException ex) {
463.???????????? Log.w(TAG, ex);
464.???????? }
465.
466.???????? BitmapFactory.Options fullOptions = new BitmapFactory.Options();
467.???????? BitmapFactory.Options exifOptions = new BitmapFactory.Options();
468. int exifThumbWidth = 0;
469. int fullThumbWidth = 0;
470.
471. // Compute exifThumbWidth.
472. if (thumbData != null) {
473.???????????? exifOptions.inJustDecodeBounds = true;
474.???????????? BitmapFactory.decodeByteArray(thumbData, 0, thumbData.length, exifOptions);
475.???????????? exifOptions.inSampleSize = computeSampleSize(exifOptions, targetSize, maxPixels);
476.???????????? exifThumbWidth = exifOptions.outWidth / exifOptions.inSampleSize;
477.???????? }
478.
479. // Compute fullThumbWidth.
480.???????? fullOptions.inJustDecodeBounds = true;
481.???????? BitmapFactory.decodeFile(filePath, fullOptions);
482.???????? fullOptions.inSampleSize = computeSampleSize(fullOptions, targetSize, maxPixels);
483.???????? fullThumbWidth = fullOptions.outWidth / fullOptions.inSampleSize;
484.
485. // Choose the larger thumbnail as the returning sizedThumbBitmap.
486. if (thumbData != null && exifThumbWidth >= fullThumbWidth) {
487. int width = exifOptions.outWidth;
488. int height = exifOptions.outHeight;
489.???????????? exifOptions.inJustDecodeBounds = false;
490.???????????? sizedThumbBitmap.mBitmap = BitmapFactory.decodeByteArray(thumbData, 0,
491.???????????????????? thumbData.length, exifOptions);
492. if (sizedThumbBitmap.mBitmap != null) {
493.???????????????? sizedThumbBitmap.mThumbnailData = thumbData;
494.???????????????? sizedThumbBitmap.mThumbnailWidth = width;
495.???????????????? sizedThumbBitmap.mThumbnailHeight = height;
496.???????????? }
497.???????? } else {
498.???????????? fullOptions.inJustDecodeBounds = false;
499.???????????? sizedThumbBitmap.mBitmap = BitmapFactory.decodeFile(filePath, fullOptions);
500.???????? }
501.???? }
502. }
總結
以上是生活随笔為你收集整理的android的图片缩放,Android图片缩放总结及比较的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android新建多个java,Java
- 下一篇: android sina oauth2.