在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图片缩放总结及比较相关推荐

  1. android layout后还原位置,Android图片框架photoview如何记住所有状态并还原,包括缩放度,缩放后的移动的距离等等...

    Android图片框架photoview如何记住状态并还原,包括缩放度,缩放后的移动的距离等等,尝试了好多方法都没有作用. private void generateImages() { for (i ...

  2. Android 双击和手势的图片缩放

    2019独角兽企业重金招聘Python工程师标准>>> 代码: package com.mooc.view; import android.content.Context; impo ...

  3. android 多点触控缩放,Android多点触控(图片的缩放Demo)

    本文主要介绍Android的多点触控,使用了一个图片缩放的实例,来更好的说明其原理.需要实现OnTouchListener接口,重写其中的onTouch方法. 实现效果图: 源代码: 布局文件: ac ...

  4. [Android] 触屏setOnTouchListener实现图片缩放、移动、绘制和添加水印

        前一篇文章讲述了Android实现图片Matrix矩阵类缩放.旋转.对比度.亮度.饱和度处理,但是真正的图片软件都是使用触屏实现图片缩放.移动.添加水印等功能,所以该篇文章主要通过setOnT ...

  5. android 手势事件 重写,Android实现通过手势控制图片大小缩放的方法

    本文实例讲述了Android实现通过手势控制图片大小缩放的方法.分享给大家供大家参考,具体如下: 该程序实现的是通过手势来缩放图片,从左向右挥动图片时图片被放大,从右向左挥动图片时图片被缩小,挥动速度 ...

  6. Android 调用相册 拍照 实现系统控件缩放 切割图片

    android 下如果做处理图片的软件 可以调用系统的控件 实现缩放切割图片 非常好的效果 今天写了一个demo分享给大家. package cn.m15.test;import java.io.By ...

  7. Android实现支持缩放平移图片

    本文主要用到了以下知识点 Matrix GestureDetector 能够捕捉到长按.双击 ScaleGestureDetector 用于检测缩放的手势 自由的缩放 需求:当图片加载时,将图片在屏幕 ...

  8. android 横向滚动图片,Android使用Photoview实现图片左右滑动及缩放功能

    Android使用Photoview实现图片左右滑动及缩放功能 发布时间:2020-10-12 14:51:12 来源:脚本之家 阅读:119 作者:kuaizilanqiu 我想,不管是做什么样的a ...

  9. Android 手势检测实战 打造支持缩放平移的图片预览效果(下)

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/39480503,本文出自:[张鸿洋的博客] 上一篇已经带大家实现了自由的放大缩小图 ...

最新文章

  1. 解决WebClient或HttpWebRequest首次连接缓慢问题
  2. Python 技术篇-文件操控:文件的移动和复制
  3. 记录本地Hexo博客部署到服务器上
  4. python笔记之序列(str的基本使用和常用操作)
  5. Java静态方法可能会产生代码异味
  6. 计算机几何学论坛,现代几何学与计算机科学-中国计算机学会.pdf
  7. php中数组下标,PHP数组介绍_php
  8. java 定位打印_Java定位打印(Java location printing).doc
  9. ORM框架,sqlsugar学习一
  10. mvc 调试 f12 浏览器闪退
  11. Redis学习笔记(四)——数据结构之List
  12. DataStore详解
  13. 大学四年,工作2年我总结了后端面试的所有知识点(持续更新)
  14. 自行委托的鉴定意见可以作为审理依据
  15. python 全角字符和半角字符切换
  16. POJ 1392 Ouroboros Snake 欧拉回路
  17. 登录前的人机验证VAPTCHA
  18. PHP 进阶:代码整洁之道
  19. 四种基础博弈 巴什博奕+威佐夫博奕+斐波那契博弈+K倍博弈
  20. 编写Python脚本调用企查查股东信息接口将数据导出为excel文件

热门文章

  1. MySQL启动、连接,退出,关闭命令学习
  2. Java 遍历HashTable
  3. MATLAB基础教程(2) 语言基础知识
  4. C++基础10-类和对象之友元函数
  5. mysql 导入导出大文件
  6. echarts3 loading动画无法去除解决方案
  7. mitmproxy抓包 | Python双篡改假请求实战(六)
  8. python 过滤文本中的标点符号(转)
  9. 使用fiddler的过滤条件
  10. leetCode题解之Reshape the Matrix