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 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等经过人家一阵加工而成。

效率好像比第二种方法高一点点。

下面是我的例子:

[html] view
plain
 copy

  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_width="fill_parent"
  5. android:layout_height="fill_parent"
  6. >
  7. <ImageView
  8. android:id="@+id/imageShow"
  9. android:layout_width="wrap_content"
  10. android:layout_height="wrap_content"
  11. />
  12. <ImageView
  13. android:id="@+id/image2"
  14. android:layout_width="wrap_content"
  15. android:layout_height="wrap_content"
  16. />
  17. <TextView
  18. android:id="@+id/text"
  19. android:layout_width="fill_parent"
  20. android:layout_height="wrap_content"
  21. android:text="@string/hello"
  22. />
  23. </LinearLayout>

[java] view
plain
 copy

  1. package com.linc.ResolvePicture;
  2. import java.io.File;
  3. import java.io.FileNotFoundException;
  4. import java.io.FileOutputStream;
  5. import java.io.IOException;
  6. import android.app.Activity;
  7. import android.graphics.Bitmap;
  8. import android.graphics.BitmapFactory;
  9. import android.graphics.Matrix;
  10. import android.graphics.drawable.BitmapDrawable;
  11. import android.graphics.drawable.Drawable;
  12. import android.media.ThumbnailUtils;
  13. import android.os.Bundle;
  14. import android.util.Log;
  15. import android.widget.ImageView;
  16. import android.widget.TextView;
  17. public class ResolvePicture extends Activity {
  18. private static String tag="ResolvePicture";
  19. Drawable bmImg;
  20. ImageView imView;
  21. ImageView imView2;
  22. TextView text;
  23. String theTime;
  24. long start, stop;
  25. /** Called when the activity is first created. */
  26. @Override
  27. public void onCreate(Bundle savedInstanceState) {
  28. super.onCreate(savedInstanceState);
  29. setContentView(R.layout.main);
  30. text=(TextView)findViewById(R.id.text);
  31. imView=(ImageView) findViewById(R.id.imageShow);
  32. imView2=(ImageView) findViewById(R.id.image2);
  33. Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
  34. R.drawable.pic);
  35. start=System.currentTimeMillis();
  36. //        imView.setImageDrawable(resizeImage(bitmap, 300, 100));
  37. imView2.setImageDrawable(resizeImage2("/sdcard/2.jpeg", 200, 100));
  38. stop=System.currentTimeMillis();
  39. String theTime= String.format("\n1 iterative: (%d msec)",
  40. stop - start);
  41. start=System.currentTimeMillis();
  42. imView.setImageBitmap(ThumbnailUtils.extractThumbnail(bitmap,200,100));//2.2才加进来的新类,简单易用
  43. //        imView.setImageDrawable(resizeImage(bitmap, 30, 30));
  44. stop=System.currentTimeMillis();
  45. theTime+= String.format("\n2 iterative: (%d msec)",
  46. stop - start);
  47. text.setText(theTime);
  48. }
  49. //使用Bitmap加Matrix来缩放
  50. public static Drawable resizeImage(Bitmap bitmap, int w, int h)
  51. {
  52. Bitmap BitmapOrg = bitmap;
  53. int width = BitmapOrg.getWidth();
  54. int height = BitmapOrg.getHeight();
  55. int newWidth = w;
  56. int newHeight = h;
  57. float scaleWidth = ((float) newWidth) / width;
  58. float scaleHeight = ((float) newHeight) / height;
  59. Matrix matrix = new Matrix();
  60. matrix.postScale(scaleWidth, scaleHeight);
  61. // if you want to rotate the Bitmap
  62. // matrix.postRotate(45);
  63. Bitmap resizedBitmap = Bitmap.createBitmap(BitmapOrg, 0, 0, width,
  64. height, matrix, true);
  65. return new BitmapDrawable(resizedBitmap);
  66. }
  67. //使用BitmapFactory.Options的inSampleSize参数来缩放
  68. public static Drawable resizeImage2(String path,
  69. int width,int height)
  70. {
  71. BitmapFactory.Options options = new BitmapFactory.Options();
  72. options.inJustDecodeBounds = true;//不加载bitmap到内存中
  73. BitmapFactory.decodeFile(path,options);
  74. int outWidth = options.outWidth;
  75. int outHeight = options.outHeight;
  76. options.inDither = false;
  77. options.inPreferredConfig = Bitmap.Config.ARGB_8888;
  78. options.inSampleSize = 1;
  79. if (outWidth != 0 && outHeight != 0 && width != 0 && height != 0)
  80. {
  81. int sampleSize=(outWidth/width+outHeight/height)/2;
  82. Log.d(tag, "sampleSize = " + sampleSize);
  83. options.inSampleSize = sampleSize;
  84. }
  85. options.inJustDecodeBounds = false;
  86. return new BitmapDrawable(BitmapFactory.decodeFile(path, options));
  87. }
  88. //图片保存
  89. private void saveThePicture(Bitmap bitmap)
  90. {
  91. File file=new File("/sdcard/2.jpeg");
  92. try
  93. {
  94. FileOutputStream fos=new FileOutputStream(file);
  95. if(bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos))
  96. {
  97. fos.flush();
  98. fos.close();
  99. }
  100. }
  101. catch(FileNotFoundException e1)
  102. {
  103. e1.printStackTrace();
  104. }
  105. catch(IOException e2)
  106. {
  107. e2.printStackTrace();
  108. }
  109. }
  110. }

ThumbnailUtils源码:

[java] view
plain
 copy

  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. package android.media;
  17. import android.content.ContentResolver;
  18. import android.content.ContentUris;
  19. import android.content.ContentValues;
  20. import android.database.Cursor;
  21. import android.graphics.Bitmap;
  22. import android.graphics.BitmapFactory;
  23. import android.graphics.Canvas;
  24. import android.graphics.Matrix;
  25. import android.graphics.Rect;
  26. import android.media.MediaMetadataRetriever;
  27. import android.media.MediaFile.MediaFileType;
  28. import android.net.Uri;
  29. import android.os.ParcelFileDescriptor;
  30. import android.provider.BaseColumns;
  31. import android.provider.MediaStore.Images;
  32. import android.provider.MediaStore.Images.Thumbnails;
  33. import android.util.Log;
  34. import java.io.FileInputStream;
  35. import java.io.FileDescriptor;
  36. import java.io.IOException;
  37. import java.io.OutputStream;
  38. /**
  39. * Thumbnail generation routines for media provider.
  40. */
  41. public class ThumbnailUtils {
  42. private static final String TAG = "ThumbnailUtils";
  43. /* Maximum pixels size for created bitmap. */
  44. private static final int MAX_NUM_PIXELS_THUMBNAIL = 512 * 384;
  45. private static final int MAX_NUM_PIXELS_MICRO_THUMBNAIL = 128 * 128;
  46. private static final int UNCONSTRAINED = -1;
  47. /* Options used internally. */
  48. private static final int OPTIONS_NONE = 0x0;
  49. private static final int OPTIONS_SCALE_UP = 0x1;
  50. /**
  51. * Constant used to indicate we should recycle the input in
  52. * {@link #extractThumbnail(Bitmap, int, int, int)} unless the output is the input.
  53. */
  54. public static final int OPTIONS_RECYCLE_INPUT = 0x2;
  55. /**
  56. * Constant used to indicate the dimension of mini thumbnail.
  57. * @hide Only used by media framework and media provider internally.
  58. */
  59. public static final int TARGET_SIZE_MINI_THUMBNAIL = 320;
  60. /**
  61. * Constant used to indicate the dimension of micro thumbnail.
  62. * @hide Only used by media framework and media provider internally.
  63. */
  64. public static final int TARGET_SIZE_MICRO_THUMBNAIL = 96;
  65. /**
  66. * This method first examines if the thumbnail embedded in EXIF is bigger than our target
  67. * size. If not, then it‘ll create a thumbnail from original image. Due to efficiency
  68. * consideration, we want to let MediaThumbRequest avoid calling this method twice for
  69. * both kinds, so it only requests for MICRO_KIND and set saveImage to true.
  70. *
  71. * This method always returns a "square thumbnail" for MICRO_KIND thumbnail.
  72. *
  73. * @param filePath the path of image file
  74. * @param kind could be MINI_KIND or MICRO_KIND
  75. * @return Bitmap
  76. *
  77. * @hide This method is only used by media framework and media provider internally.
  78. */
  79. public static Bitmap createImageThumbnail(String filePath, int kind) {
  80. boolean wantMini = (kind == Images.Thumbnails.MINI_KIND);
  81. int targetSize = wantMini
  82. ? TARGET_SIZE_MINI_THUMBNAIL
  83. : TARGET_SIZE_MICRO_THUMBNAIL;
  84. int maxPixels = wantMini
  85. ? MAX_NUM_PIXELS_THUMBNAIL
  86. : MAX_NUM_PIXELS_MICRO_THUMBNAIL;
  87. SizedThumbnailBitmap sizedThumbnailBitmap = new SizedThumbnailBitmap();
  88. Bitmap bitmap = null;
  89. MediaFileType fileType = MediaFile.getFileType(filePath);
  90. if (fileType != null && fileType.fileType == MediaFile.FILE_TYPE_JPEG) {
  91. createThumbnailFromEXIF(filePath, targetSize, maxPixels, sizedThumbnailBitmap);
  92. bitmap = sizedThumbnailBitmap.mBitmap;
  93. }
  94. if (bitmap == null) {
  95. try {
  96. FileDescriptor fd = new FileInputStream(filePath).getFD();
  97. BitmapFactory.Options options = new BitmapFactory.Options();
  98. options.inSampleSize = 1;
  99. options.inJustDecodeBounds = true;
  100. BitmapFactory.decodeFileDescriptor(fd, null, options);
  101. if (options.mCancel || options.outWidth == -1
  102. || options.outHeight == -1) {
  103. return null;
  104. }
  105. options.inSampleSize = computeSampleSize(
  106. options, targetSize, maxPixels);
  107. options.inJustDecodeBounds = false;
  108. options.inDither = false;
  109. options.inPreferredConfig = Bitmap.Config.ARGB_8888;
  110. bitmap = BitmapFactory.decodeFileDescriptor(fd, null, options);
  111. } catch (IOException ex) {
  112. Log.e(TAG, "", ex);
  113. }
  114. }
  115. if (kind == Images.Thumbnails.MICRO_KIND) {
  116. // now we make it a "square thumbnail" for MICRO_KIND thumbnail
  117. bitmap = extractThumbnail(bitmap,
  118. TARGET_SIZE_MICRO_THUMBNAIL,
  119. TARGET_SIZE_MICRO_THUMBNAIL, OPTIONS_RECYCLE_INPUT);
  120. }
  121. return bitmap;
  122. }
  123. /**
  124. * Create a video thumbnail for a video. May return null if the video is
  125. * corrupt or the format is not supported.
  126. *
  127. * @param filePath the path of video file
  128. * @param kind could be MINI_KIND or MICRO_KIND
  129. */
  130. public static Bitmap createVideoThumbnail(String filePath, int kind) {
  131. Bitmap bitmap = null;
  132. MediaMetadataRetriever retriever = new MediaMetadataRetriever();
  133. try {
  134. retriever.setMode(MediaMetadataRetriever.MODE_CAPTURE_FRAME_ONLY);
  135. retriever.setDataSource(filePath);
  136. bitmap = retriever.captureFrame();
  137. } catch (IllegalArgumentException ex) {
  138. // Assume this is a corrupt video file
  139. } catch (RuntimeException ex) {
  140. // Assume this is a corrupt video file.
  141. } finally {
  142. try {
  143. retriever.release();
  144. } catch (RuntimeException ex) {
  145. // Ignore failures while cleaning up.
  146. }
  147. }
  148. if (kind == Images.Thumbnails.MICRO_KIND && bitmap != null) {
  149. bitmap = extractThumbnail(bitmap,
  150. TARGET_SIZE_MICRO_THUMBNAIL,
  151. TARGET_SIZE_MICRO_THUMBNAIL,
  152. OPTIONS_RECYCLE_INPUT);
  153. }
  154. return bitmap;
  155. }
  156. /**
  157. * Creates a centered bitmap of the desired size.
  158. *
  159. * @param source original bitmap source
  160. * @param width targeted width
  161. * @param height targeted height
  162. */
  163. public static Bitmap extractThumbnail(
  164. Bitmap source, int width, int height) {
  165. return extractThumbnail(source, width, height, OPTIONS_NONE);
  166. }
  167. /**
  168. * Creates a centered bitmap of the desired size.
  169. *
  170. * @param source original bitmap source
  171. * @param width targeted width
  172. * @param height targeted height
  173. * @param options options used during thumbnail extraction
  174. */
  175. public static Bitmap extractThumbnail(
  176. Bitmap source, int width, int height, int options) {
  177. if (source == null) {
  178. return null;
  179. }
  180. float scale;
  181. if (source.getWidth() < source.getHeight()) {
  182. scale = width / (float) source.getWidth();
  183. } else {
  184. scale = height / (float) source.getHeight();
  185. }
  186. Matrix matrix = new Matrix();
  187. matrix.setScale(scale, scale);
  188. Bitmap thumbnail = transform(matrix, source, width, height,
  189. OPTIONS_SCALE_UP | options);
  190. return thumbnail;
  191. }
  192. /*
  193. * Compute the sample size as a function of minSideLength
  194. * and maxNumOfPixels.
  195. * minSideLength is used to specify that minimal width or height of a
  196. * bitmap.
  197. * maxNumOfPixels is used to specify the maximal size in pixels that is
  198. * tolerable in terms of memory usage.
  199. *
  200. * The function returns a sample size based on the constraints.
  201. * Both size and minSideLength can be passed in as IImage.UNCONSTRAINED,
  202. * which indicates no care of the corresponding constraint.
  203. * The functions prefers returning a sample size that
  204. * generates a smaller bitmap, unless minSideLength = IImage.UNCONSTRAINED.
  205. *
  206. * Also, the function rounds up the sample size to a power of 2 or multiple
  207. * of 8 because BitmapFactory only honors sample size this way.
  208. * For example, BitmapFactory downsamples an image by 2 even though the
  209. * request is 3. So we round up the sample size to avoid OOM.
  210. */
  211. private static int computeSampleSize(BitmapFactory.Options options,
  212. int minSideLength, int maxNumOfPixels) {
  213. int initialSize = computeInitialSampleSize(options, minSideLength,
  214. maxNumOfPixels);
  215. int roundedSize;
  216. if (initialSize <= 8 ) {
  217. roundedSize = 1;
  218. while (roundedSize < initialSize) {
  219. roundedSize <<= 1;
  220. }
  221. } else {
  222. roundedSize = (initialSize + 7) / 8 * 8;
  223. }
  224. return roundedSize;
  225. }
  226. private static int computeInitialSampleSize(BitmapFactory.Options options,
  227. int minSideLength, int maxNumOfPixels) {
  228. double w = options.outWidth;
  229. double h = options.outHeight;
  230. int lowerBound = (maxNumOfPixels == UNCONSTRAINED) ? 1 :
  231. (int) Math.ceil(Math.sqrt(w * h / maxNumOfPixels));
  232. int upperBound = (minSideLength == UNCONSTRAINED) ? 128 :
  233. (int) Math.min(Math.floor(w / minSideLength),
  234. Math.floor(h / minSideLength));
  235. if (upperBound < lowerBound) {
  236. // return the larger one when there is no overlapping zone.
  237. return lowerBound;
  238. }
  239. if ((maxNumOfPixels == UNCONSTRAINED) &&
  240. (minSideLength == UNCONSTRAINED)) {
  241. return 1;
  242. } else if (minSideLength == UNCONSTRAINED) {
  243. return lowerBound;
  244. } else {
  245. return upperBound;
  246. }
  247. }
  248. /**
  249. * Make a bitmap from a given Uri, minimal side length, and maximum number of pixels.
  250. * The image data will be read from specified pfd if it‘s not null, otherwise
  251. * a new input stream will be created using specified ContentResolver.
  252. *
  253. * Clients are allowed to pass their own BitmapFactory.Options used for bitmap decoding. A
  254. * new BitmapFactory.Options will be created if options is null.
  255. */
  256. private static Bitmap makeBitmap(int minSideLength, int maxNumOfPixels,
  257. Uri uri, ContentResolver cr, ParcelFileDescriptor pfd,
  258. BitmapFactory.Options options) {
  259. Bitmap b = null;
  260. try {
  261. if (pfd == null) pfd = makeInputStream(uri, cr);
  262. if (pfd == null) return null;
  263. if (options == null) options = new BitmapFactory.Options();
  264. FileDescriptor fd = pfd.getFileDescriptor();
  265. options.inSampleSize = 1;
  266. options.inJustDecodeBounds = true;
  267. BitmapFactory.decodeFileDescriptor(fd, null, options);
  268. if (options.mCancel || options.outWidth == -1
  269. || options.outHeight == -1) {
  270. return null;
  271. }
  272. options.inSampleSize = computeSampleSize(
  273. options, minSideLength, maxNumOfPixels);
  274. options.inJustDecodeBounds = false;
  275. options.inDither = false;
  276. options.inPreferredConfig = Bitmap.Config.ARGB_8888;
  277. b = BitmapFactory.decodeFileDescriptor(fd, null, options);
  278. } catch (OutOfMemoryError ex) {
  279. Log.e(TAG, "Got oom exception ", ex);
  280. return null;
  281. } finally {
  282. closeSilently(pfd);
  283. }
  284. return b;
  285. }
  286. private static void closeSilently(ParcelFileDescriptor c) {
  287. if (c == null) return;
  288. try {
  289. c.close();
  290. } catch (Throwable t) {
  291. // do nothing
  292. }
  293. }
  294. private static ParcelFileDescriptor makeInputStream(
  295. Uri uri, ContentResolver cr) {
  296. try {
  297. return cr.openFileDescriptor(uri, "r");
  298. } catch (IOException ex) {
  299. return null;
  300. }
  301. }
  302. /**
  303. * Transform source Bitmap to targeted width and height.
  304. */
  305. private static Bitmap transform(Matrix scaler,
  306. Bitmap source,
  307. int targetWidth,
  308. int targetHeight,
  309. int options) {
  310. boolean scaleUp = (options & OPTIONS_SCALE_UP) != 0;
  311. boolean recycle = (options & OPTIONS_RECYCLE_INPUT) != 0;
  312. int deltaX = source.getWidth() - targetWidth;
  313. int deltaY = source.getHeight() - targetHeight;
  314. if (!scaleUp && (deltaX < 0 || deltaY < 0)) {
  315. /*
  316. * In this case the bitmap is smaller, at least in one dimension,
  317. * than the target.  Transform it by placing as much of the image
  318. * as possible into the target and leaving the top/bottom or
  319. * left/right (or both) black.
  320. */
  321. Bitmap b2 = Bitmap.createBitmap(targetWidth, targetHeight,
  322. Bitmap.Config.ARGB_8888);
  323. Canvas c = new Canvas(b2);
  324. int deltaXHalf = Math.max(0, deltaX / 2);
  325. int deltaYHalf = Math.max(0, deltaY / 2);
  326. Rect src = new Rect(
  327. deltaXHalf,
  328. deltaYHalf,
  329. deltaXHalf + Math.min(targetWidth, source.getWidth()),
  330. deltaYHalf + Math.min(targetHeight, source.getHeight()));
  331. int dstX = (targetWidth  - src.width())  / 2;
  332. int dstY = (targetHeight - src.height()) / 2;
  333. Rect dst = new Rect(
  334. dstX,
  335. dstY,
  336. targetWidth - dstX,
  337. targetHeight - dstY);
  338. c.drawBitmap(source, src, dst, null);
  339. if (recycle) {
  340. source.recycle();
  341. }
  342. return b2;
  343. }
  344. float bitmapWidthF = source.getWidth();
  345. float bitmapHeightF = source.getHeight();
  346. float bitmapAspect = bitmapWidthF / bitmapHeightF;
  347. float viewAspect   = (float) targetWidth / targetHeight;
  348. if (bitmapAspect > viewAspect) {
  349. float scale = targetHeight / bitmapHeightF;
  350. if (scale < .9F || scale > 1F) {
  351. scaler.setScale(scale, scale);
  352. } else {
  353. scaler = null;
  354. }
  355. } else {
  356. float scale = targetWidth / bitmapWidthF;
  357. if (scale < .9F || scale > 1F) {
  358. scaler.setScale(scale, scale);
  359. } else {
  360. scaler = null;
  361. }
  362. }
  363. Bitmap b1;
  364. if (scaler != null) {
  365. // this is used for minithumb and crop, so we want to filter here.
  366. b1 = Bitmap.createBitmap(source, 0, 0,
  367. source.getWidth(), source.getHeight(), scaler, true);
  368. } else {
  369. b1 = source;
  370. }
  371. if (recycle && b1 != source) {
  372. source.recycle();
  373. }
  374. int dx1 = Math.max(0, b1.getWidth() - targetWidth);
  375. int dy1 = Math.max(0, b1.getHeight() - targetHeight);
  376. Bitmap b2 = Bitmap.createBitmap(
  377. b1,
  378. dx1 / 2,
  379. dy1 / 2,
  380. targetWidth,
  381. targetHeight);
  382. if (b2 != b1) {
  383. if (recycle || b1 != source) {
  384. b1.recycle();
  385. }
  386. }
  387. return b2;
  388. }
  389. /**
  390. * SizedThumbnailBitmap contains the bitmap, which is downsampled either from
  391. * the thumbnail in exif or the full image.
  392. * mThumbnailData, mThumbnailWidth and mThumbnailHeight are set together only if mThumbnail
  393. * is not null.
  394. *
  395. * The width/height of the sized bitmap may be different from mThumbnailWidth/mThumbnailHeight.
  396. */
  397. private static class SizedThumbnailBitmap {
  398. public byte[] mThumbnailData;
  399. public Bitmap mBitmap;
  400. public int mThumbnailWidth;
  401. public int mThumbnailHeight;
  402. }
  403. /**
  404. * Creates a bitmap by either downsampling from the thumbnail in EXIF or the full image.
  405. * The functions returns a SizedThumbnailBitmap,
  406. * which contains a downsampled bitmap and the thumbnail data in EXIF if exists.
  407. */
  408. private static void createThumbnailFromEXIF(String filePath, int targetSize,
  409. int maxPixels, SizedThumbnailBitmap sizedThumbBitmap) {
  410. if (filePath == null) return;
  411. ExifInterface exif = null;
  412. byte [] thumbData = null;
  413. try {
  414. exif = new ExifInterface(filePath);
  415. if (exif != null) {
  416. thumbData = exif.getThumbnail();
  417. }
  418. } catch (IOException ex) {
  419. Log.w(TAG, ex);
  420. }
  421. BitmapFactory.Options fullOptions = new BitmapFactory.Options();
  422. BitmapFactory.Options exifOptions = new BitmapFactory.Options();
  423. int exifThumbWidth = 0;
  424. int fullThumbWidth = 0;
  425. // Compute exifThumbWidth.
  426. if (thumbData != null) {
  427. exifOptions.inJustDecodeBounds = true;
  428. BitmapFactory.decodeByteArray(thumbData, 0, thumbData.length, exifOptions);
  429. exifOptions.inSampleSize = computeSampleSize(exifOptions, targetSize, maxPixels);
  430. exifThumbWidth = exifOptions.outWidth / exifOptions.inSampleSize;
  431. }
  432. // Compute fullThumbWidth.
  433. fullOptions.inJustDecodeBounds = true;
  434. BitmapFactory.decodeFile(filePath, fullOptions);
  435. fullOptions.inSampleSize = computeSampleSize(fullOptions, targetSize, maxPixels);
  436. fullThumbWidth = fullOptions.outWidth / fullOptions.inSampleSize;
  437. // Choose the larger thumbnail as the returning sizedThumbBitmap.
  438. if (thumbData != null && exifThumbWidth >= fullThumbWidth) {
  439. int width = exifOptions.outWidth;
  440. int height = exifOptions.outHeight;
  441. exifOptions.inJustDecodeBounds = false;
  442. sizedThumbBitmap.mBitmap = BitmapFactory.decodeByteArray(thumbData, 0,
  443. thumbData.length, exifOptions);
  444. if (sizedThumbBitmap.mBitmap != null) {
  445. sizedThumbBitmap.mThumbnailData = thumbData;
  446. sizedThumbBitmap.mThumbnailWidth = width;
  447. sizedThumbBitmap.mThumbnailHeight = height;
  448. }
  449. } else {
  450. fullOptions.inJustDecodeBounds = false;
  451. sizedThumbBitmap.mBitmap = BitmapFactory.decodeFile(filePath, fullOptions);
  452. }
  453. }
  454. }
时间: 2024-10-03 18:59:55

Android--生成缩略图------方法总结的相关文章

C# 生成缩略图 方法

#region -生成缩略图- /// <summary> /// 生成缩略图 /// </summary> /// <param name="orginalImagePath">原图片对象</param> /// <param name="thumbnailPath">缩略图的路径</param> /// <param name="width">指定宽度<

Android生成keystore方法

一.eclipse 中生成android keystore 建立任意一个android项目(例如:AntForAndroid) 右键AntForAndroid根目录弹出菜单->Android Tools -> Export Signed Application Package... Next > 选择"Create new keystore"并且保存在一个目录下面(本例子保存在项目跟目录下) 输入密码,然后next 填写一些信息,填写的Alias 和 密码不要忘记了

C#生成缩略图

[csharp] view plain copy print? /// 生成缩略图 /// </summary> /// <param name="originalImagePath">源图路径</param> /// <param name="thumbnailPath">缩略图路径</param> /// <param name="width">缩略图宽度</par

asp.net生成缩略图、文字图片水印

1 /// <summary> 2 /// 会产生graphics异常的PixelFormat 3 /// </summary> 4 private static PixelFormat[] indexedPixelFormats = { PixelFormat.Undefined, PixelFormat.DontCare, 5 PixelFormat.Format16bppArgb1555, PixelFormat.Format1bppIndexed, PixelFormat.

C#生成缩略图 (通用模式)

用数据库保存图片的路径和文件名称,把文件保存在文件夹中.//保存在数据库中的文件路径ArrayList arrFilePath=new ArrayList();arrFilePath=myCommonMethod.UploadPic(Files,"/UpLoads/UpPicture/");//获取文件名称string fileName=arrFilePath[0].SubString(arrFilePath[0].LastIndexOf("/")+1);//源图路

ASP组件AspJpeg(加水印)生成缩略图等使用方法

ASP组件AspJpeg(加水印)生成缩略图等使用方法 作者: 字体:[增加 减小] 类型:转载 时间:2012-12-17我要评论 ASPJPEG是一款功能相当强大的图象处理组件,用它可以轻松地做出图片的缩略图和为图片加上水印功能.下面简单介绍一下使用方法,需要的朋友可以了解下 一.为图片添加水印 复制代码 代码如下: <% Dim Jpeg ''''//声明变量 Set Jpeg = Server.CreateObject("Persits.Jpeg") ''''//调用组件

.net又一个生成缩略图的方法,不变形

生成缩略图是一个十分常用功能,找到了一个方法,重写部分代码,实用又好用,.net又一个生成缩略图的方法,不变形 1 /// <summary> 2 /// 为图片生成缩略图 by 何问起 3 /// </summary> 4 /// <param name="phyPath">原图片的路径</param> 5 /// <param name="width">缩略图宽</param> 6 ///

.net又一个生成缩略图的方法,不变形,非常好用

生成缩略图是一个十分常用功能,找到了一个方法,重写部分代码,实用又好用,.net又一个生成缩略图的方法,不变形 1 /// <summary> 2 /// 为图片生成缩略图 by 何问起 3 /// </summary> 4 /// <param name="phyPath">原图片的路径</param> 5 /// <param name="width">缩略图宽</param> 6 ///

C#生成缩略图不失真的方法

最近一个手持机项目有个需求,因为物料图片的大小不一,有的很大显示到手持机上会只显示图片的一部分,界面显得非常乱,很影响客户的体验度.所以需要一个方法,将上传到服务器上的图片进行处理,按照一定的大小格式进行保存. 下面提供了两种获取图片缩略图的方法,供大家参考. 方法一:通过调用Image对象的自带方法GetThumbnailImage()进行图片转换 /// <summary> /// 生成缩略图重载方法,返回缩略图的Image对象 /// </summary> /// <p

C#简单生成缩略图的方法

本文实例讲述了C#简单生成缩略图的方法.分享给大家供大家参考.具体实现方法如下: /// <summary> /// 生成缩略图 /// </summary> /// <param name="originalImagePath">源图路径(物理路径)</param> /// <param name="thumbnailPath">缩略图路径(物理路径)</param> /// <para