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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/572660.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

rtf乱码解决办法

首先&#xff0c;阐述下rtf&#xff0c;富文本格式文档&#xff0c;目前常用来做模板&#xff1b; 我遇到的问题是rtf中替换后的文本显示是正常的&#xff0c;rtf直接转pdf就不正常了&#xff0c;通过notpad 打开后发现rtf本身内容编码是我没有见过的&#xff08;查资料说时ans…

华为鸿蒙山海,华为包圆了整部《山海经》,鸿蒙是何意?还有青龙白虎朱雀玄武?...

华为已经申请注册“华为鸿蒙”商标并标注该商品可用于操作系统程序鸿蒙一个自带书香气的名字一听就是文化人&#xff01;一听就是中华文化传承人&#xff01;那么鸿蒙是啥意思鸿蒙就是一团气不是普通的气体传说盘古在昆仑山开天辟地之前世界是一团混沌的元气这种自然的元气叫做…

ASP.NET MVC5使用Area区域

转载&#xff1a;http://www.lanhusoft.com/Article/217.html 在大型的ASP.NET mvc5项目中一般都有许多个功能模块&#xff0c;这些功能模块可以用Area&#xff08;中文翻译为区域&#xff09;把它们分离开来&#xff0c;比如&#xff1a;Admin&#xff0c;Customer&#xff0c…

html5 最小化,当前界面最小化快捷键 窗口最小化和全屏化的快捷键是什么?

怎样用快捷键显示最小化的窗口在键盘上同时按下WinD 键&#xff0c;可以最小化所有窗口。在键盘上再次同时按下WinD 键&#xff0c;可以还原步骤1最小化的所有窗口。在键盘上同时按下WindowsM键&#xff0c;可以最小化所有窗口。在键盘上同时按下WindowsShiftM键。电脑窗口最小…

华为鸿蒙用户体验计划怎样关闭,华为用户要注意,手机关闭这3个“默认选项”,还能流畅再用2年...

华为用户要注意&#xff0c;手机关闭这3个“默认选项”&#xff0c;还能流畅再用2年众所周知&#xff0c;我们在使用手机的时候&#xff0c;经常会有这样的感触&#xff0c;就是手机明明才刚买没多久&#xff0c;使用起来却相当的卡顿&#xff0c;这还是为什么&#xff1f;手机…

html 像素跟百分比,html – 将百分比宽度与边距(以像素为单位)组合起来

我有一个包含多个项目的页面,其宽度为33.33&#xff05;,以填充页面的整个宽度.但是,我想在项目之间添加20px的边距(垂直和水平,但垂直是这里的问题),但只是在连续的每个第1和第2项的右边添加20px边距,销毁整个页面. (从小提琴中删除已注释掉的CSS,看看我的意思).现在,问题是&a…

GCC命令

一. 常用编译命令选项 源程序test.c 1. 无选项编译链接用法&#xff1a;#gcc test.c作用&#xff1a;将test.c预处理、汇编、编译并链接形成可执行文件。这里未指定输出文件&#xff0c;默认输出为a.out。 2. 选项 -o用法&#xff1a;#gcc test.c -o test作用&#xff1a;将tes…

html5手机端三级联动城市选择代码,省市县三级联动(jQuery手机端收货地址选择地区代码)...

【实例简介】【实例截图】【核心代码】jQuery手机端收货地址选择代码 - 站长素材默认调用所在地区&#xff1a;设置默认值所在地区&#xff1a;/*** 默认调用*/!function () {var $target $(#J_Address);$target.citySelect();$target.on(click, function (event) {event.stop…

内连接、左外连接、右外连接、交叉连接区别

在之前&#xff0c;我对MSSQL中的内连接和外连接所得出的数据集不是很清楚。这几天重新温习了一下SQL的书本&#xff0c;现在的思路应该是很清楚了&#xff0c;现在把自己的理解发出来给大家温习下。希望和我一样对SQL的连接语句不太理解的朋友能够有所帮助。&#xff08;发这么…

winform数据传递到html,C#下winform和JS的互相调用和传参(webbrowser)

不多说&#xff0c;直接上代码&#xff0c;winform下button1调用js函数&#xff0c;从html页面获取值&#xff0c;然后JS调用WINFORM的函数&#xff0c;传送获取到的值到winform并通过messagebox的方法show出来。一步到位&#xff0c; winform调用JS函数 和JS调用winform函数的…

xcode开发html5工具,5个Xcode开发调试技巧

1.Enable NSZombie Objects(开启僵尸对象)Enable NSZombie Objects可能是整个Xcode开发环境中最有用的调试技巧。这个技巧非常非常容易追踪到重复释放的问题。该技巧会以非常简洁的方式打印指出重复释放的类和该类的内存地址。怎么开启僵尸对象呢&#xff1f;首先打开“Edit Sc…

求1-n之内的素数

#include<stdio.h>#include<math.h>int main(){ int n,i,j,k; scanf("%d",&n); //输入范围n for(i2;i<n;i) { ksqrt(i); for(j2;j<sqrt(i);j) { if(i%j0){ //如果i…

计算机基础和操作系统基础知识测试,计算机基础知识和操作系统.doc

全国计算机等级考试精讲精解精练——二级C第1章 计算机基础知识与操作系统 PAGE 2 PAGE 33技术资料共享知识第1章计算机基础知识与操作系统大纲要求了解计算机的有关概念及软硬件系统的组成&#xff1b;了解数据基本单位&#xff0c;掌握计算机常用数制的转换方法&#xff1b;具…

Unity 协程深入解析与原理

先来直接放一段代码 1 using System.Collections;2 using System.Collections.Generic;3 using UnityEngine;4 5 public class CoroutineTest : MonoBehaviour6 {7 8 void Start()9 { 10 Debug.Log("Start Begin"); 11 12 CustomCoroutine …

计算机操作员初级 第1单元0202微型计算机基本操作 教学大纲,计算机操作员教学大纲...

计算机操作员培训教学大纲一、课程的地位、目的与任务计算机应用基础课程是计算机操作员必修课。通过学习&#xff0c;测试学员的计算机基础知识&#xff0c;基本操作和使用计算机的能力&#xff1b;它是学员学习计算机的入门课程&#xff0c;提高学员的综合学习的能力。二、教…

晓庄学院计算机科学分数,南京晓庄学院计算机单招分数

技校网专门为您推荐的类似问题答案问题1&#xff1a;南京晓庄学院的计算机专业晓庄排名太低计算机实力也弱 你的分这么高 上了浪费 建议上南京林业大学或其它符合等级的外省一流学校问题2&#xff1a;有南京晓庄学院 行知学院 计算机专业的学生吗, 这个学校如何你好啊&#xff…

NAT协议详解

NAT&#xff08;Network Address Translation&#xff0c;网络地址转换&#xff09;是将IP数据报头中的IP地址转换为另一个IP地址的过程。在实际应用中&#xff0c;NAT主要用于实现私有网络访问公共网络的功能。这种通过使用少量的公网IP地址代表较多的私网IP地址的方式&#x…

[Design-Pattern]工厂模式

Java版本 1 package interfaces;2 3 interface Service {4 void method1();5 void method2();6 } 7 8 interface ServiceFactory { 9 Service getService(); 10 } 11 12 class Implementation1 implements Service { 13 Implementation1() {} 14 public void method1…

计算机应用基础文字处理软件应用职高PPT,《计算机应用基础》职高2010修订版_教(学)案...

《计算机应用基础》职高2010修订版_教(学)案 (93页)本资源提供全文预览&#xff0c;点击全文预览即可全文预览,如果喜欢文档就下载吧&#xff0c;查找使用更方便哦&#xff01;39.9 积分&#xfeff;. .《计算机应用基础》职高2010修订版 教案第一章 计算机基础知识第二章 中文…

快速排序【记录一下代码】

本文仅用作学习记录&#xff0c;大神勿喷O(∩_∩)O~ 代码一、百度百科C语言版本代码,参考数据结构p274(清华大学出版社&#xff0c;严蔚敏) 1 void Qsort1(int a[], int low, int high)//百度百科C语言版本代码 2 {/*参考数据结构p274(清华大学出版社&#xff0c;严蔚敏)*/3 …