Android 使用ThumbnailUtils类获取视频的缩略图

前言
         欢迎大家我分享和推荐好用的代码段~~
声明
         欢迎转载,但请保留文章原始出处:
         CSDN:http://www.csdn.net
         雨季o莫忧离:http://blog.csdn.net/luckkof

正文

 

今天看了一段代码,是关于获取视频的缩略图的,让我认识了一个ThumbnailUtils类,代码如下。

[java]  view plain copy
  1. Bitmap bitmap = ThumbnailUtils.createVideoThumbnail(path, Thumbnails.MINI_KIND); //用于获取视频的缩略图  
  2.   
  3. BitmapDrawable background=new BitmapDrawable(bitmap);  


通过察看android.media.ThumbnailUtils的源码,可以发现该类提供了三种静态方法可以直接调用获取,从而可以帮助我们获取系统视频或图片文件的缩略图。

Android 使用ThumbnailUtils类获取视频的缩略图_第1张图片

第一个方法可以用来创建一张视频的缩略图,如果视频已损坏或者格式不支持可能返回null

[java]  view plain copy
  1. /** 
  2.  * Create a video thumbnail for a video. May return null if the video is 
  3.  * corrupt or the format is not supported. 
  4.  * 
  5.  * @param filePath the path of video file 
  6.  * @param kind could be MINI_KIND or MICRO_KIND 
  7.  */  
  8. public static Bitmap createVideoThumbnail(String filePath, int kind) {  
  9.     Bitmap bitmap = null;  
  10.     MediaMetadataRetriever retriever = new MediaMetadataRetriever();  
  11.     try {  
  12.         retriever.setDataSource(filePath);  
  13.         bitmap = retriever.getFrameAtTime(-1);  
  14.     } catch (IllegalArgumentException ex) {  
  15.         // Assume this is a corrupt video file  
  16.     } catch (RuntimeException ex) {  
  17.         // Assume this is a corrupt video file.  
  18.     } finally {  
  19.         try {  
  20.             retriever.release();  
  21.         } catch (RuntimeException ex) {  
  22.             // Ignore failures while cleaning up.  
  23.         }  
  24.     }  
  25.   
  26.     if (bitmap == nullreturn null;  
  27.   
  28.     if (kind == Images.Thumbnails.MINI_KIND) {  
  29.         // Scale down the bitmap if it's too large.  
  30.         int width = bitmap.getWidth();  
  31.         int height = bitmap.getHeight();  
  32.         int max = Math.max(width, height);  
  33.         if (max > 512) {  
  34.             float scale = 512f / max;  
  35.             int w = Math.round(scale * width);  
  36.             int h = Math.round(scale * height);  
  37.             bitmap = Bitmap.createScaledBitmap(bitmap, w, h, true);  
  38.         }  
  39.     } else if (kind == Images.Thumbnails.MICRO_KIND) {  
  40.         bitmap = extractThumbnail(bitmap,  
  41.                 TARGET_SIZE_MICRO_THUMBNAIL,  
  42.                 TARGET_SIZE_MICRO_THUMBNAIL,  
  43.                 OPTIONS_RECYCLE_INPUT);  
  44.     }  
  45.     return bitmap;  
  46. }  


参数说明:

  • filePath表示视频文件路径
  • kind表示类型,可以有两个选项,分别是Images.Thumbnails.MICRO_KIND和Images.Thumbnails.MINI_KIND,其中,MINI_KIND: 512 x 384,MICRO_KIND: 96 x 96,当然读了代码你会发现,你也可以传入任意的int型数字,只是就不会对获取的bitmap进行相关的设置,我们可以自己使用extractThumbnail( Bitmap source, int width, int height)方法对返回的bitmap进行相关设置。


第二个方法可以用来创建一个指定大小的缩略图


[java]  view plain copy
  1. /** 
  2.  * Creates a centered bitmap of the desired size. 
  3.  * 
  4.  * @param source original bitmap source 
  5.  * @param width targeted width 
  6.  * @param height targeted height 
  7.  */  
  8. public static Bitmap extractThumbnail(  
  9.         Bitmap source, int width, int height) {  
  10.     return extractThumbnail(source, width, height, OPTIONS_NONE);  
  11. }  

参数说明:

  • source表示图片源文件(Bitmap类型)
  • width表示指定压缩成后的宽度
  • height表示指定压缩成后的高度


第三个方法可以用来创建一个指定大小的缩略图

[java]  view plain copy
  1. /** 
  2.      * Creates a centered bitmap of the desired size. 
  3.      * 
  4.      * @param source original bitmap source 
  5.      * @param width targeted width 
  6.      * @param height targeted height 
  7.      * @param options options used during thumbnail extraction 
  8.      */  
  9.     public static Bitmap extractThumbnail(  
  10.             Bitmap source, int width, int height, int options) {  
  11.         if (source == null) {  
  12.             return null;  
  13.         }  
  14.   
  15.         float scale;  
  16.         if (source.getWidth() < source.getHeight()) {  
  17.             scale = width / (float) source.getWidth();  
  18.         } else {  
  19.             scale = height / (float) source.getHeight();  
  20.         }  
  21.         Matrix matrix = new Matrix();  
  22.         matrix.setScale(scale, scale);  
  23.         Bitmap thumbnail = transform(matrix, source, width, height,  
  24.                 OPTIONS_SCALE_UP | options);  
  25.         return thumbnail;  
  26.     }  




参数说明:
  • source表示图片源文件(Bitmap类型)
  • width表示指定压缩成后的宽度
  • height表示指定压缩成后的高度
  • options表示在缩略图抽取时提供的选项,如果options定义为OPTIONS_RECYCLE_INPUT,则回收@param source这个资源文件(除非缩略图等于@param source)

=====================华丽丽的分界线========================


下面展示两个封装好的代码,用来获取图像和视频的缩略图

[java]  view plain copy
  1. /**  
  2.      * 根据指定的图像路径和大小来获取缩略图  
  3.      * 此方法有两点好处:  
  4.      *     1. 使用较小的内存空间,第一次获取的bitmap实际上为null,只是为了读取宽度和高度,  
  5.      *        第二次读取的bitmap是根据比例压缩过的图像,第三次读取的bitmap是所要的缩略图。  
  6.      *     2. 缩略图对于原图像来讲没有拉伸,这里使用了2.2版本的新工具ThumbnailUtils,使  
  7.      *        用这个工具生成的图像不会被拉伸。  
  8.      * @param imagePath 图像的路径  
  9.      * @param width 指定输出图像的宽度  
  10.      * @param height 指定输出图像的高度  
  11.      * @return 生成的缩略图  
  12.      */    
  13.     private Bitmap getImageThumbnail(String imagePath, int width, int height) {    
  14.         Bitmap bitmap = null;    
  15.         BitmapFactory.Options options = new BitmapFactory.Options();    
  16.         options.inJustDecodeBounds = true;    
  17.         // 获取这个图片的宽和高,注意此处的bitmap为null    
  18.         bitmap = BitmapFactory.decodeFile(imagePath, options);    
  19.         options.inJustDecodeBounds = false// 设为 false    
  20.         // 计算缩放比    
  21.         int h = options.outHeight;    
  22.         int w = options.outWidth;    
  23.         int beWidth = w / width;    
  24.         int beHeight = h / height;    
  25.         int be = 1;    
  26.         if (beWidth < beHeight) {    
  27.             be = beWidth;    
  28.         } else {    
  29.             be = beHeight;    
  30.         }    
  31.         if (be <= 0) {    
  32.             be = 1;    
  33.         }    
  34.         options.inSampleSize = be;    
  35.         // 重新读入图片,读取缩放后的bitmap,注意这次要把options.inJustDecodeBounds 设为 false    
  36.         bitmap = BitmapFactory.decodeFile(imagePath, options);    
  37.         // 利用ThumbnailUtils来创建缩略图,这里要指定要缩放哪个Bitmap对象    
  38.         bitmap = ThumbnailUtils.extractThumbnail(bitmap, width, height,    
  39.                 ThumbnailUtils.OPTIONS_RECYCLE_INPUT);    
  40.         return bitmap;    
  41.     }    
  42.     
  43.     /**  
  44.      * 获取视频的缩略图  
  45.      * 先通过ThumbnailUtils来创建一个视频的缩略图,然后再利用ThumbnailUtils来生成指定大小的缩略图。  
  46.      * 如果想要的缩略图的宽和高都小于MICRO_KIND,则类型要使用MICRO_KIND作为kind的值,这样会节省内存。  
  47.      * @param videoPath 视频的路径  
  48.      * @param width 指定输出视频缩略图的宽度  
  49.      * @param height 指定输出视频缩略图的高度度  
  50.      * @param kind 参照MediaStore.Images.Thumbnails类中的常量MINI_KIND和MICRO_KIND。  
  51.      *            其中,MINI_KIND: 512 x 384,MICRO_KIND: 96 x 96  
  52.      * @return 指定大小的视频缩略图  
  53.      */    
  54.     private Bitmap getVideoThumbnail(String videoPath, int width, int height,    
  55.             int kind) {    
  56.         Bitmap bitmap = null;    
  57.         // 获取视频的缩略图    
  58.         bitmap = ThumbnailUtils.createVideoThumbnail(videoPath, kind);    
  59.         System.out.println("w"+bitmap.getWidth());    
  60.         System.out.println("h"+bitmap.getHeight());    
  61.         bitmap = ThumbnailUtils.extractThumbnail(bitmap, width, height,    
  62.                 ThumbnailUtils.OPTIONS_RECYCLE_INPUT);    
  63.         return bitmap;    
  64.     }    


   =====================华丽丽的分界线========================


最后附上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.   
  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, or null on failures 
  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.             FileInputStream stream = null;  
  108.             try {  
  109.                 stream = new FileInputStream(filePath);  
  110.                 FileDescriptor fd = stream.getFD();  
  111.                 BitmapFactory.Options options = new BitmapFactory.Options();  
  112.                 options.inSampleSize = 1;  
  113.                 options.inJustDecodeBounds = true;  
  114.                 BitmapFactory.decodeFileDescriptor(fd, null, options);  
  115.                 if (options.mCancel || options.outWidth == -1  
  116.                         || options.outHeight == -1) {  
  117.                     return null;  
  118.                 }  
  119.                 options.inSampleSize = computeSampleSize(  
  120.                         options, targetSize, maxPixels);  
  121.                 options.inJustDecodeBounds = false;  
  122.   
  123.                 options.inDither = false;  
  124.                 options.inPreferredConfig = Bitmap.Config.ARGB_8888;  
  125.                 bitmap = BitmapFactory.decodeFileDescriptor(fd, null, options);  
  126.             } catch (IOException ex) {  
  127.                 Log.e(TAG, "", ex);  
  128.             } catch (OutOfMemoryError oom) {  
  129.                 Log.e(TAG, "Unable to decode file " + filePath + ". OutOfMemoryError.", oom);  
  130.             } finally {  
  131.                 try {  
  132.                     if (stream != null) {  
  133.                         stream.close();  
  134.                     }  
  135.                 } catch (IOException ex) {  
  136.                     Log.e(TAG, "", ex);  
  137.                 }  
  138.             }  
  139.   
  140.         }  
  141.   
  142.         if (kind == Images.Thumbnails.MICRO_KIND) {  
  143.             // now we make it a "square thumbnail" for MICRO_KIND thumbnail  
  144.             bitmap = extractThumbnail(bitmap,  
  145.                     TARGET_SIZE_MICRO_THUMBNAIL,  
  146.                     TARGET_SIZE_MICRO_THUMBNAIL, OPTIONS_RECYCLE_INPUT);  
  147.         }  
  148.         return bitmap;  
  149.     }  
  150.   
  151.     /** 
  152.      * Create a video thumbnail for a video. May return null if the video is 
  153.      * corrupt or the format is not supported. 
  154.      * 
  155.      * @param filePath the path of video file 
  156.      * @param kind could be MINI_KIND or MICRO_KIND 
  157.      */  
  158.     public static Bitmap createVideoThumbnail(String filePath, int kind) {  
  159.         Bitmap bitmap = null;  
  160.         MediaMetadataRetriever retriever = new MediaMetadataRetriever();  
  161.         try {  
  162.             retriever.setDataSource(filePath);  
  163.             bitmap = retriever.getFrameAtTime(-1);  
  164.         } catch (IllegalArgumentException ex) {  
  165.             // Assume this is a corrupt video file  
  166.         } catch (RuntimeException ex) {  
  167.             // Assume this is a corrupt video file.  
  168.         } finally {  
  169.             try {  
  170.                 retriever.release();  
  171.             } catch (RuntimeException ex) {  
  172.                 // Ignore failures while cleaning up.  
  173.             }  
  174.         }  
  175.   
  176.         if (bitmap == nullreturn null;  
  177.   
  178.         if (kind == Images.Thumbnails.MINI_KIND) {  
  179.             // Scale down the bitmap if it's too large.  
  180.             int width = bitmap.getWidth();  
  181.             int height = bitmap.getHeight();  
  182.             int max = Math.max(width, height);  
  183.             if (max > 512) {  
  184.                 float scale = 512f / max;  
  185.                 int w = Math.round(scale * width);  
  186.                 int h = Math.round(scale * height);  
  187.                 bitmap = Bitmap.createScaledBitmap(bitmap, w, h, true);  
  188.             }  
  189.         } else if (kind == Images.Thumbnails.MICRO_KIND) {  
  190.             bitmap = extractThumbnail(bitmap,  
  191.                     TARGET_SIZE_MICRO_THUMBNAIL,  
  192.                     TARGET_SIZE_MICRO_THUMBNAIL,  
  193.                     OPTIONS_RECYCLE_INPUT);  
  194.         }  
  195.         return bitmap;  
  196.     }  
  197.   
  198.     /** 
  199.      * Creates a centered bitmap of the desired size. 
  200.      * 
  201.      * @param source original bitmap source 
  202.      * @param width targeted width 
  203.      * @param height targeted height 
  204.      */  
  205.     public static Bitmap extractThumbnail(  
  206.             Bitmap source, int width, int height) {  
  207.         return extractThumbnail(source, width, height, OPTIONS_NONE);  
  208.     }  
  209.   
  210.     /** 
  211.      * Creates a centered bitmap of the desired size. 
  212.      * 
  213.      * @param source original bitmap source 
  214.      * @param width targeted width 
  215.      * @param height targeted height 
  216.      * @param options options used during thumbnail extraction 
  217.      */  
  218.     public static Bitmap extractThumbnail(  
  219.             Bitmap source, int width, int height, int options) {  
  220.         if (source == null) {  
  221.             return null;  
  222.         }  
  223.   
  224.         float scale;  
  225.         if (source.getWidth() < source.getHeight()) {  
  226.             scale = width / (float) source.getWidth();  
  227.         } else {  
  228.             scale = height / (float) source.getHeight();  
  229.         }  
  230.         Matrix matrix = new Matrix();  
  231.         matrix.setScale(scale, scale);  
  232.         Bitmap thumbnail = transform(matrix, source, width, height,  
  233.                 OPTIONS_SCALE_UP | options);  
  234.         return thumbnail;  
  235.     }  
  236.   
  237.     /* 
  238.      * Compute the sample size as a function of minSideLength 
  239.      * and maxNumOfPixels. 
  240.      * minSideLength is used to specify that minimal width or height of a 
  241.      * bitmap. 
  242.      * maxNumOfPixels is used to specify the maximal size in pixels that is 
  243.      * tolerable in terms of memory usage. 
  244.      * 
  245.      * The function returns a sample size based on the constraints. 
  246.      * Both size and minSideLength can be passed in as IImage.UNCONSTRAINED, 
  247.      * which indicates no care of the corresponding constraint. 
  248.      * The functions prefers returning a sample size that 
  249.      * generates a smaller bitmap, unless minSideLength = IImage.UNCONSTRAINED. 
  250.      * 
  251.      * Also, the function rounds up the sample size to a power of 2 or multiple 
  252.      * of 8 because BitmapFactory only honors sample size this way. 
  253.      * For example, BitmapFactory downsamples an image by 2 even though the 
  254.      * request is 3. So we round up the sample size to avoid OOM. 
  255.      */  
  256.     private static int computeSampleSize(BitmapFactory.Options options,  
  257.             int minSideLength, int maxNumOfPixels) {  
  258.         int initialSize = computeInitialSampleSize(options, minSideLength,  
  259.                 maxNumOfPixels);  
  260.   
  261.         int roundedSize;  
  262.         if (initialSize <= 8 ) {  
  263.             roundedSize = 1;  
  264.             while (roundedSize < initialSize) {  
  265.                 roundedSize <<= 1;  
  266.             }  
  267.         } else {  
  268.             roundedSize = (initialSize + 7) / 8 * 8;  
  269.         }  
  270.   
  271.         return roundedSize;  
  272.     }  
  273.   
  274.     private static int computeInitialSampleSize(BitmapFactory.Options options,  
  275.             int minSideLength, int maxNumOfPixels) {  
  276.         double w = options.outWidth;  
  277.         double h = options.outHeight;  
  278.   
  279.         int lowerBound = (maxNumOfPixels == UNCONSTRAINED) ? 1 :  
  280.                 (int) Math.ceil(Math.sqrt(w * h / maxNumOfPixels));  
  281.         int upperBound = (minSideLength == UNCONSTRAINED) ? 128 :  
  282.                 (int) Math.min(Math.floor(w / minSideLength),  
  283.                 Math.floor(h / minSideLength));  
  284.   
  285.         if (upperBound < lowerBound) {  
  286.             // return the larger one when there is no overlapping zone.  
  287.             return lowerBound;  
  288.         }  
  289.   
  290.         if ((maxNumOfPixels == UNCONSTRAINED) &&  
  291.                 (minSideLength == UNCONSTRAINED)) {  
  292.             return 1;  
  293.         } else if (minSideLength == UNCONSTRAINED) {  
  294.             return lowerBound;  
  295.         } else {  
  296.             return upperBound;  
  297.         }  
  298.     }  
  299.   
  300.     /** 
  301.      * Make a bitmap from a given Uri, minimal side length, and maximum number of pixels. 
  302.      * The image data will be read from specified pfd if it's not null, otherwise 
  303.      * a new input stream will be created using specified ContentResolver. 
  304.      * 
  305.      * Clients are allowed to pass their own BitmapFactory.Options used for bitmap decoding. A 
  306.      * new BitmapFactory.Options will be created if options is null. 
  307.      */  
  308.     private static Bitmap makeBitmap(int minSideLength, int maxNumOfPixels,  
  309.             Uri uri, ContentResolver cr, ParcelFileDescriptor pfd,  
  310.             BitmapFactory.Options options) {  
  311.         Bitmap b = null;  
  312.         try {  
  313.             if (pfd == null) pfd = makeInputStream(uri, cr);  
  314.             if (pfd == nullreturn null;  
  315.             if (options == null) options = new BitmapFactory.Options();  
  316.   
  317.             FileDescriptor fd = pfd.getFileDescriptor();  
  318.             options.inSampleSize = 1;  
  319.             options.inJustDecodeBounds = true;  
  320.             BitmapFactory.decodeFileDescriptor(fd, null, options);  
  321.             if (options.mCancel || options.outWidth == -1  
  322.                     || options.outHeight == -1) {  
  323.                 return null;  
  324.             }  
  325.             options.inSampleSize = computeSampleSize(  
  326.                     options, minSideLength, maxNumOfPixels);  
  327.             options.inJustDecodeBounds = false;  
  328.   
  329.             options.inDither = false;  
  330.             options.inPreferredConfig = Bitmap.Config.ARGB_8888;  
  331.             b = BitmapFactory.decodeFileDescriptor(fd, null, options);  
  332.         } catch (OutOfMemoryError ex) {  
  333.             Log.e(TAG, "Got oom exception ", ex);  
  334.             return null;  
  335.         } finally {  
  336.             closeSilently(pfd);  
  337.         }  
  338.         return b;  
  339.     }  
  340.   
  341.     private static void closeSilently(ParcelFileDescriptor c) {  
  342.       if (c == nullreturn;  
  343.       try {  
  344.           c.close();  
  345.       } catch (Throwable t) {  
  346.           // do nothing  
  347.       }  
  348.     }  
  349.   
  350.     private static ParcelFileDescriptor makeInputStream(  
  351.             Uri uri, ContentResolver cr) {  
  352.         try {  
  353.             return cr.openFileDescriptor(uri, "r");  
  354.         } catch (IOException ex) {  
  355.             return null;  
  356.         }  
  357.     }  
  358.   
  359.     /** 
  360.      * Transform source Bitmap to targeted width and height. 
  361.      */  
  362.     private static Bitmap transform(Matrix scaler,  
  363.             Bitmap source,  
  364.             int targetWidth,  
  365.             int targetHeight,  
  366.             int options) {  
  367.         boolean scaleUp = (options & OPTIONS_SCALE_UP) != 0;  
  368.         boolean recycle = (options & OPTIONS_RECYCLE_INPUT) != 0;  
  369.   
  370.         int deltaX = source.getWidth() - targetWidth;  
  371.         int deltaY = source.getHeight() - targetHeight;  
  372.         if (!scaleUp && (deltaX < 0 || deltaY < 0)) {  
  373.             /* 
  374.             * In this case the bitmap is smaller, at least in one dimension, 
  375.             * than the target.  Transform it by placing as much of the image 
  376.             * as possible into the target and leaving the top/bottom or 
  377.             * left/right (or both) black. 
  378.             */  
  379.             Bitmap b2 = Bitmap.createBitmap(targetWidth, targetHeight,  
  380.             Bitmap.Config.ARGB_8888);  
  381.             Canvas c = new Canvas(b2);  
  382.   
  383.             int deltaXHalf = Math.max(0, deltaX / 2);  
  384.             int deltaYHalf = Math.max(0, deltaY / 2);  
  385.             Rect src = new Rect(  
  386.             deltaXHalf,  
  387.             deltaYHalf,  
  388.             deltaXHalf + Math.min(targetWidth, source.getWidth()),  
  389.             deltaYHalf + Math.min(targetHeight, source.getHeight()));  
  390.             int dstX = (targetWidth  - src.width())  / 2;  
  391.             int dstY = (targetHeight - src.height()) / 2;  
  392.             Rect dst = new Rect(  
  393.                     dstX,  
  394.                     dstY,  
  395.                     targetWidth - dstX,  
  396.                     targetHeight - dstY);  
  397.             c.drawBitmap(source, src, dst, null);  
  398.             if (recycle) {  
  399.                 source.recycle();  
  400.             }  
  401.             c.setBitmap(null);  
  402.             return b2;  
  403.         }  
  404.         float bitmapWidthF = source.getWidth();  
  405.         float bitmapHeightF = source.getHeight();  
  406.   
  407.         float bitmapAspect = bitmapWidthF / bitmapHeightF;  
  408.         float viewAspect   = (float) targetWidth / targetHeight;  
  409.   
  410.         if (bitmapAspect > viewAspect) {  
  411.             float scale = targetHeight / bitmapHeightF;  
  412.             if (scale < .9F || scale > 1F) {  
  413.                 scaler.setScale(scale, scale);  
  414.             } else {  
  415.                 scaler = null;  
  416.             }  
  417.         } else {  
  418.             float scale = targetWidth / bitmapWidthF;  
  419.             if (scale < .9F || scale > 1F) {  
  420.                 scaler.setScale(scale, scale);  
  421.             } else {  
  422.                 scaler = null;  
  423.             }  
  424.         }  
  425.   
  426.         Bitmap b1;  
  427.         if (scaler != null) {  
  428.             // this is used for minithumb and crop, so we want to filter here.  
  429.             b1 = Bitmap.createBitmap(source, 00,  
  430.             source.getWidth(), source.getHeight(), scaler, true);  
  431.         } else {  
  432.             b1 = source;  
  433.         }  
  434.   
  435.         if (recycle && b1 != source) {  
  436.             source.recycle();  
  437.         }  
  438.   
  439.         int dx1 = Math.max(0, b1.getWidth() - targetWidth);  
  440.         int dy1 = Math.max(0, b1.getHeight() - targetHeight);  
  441.   
  442.         Bitmap b2 = Bitmap.createBitmap(  
  443.                 b1,  
  444.                 dx1 / 2,  
  445.                 dy1 / 2,  
  446.                 targetWidth,  
  447.                 targetHeight);  
  448.   
  449.         if (b2 != b1) {  
  450.             if (recycle || b1 != source) {  
  451.                 b1.recycle();  
  452.             }  
  453.         }  
  454.   
  455.         return b2;  
  456.     }  
  457.   
  458.     /** 
  459.      * SizedThumbnailBitmap contains the bitmap, which is downsampled either from 
  460.      * the thumbnail in exif or the full image. 
  461.      * mThumbnailData, mThumbnailWidth and mThumbnailHeight are set together only if mThumbnail 
  462.      * is not null. 
  463.      * 
  464.      * The width/height of the sized bitmap may be different from mThumbnailWidth/mThumbnailHeight. 
  465.      */  
  466.     private static class SizedThumbnailBitmap {  
  467.         public byte[] mThumbnailData;  
  468.         public Bitmap mBitmap;  
  469.         public int mThumbnailWidth;  
  470.         public int mThumbnailHeight;  
  471.     }  
  472.   
  473.     /** 
  474.      * Creates a bitmap by either downsampling from the thumbnail in EXIF or the full image. 
  475.      * The functions returns a SizedThumbnailBitmap, 
  476.      * which contains a downsampled bitmap and the thumbnail data in EXIF if exists. 
  477.      */  
  478.     private static void createThumbnailFromEXIF(String filePath, int targetSize,  
  479.             int maxPixels, SizedThumbnailBitmap sizedThumbBitmap) {  
  480.         if (filePath == nullreturn;  
  481.   
  482.         ExifInterface exif = null;  
  483.         byte [] thumbData = null;  
  484.         try {  
  485.             exif = new ExifInterface(filePath);  
  486.             thumbData = exif.getThumbnail();  
  487.         } catch (IOException ex) {  
  488.             Log.w(TAG, ex);  
  489.         }  
  490.   
  491.         BitmapFactory.Options fullOptions = new BitmapFactory.Options();  
  492.         BitmapFactory.Options exifOptions = new BitmapFactory.Options();  
  493.         int exifThumbWidth = 0;  
  494.         int fullThumbWidth = 0;  
  495.   
  496.         // Compute exifThumbWidth.  
  497.         if (thumbData != null) {  
  498.             exifOptions.inJustDecodeBounds = true;  
  499.             BitmapFactory.decodeByteArray(thumbData, 0, thumbData.length, exifOptions);  
  500.             exifOptions.inSampleSize = computeSampleSize(exifOptions, targetSize, maxPixels);  
  501.             exifThumbWidth = exifOptions.outWidth / exifOptions.inSampleSize;  
  502.         }  
  503.   
  504.         // Compute fullThumbWidth.  
  505.         fullOptions.inJustDecodeBounds = true;  
  506.         BitmapFactory.decodeFile(filePath, fullOptions);  
  507.         fullOptions.inSampleSize = computeSampleSize(fullOptions, targetSize, maxPixels);  
  508.         fullThumbWidth = fullOptions.outWidth / fullOptions.inSampleSize;  
  509.   
  510.         // Choose the larger thumbnail as the returning sizedThumbBitmap.  
  511.         if (thumbData != null && exifThumbWidth >= fullThumbWidth) {  
  512.             int width = exifOptions.outWidth;  
  513.             int height = exifOptions.outHeight;  
  514.             exifOptions.inJustDecodeBounds = false;  
  515.             sizedThumbBitmap.mBitmap = BitmapFactory.decodeByteArray(thumbData, 0,  
  516.                     thumbData.length, exifOptions);  
  517.             if (sizedThumbBitmap.mBitmap != null) {  
  518.                 sizedThumbBitmap.mThumbnailData = thumbData;  
  519.                 sizedThumbBitmap.mThumbnailWidth = width;  
  520.                 sizedThumbBitmap.mThumbnailHeight = height;  
  521.             }  
  522.         } else {  
  523.             fullOptions.inJustDecodeBounds = false;  
  524.             sizedThumbBitmap.mBitmap = BitmapFactory.decodeFile(filePath, fullOptions);  
  525.         }  
  526.     }  
  527. }  

====================================================================================

  作者:欧阳鹏  欢迎转载,与人分享是进步的源泉!

  转载请保留原文地址:http://blog.csdn.net/ouyang_peng

===================================================================================

你可能感兴趣的:(Android)