您的位置:首页 > 移动开发 > Android开发

Android图片缩放总结及比较

2011-11-15 10:08 253 查看
在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 image, returning a smaller image 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. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

3. android:orientation="vertical"

4. android:layout_;fill_parent"

5. android:layout_height="fill_parent"

6. >

7.

8. <ImageView

9. android:id="@+id/imageShow"

10. android:layout_;wrap_content"

11. android:layout_height="wrap_content"

12. />

13. <ImageView

14. android:id="@+id/image2"

15. android:layout_;wrap_content"

16. android:layout_height="wrap_content"

17. />

18. <TextView

19. android:id="@+id/text"

20. android:layout_;fill_parent"

21. android:layout_height="wrap_content"

22. android:text="@string/hello"

23. />

24. </LinearLayout>

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.imageShow);

37. imView2=(ImageView) findViewById(R.id.image2);

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 image. 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 image 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 image 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 image 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 image

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 image.

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 image.

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. }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  比较 总结 移动开发