频道栏目
首页 > 资讯 > Android > 正文

Android--生成缩略图------方法总结

16-05-12        来源:[db:作者]  
收藏   我要投稿
在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 plaincopy
 
  1.  
  2. android:layout_width="fill_parent"
  3. android:layout_height="fill_parent"
  4. >
  5.  
  6. <>
  7. android:id="@+id/imageShow"
  8. android:layout_width="wrap_content"
  9. android:layout_height="wrap_content"
  10. />
  11. <>
  12. android:id="@+id/image2"
  13. android:layout_width="wrap_content"
  14. android:layout_height="wrap_content"
  15. />
  16. <>
  17. android:id="@+id/text"
  18. android:layout_width="fill_parent"
  19. android:layout_height="wrap_content"
  20. android:text="@string/hello"
  21. />

  22. [java]view plaincopy
     
    1. packagecom.linc.ResolvePicture;
    2.  
    3. importjava.io.File;
    4. importjava.io.FileNotFoundException;
    5. importjava.io.FileOutputStream;
    6. importjava.io.IOException;
    7.  
    8. importandroid.app.Activity;
    9. importandroid.graphics.Bitmap;
    10. importandroid.graphics.BitmapFactory;
    11. importandroid.graphics.Matrix;
    12. importandroid.graphics.drawable.BitmapDrawable;
    13. importandroid.graphics.drawable.Drawable;
    14. importandroid.media.ThumbnailUtils;
    15. importandroid.os.Bundle;
    16. importandroid.util.Log;
    17. importandroid.widget.ImageView;
    18. importandroid.widget.TextView;
    19.  
    20. publicclassResolvePictureextendsActivity{
    21. privatestaticStringtag="ResolvePicture";
    22. DrawablebmImg;
    23. ImageViewimView;
    24. ImageViewimView2;
    25. TextViewtext;
    26. StringtheTime;
    27. longstart,stop;
    28. /**Calledwhentheactivityisfirstcreated.*/
    29. @Override
    30. publicvoidonCreate(BundlesavedInstanceState){
    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. Bitmapbitmap=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. StringtheTime=String.format("\n1iterative:(%dmsec)",
    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("\n2iterative:(%dmsec)",
    59. stop-start);
    60.  
    61. text.setText(theTime);
    62. }
    63.  
    64. //使用Bitmap加Matrix来缩放
    65. publicstaticDrawableresizeImage(Bitmapbitmap,intw,inth)
    66. {
    67. BitmapBitmapOrg=bitmap;
    68. intwidth=BitmapOrg.getWidth();
    69. intheight=BitmapOrg.getHeight();
    70. intnewWidth=w;
    71. intnewHeight=h;
    72.  
    73. floatscaleWidth=((float)newWidth)/width;
    74. floatscaleHeight=((float)newHeight)/height;
    75.  
    76. Matrixmatrix=newMatrix();
    77. matrix.postScale(scaleWidth,scaleHeight);
    78. //ifyouwanttorotatetheBitmap
    79. //matrix.postRotate(45);
    80. BitmapresizedBitmap=Bitmap.createBitmap(BitmapOrg,0,0,width,
    81. height,matrix,true);
    82. returnnewBitmapDrawable(resizedBitmap);
    83. }
    84.  
    85. //使用BitmapFactory.Options的inSampleSize参数来缩放
    86. publicstaticDrawableresizeImage2(Stringpath,
    87. intwidth,intheight)
    88. {
    89. BitmapFactory.Optionsoptions=newBitmapFactory.Options();
    90. options.inJustDecodeBounds=true;//不加载bitmap到内存中
    91. BitmapFactory.decodeFile(path,options);
    92. intoutWidth=options.outWidth;
    93. intoutHeight=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. intsampleSize=(outWidth/width+outHeight/height)/2;
    101. Log.d(tag,"sampleSize="+sampleSize);
    102. options.inSampleSize=sampleSize;
    103. }
    104.  
    105. options.inJustDecodeBounds=false;
    106. returnnewBitmapDrawable(BitmapFactory.decodeFile(path,options));
    107. }
    108.  
    109. //图片保存
    110. privatevoidsaveThePicture(Bitmapbitmap)
    111. {
    112. Filefile=newFile("/sdcard/2.jpeg");
    113. try
    114. {
    115. FileOutputStreamfos=newFileOutputStream(file);
    116. if(bitmap.compress(Bitmap.CompressFormat.JPEG,100,fos))
    117. {
    118. fos.flush();
    119. fos.close();
    120. }
    121. }
    122. catch(FileNotFoundExceptione1)
    123. {
    124. e1.printStackTrace();
    125. }
    126. catch(IOExceptione2)
    127. {
    128. e2.printStackTrace();
    129. }
    130. }
    131. }

ThumbnailUtils源码:
[java]view plaincopy
  1. /*
  2. *Copyright(C)2009TheAndroidOpenSourceProject
  3. *
  4. *LicensedundertheApacheLicense,Version2.0(the"License");
  5. *youmaynotusethisfileexceptincompliancewiththeLicense.
  6. *YoumayobtainacopyoftheLicenseat
  7. *
  8. *http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. *Unlessrequiredbyapplicablelaworagreedtoinwriting,software
  11. *distributedundertheLicenseisdistributedonan"ASIS"BASIS,
  12. *WITHOUTWARRANTIESORCONDITIONSOFANYKIND,eitherexpressorimplied.
  13. *SeetheLicenseforthespecificlanguagegoverningpermissionsand
  14. *limitationsundertheLicense.
  15. */
  16.  
  17. packageandroid.media;
  18.  
  19. importandroid.content.ContentResolver;
  20. importandroid.content.ContentUris;
  21. importandroid.content.ContentValues;
  22. importandroid.database.Cursor;
  23. importandroid.graphics.Bitmap;
  24. importandroid.graphics.BitmapFactory;
  25. importandroid.graphics.Canvas;
  26. importandroid.graphics.Matrix;
  27. importandroid.graphics.Rect;
  28. importandroid.media.MediaMetadataRetriever;
  29. importandroid.media.MediaFile.MediaFileType;
  30. importandroid.net.Uri;
  31. importandroid.os.ParcelFileDescriptor;
  32. importandroid.provider.BaseColumns;
  33. importandroid.provider.MediaStore.Images;
  34. importandroid.provider.MediaStore.Images.Thumbnails;
  35. importandroid.util.Log;
  36.  
  37. importjava.io.FileInputStream;
  38. importjava.io.FileDescriptor;
  39. importjava.io.IOException;
  40. importjava.io.OutputStream;
  41.  
  42. /**
  43. *Thumbnailgenerationroutinesformediaprovider.
  44. */
  45.  
  46. publicclassThumbnailUtils{
  47. privatestaticfinalStringTAG="ThumbnailUtils";
  48.  
  49. /*Maximumpixelssizeforcreatedbitmap.*/
  50. privatestaticfinalintMAX_NUM_PIXELS_THUMBNAIL=512*384;
  51. privatestaticfinalintMAX_NUM_PIXELS_MICRO_THUMBNAIL=128*128;
  52. privatestaticfinalintUNCONSTRAINED=-1;
  53.  
  54. /*Optionsusedinternally.*/
  55. privatestaticfinalintOPTIONS_NONE=0x0;
  56. privatestaticfinalintOPTIONS_SCALE_UP=0x1;
  57.  
  58. /**
  59. *Constantusedtoindicateweshouldrecycletheinputin
  60. *{@link#extractThumbnail(Bitmap,int,int,int)}unlesstheoutputistheinput.
  61. */
  62. publicstaticfinalintOPTIONS_RECYCLE_INPUT=0x2;
  63.  
  64. /**
  65. *Constantusedtoindicatethedimensionofminithumbnail.
  66. *@hideOnlyusedbymediaframeworkandmediaproviderinternally.
  67. */
  68. publicstaticfinalintTARGET_SIZE_MINI_THUMBNAIL=320;
  69.  
  70. /**
  71. *Constantusedtoindicatethedimensionofmicrothumbnail.
  72. *@hideOnlyusedbymediaframeworkandmediaproviderinternally.
  73. */
  74. publicstaticfinalintTARGET_SIZE_MICRO_THUMBNAIL=96;
  75.  
  76. /**
  77. *ThismethodfirstexaminesifthethumbnailembeddedinEXIFisbiggerthanourtarget
  78. *size.Ifnot,thenit'llcreateathumbnailfromoriginalimage.Duetoefficiency
  79. *consideration,wewanttoletMediaThumbRequestavoidcallingthismethodtwicefor
  80. *bothkinds,soitonlyrequestsforMICRO_KINDandsetsaveImagetotrue.
  81. *
  82. *Thismethodalwaysreturnsa"squarethumbnail"forMICRO_KINDthumbnail.
  83. *
  84. *@paramfilePaththepathofimagefile
  85. *@paramkindcouldbeMINI_KINDorMICRO_KIND
  86. *@returnBitmap
  87. *
  88. *@hideThismethodisonlyusedbymediaframeworkandmediaproviderinternally.
  89. */
  90. publicstaticBitmapcreateImageThumbnail(StringfilePath,intkind){
  91. booleanwantMini=(kind==Images.Thumbnails.MINI_KIND);
  92. inttargetSize=wantMini
  93. ?TARGET_SIZE_MINI_THUMBNAIL
  94. :TARGET_SIZE_MICRO_THUMBNAIL;
  95. intmaxPixels=wantMini
  96. ?MAX_NUM_PIXELS_THUMBNAIL
  97. :MAX_NUM_PIXELS_MICRO_THUMBNAIL;
  98. SizedThumbnailBitmapsizedThumbnailBitmap=newSizedThumbnailBitmap();
  99. Bitmapbitmap=null;
  100. MediaFileTypefileType=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. FileDescriptorfd=newFileInputStream(filePath).getFD();
  109. BitmapFactory.Optionsoptions=newBitmapFactory.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. returnnull;
  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(IOExceptionex){
  125. Log.e(TAG,"",ex);
  126. }
  127. }
  128.  
  129. if(kind==Images.Thumbnails.MICRO_KIND){
  130. //nowwemakeita"squarethumbnail"forMICRO_KINDthumbnail
  131. bitmap=extractThumbnail(bitmap,
  132. TARGET_SIZE_MICRO_THUMBNAIL,
  133. TARGET_SIZE_MICRO_THUMBNAIL,OPTIONS_RECYCLE_INPUT);
  134. }
  135. returnbitmap;
  136. }
  137.  
  138. /**
  139. *Createavideothumbnailforavideo.Mayreturnnullifthevideois
  140. *corruptortheformatisnotsupported.
  141. *
  142. *@paramfilePaththepathofvideofile
  143. *@paramkindcouldbeMINI_KINDorMICRO_KIND
  144. */
  145. publicstaticBitmapcreateVideoThumbnail(StringfilePath,intkind){
  146. Bitmapbitmap=null;
  147. MediaMetadataRetrieverretriever=newMediaMetadataRetriever();
  148. try{
  149. retriever.setMode(MediaMetadataRetriever.MODE_CAPTURE_FRAME_ONLY);
  150. retriever.setDataSource(filePath);
  151. bitmap=retriever.captureFrame();
  152. }catch(IllegalArgumentExceptionex){
  153. //Assumethisisacorruptvideofile
  154. }catch(RuntimeExceptionex){
  155. //Assumethisisacorruptvideofile.
  156. }finally{
  157. try{
  158. retriever.release();
  159. }catch(RuntimeExceptionex){
  160. //Ignorefailureswhilecleaningup.
  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. returnbitmap;
  170. }
  171.  
  172. /**
  173. *Createsacenteredbitmapofthedesiredsize.
  174. *
  175. *@paramsourceoriginalbitmapsource
  176. *@paramwidthtargetedwidth
  177. *@paramheighttargetedheight
  178. */
  179. publicstaticBitmapextractThumbnail(
  180. Bitmapsource,intwidth,intheight){
  181. returnextractThumbnail(source,width,height,OPTIONS_NONE);
  182. }
  183.  
  184. /**
  185. *Createsacenteredbitmapofthedesiredsize.
  186. *
  187. *@paramsourceoriginalbitmapsource
  188. *@paramwidthtargetedwidth
  189. *@paramheighttargetedheight
  190. *@paramoptionsoptionsusedduringthumbnailextraction
  191. */
  192. publicstaticBitmapextractThumbnail(
  193. Bitmapsource,intwidth,intheight,intoptions){
  194. if(source==null){
  195. returnnull;
  196. }
  197.  
  198. floatscale;
  199. if(source.getWidth()<>
  200. scale=width/(float)source.getWidth();
  201. }else{
  202. scale=height/(float)source.getHeight();
  203. }
  204. Matrixmatrix=newMatrix();
  205. matrix.setScale(scale,scale);
  206. Bitmapthumbnail=transform(matrix,source,width,height,
  207. OPTIONS_SCALE_UP|options);
  208. returnthumbnail;
  209. }
  210.  
  211. /*
  212. *ComputethesamplesizeasafunctionofminSideLength
  213. *andmaxNumOfPixels.
  214. *minSideLengthisusedtospecifythatminimalwidthorheightofa
  215. *bitmap.
  216. *maxNumOfPixelsisusedtospecifythemaximalsizeinpixelsthatis
  217. *tolerableintermsofmemoryusage.
  218. *
  219. *Thefunctionreturnsasamplesizebasedontheconstraints.
  220. *BothsizeandminSideLengthcanbepassedinasIImage.UNCONSTRAINED,
  221. *whichindicatesnocareofthecorrespondingconstraint.
  222. *Thefunctionsprefersreturningasamplesizethat
  223. *generatesasmallerbitmap,unlessminSideLength=IImage.UNCONSTRAINED.
  224. *
  225. *Also,thefunctionroundsupthesamplesizetoapowerof2ormultiple
  226. *of8becauseBitmapFactoryonlyhonorssamplesizethisway.
  227. *Forexample,BitmapFactorydownsamplesanimageby2eventhoughthe
  228. *requestis3.SoweroundupthesamplesizetoavoidOOM.
  229. */
  230. privatestaticintcomputeSampleSize(BitmapFactory.Optionsoptions,
  231. intminSideLength,intmaxNumOfPixels){
  232. intinitialSize=computeInitialSampleSize(options,minSideLength,
  233. maxNumOfPixels);
  234.  
  235. introundedSize;
  236. if(initialSize<=8){
  237. roundedSize=1;
  238. while(roundedSize<>
  239. roundedSize<<=1;
  240. }
  241. }else{
  242. roundedSize=(initialSize+7)/8*8;
  243. }
  244.  
  245. returnroundedSize;
  246. }
  247.  
  248. privatestaticintcomputeInitialSampleSize(BitmapFactory.Optionsoptions,
  249. intminSideLength,intmaxNumOfPixels){
  250. doublew=options.outWidth;
  251. doubleh=options.outHeight;
  252.  
  253. intlowerBound=(maxNumOfPixels==UNCONSTRAINED)?1:
  254. (int)Math.ceil(Math.sqrt(w*h/maxNumOfPixels));
  255. intupperBound=(minSideLength==UNCONSTRAINED)?128:
  256. (int)Math.min(Math.floor(w/minSideLength),
  257. Math.floor(h/minSideLength));
  258.  
  259. if(upperBound<>
  260. //returnthelargeronewhenthereisnooverlappingzone.
  261. returnlowerBound;
  262. }
  263.  
  264. if((maxNumOfPixels==UNCONSTRAINED)&&
  265. (minSideLength==UNCONSTRAINED)){
  266. return1;
  267. }elseif(minSideLength==UNCONSTRAINED){
  268. returnlowerBound;
  269. }else{
  270. returnupperBound;
  271. }
  272. }
  273.  
  274. /**
  275. *MakeabitmapfromagivenUri,minimalsidelength,andmaximumnumberofpixels.
  276. *Theimagedatawillbereadfromspecifiedpfdifit'snotnull,otherwise
  277. *anewinputstreamwillbecreatedusingspecifiedContentResolver.
  278. *
  279. *ClientsareallowedtopasstheirownBitmapFactory.Optionsusedforbitmapdecoding.A
  280. *newBitmapFactory.Optionswillbecreatedifoptionsisnull.
  281. */
  282. privatestaticBitmapmakeBitmap(intminSideLength,intmaxNumOfPixels,
  283. Uriuri,ContentResolvercr,ParcelFileDescriptorpfd,
  284. BitmapFactory.Optionsoptions){
  285. Bitmapb=null;
  286. try{
  287. if(pfd==null)pfd=makeInputStream(uri,cr);
  288. if(pfd==null)returnnull;
  289. if(options==null)options=newBitmapFactory.Options();
  290.  
  291. FileDescriptorfd=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. returnnull;
  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(OutOfMemoryErrorex){
  307. Log.e(TAG,"Gotoomexception",ex);
  308. returnnull;
  309. }finally{
  310. closeSilently(pfd);
  311. }
  312. returnb;
  313. }
  314.  
  315. privatestaticvoidcloseSilently(ParcelFileDescriptorc){
  316. if(c==null)return;
  317. try{
  318. c.close();
  319. }catch(Throwablet){
  320. //donothing
  321. }
  322. }
  323.  
  324. privatestaticParcelFileDescriptormakeInputStream(
  325. Uriuri,ContentResolvercr){
  326. try{
  327. returncr.openFileDescriptor(uri,"r");
  328. }catch(IOExceptionex){
  329. returnnull;
  330. }
  331. }
  332.  
  333. /**
  334. *TransformsourceBitmaptotargetedwidthandheight.
  335. */
  336. privatestaticBitmaptransform(Matrixscaler,
  337. Bitmapsource,
  338. inttargetWidth,
  339. inttargetHeight,
  340. intoptions){
  341. booleanscaleUp=(options&OPTIONS_SCALE_UP)!=0;
  342. booleanrecycle=(options&OPTIONS_RECYCLE_INPUT)!=0;
  343.  
  344. intdeltaX=source.getWidth()-targetWidth;
  345. intdeltaY=source.getHeight()-targetHeight;
  346. if(!scaleUp&&(deltaX<0||deltaY<0)){
  347. /*
  348. *Inthiscasethebitmapissmaller,atleastinonedimension,
  349. *thanthetarget.Transformitbyplacingasmuchoftheimage
  350. *aspossibleintothetargetandleavingthetop/bottomor
  351. *left/right(orboth)black.
  352. */
  353. Bitmapb2=Bitmap.createBitmap(targetWidth,targetHeight,
  354. Bitmap.Config.ARGB_8888);
  355. Canvasc=newCanvas(b2);
  356.  
  357. intdeltaXHalf=Math.max(0,deltaX/2);
  358. intdeltaYHalf=Math.max(0,deltaY/2);
  359. Rectsrc=newRect(
  360. deltaXHalf,
  361. deltaYHalf,
  362. deltaXHalf+Math.min(targetWidth,source.getWidth()),
  363. deltaYHalf+Math.min(targetHeight,source.getHeight()));
  364. intdstX=(targetWidth-src.width())/2;
  365. intdstY=(targetHeight-src.height())/2;
  366. Rectdst=newRect(
  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. returnb2;
  376. }
  377. floatbitmapWidthF=source.getWidth();
  378. floatbitmapHeightF=source.getHeight();
  379.  
  380. floatbitmapAspect=bitmapWidthF/bitmapHeightF;
  381. floatviewAspect=(float)targetWidth/targetHeight;
  382.  
  383. if(bitmapAspect>viewAspect){
  384. floatscale=targetHeight/bitmapHeightF;
  385. if(scale<.9F||scale>1F){
  386. scaler.setScale(scale,scale);
  387. }else{
  388. scaler=null;
  389. }
  390. }else{
  391. floatscale=targetWidth/bitmapWidthF;
  392. if(scale<.9F||scale>1F){
  393. scaler.setScale(scale,scale);
  394. }else{
  395. scaler=null;
  396. }
  397. }
  398.  
  399. Bitmapb1;
  400. if(scaler!=null){
  401. //thisisusedforminithumbandcrop,sowewanttofilterhere.
  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. intdx1=Math.max(0,b1.getWidth()-targetWidth);
  413. intdy1=Math.max(0,b1.getHeight()-targetHeight);
  414.  
  415. Bitmapb2=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. returnb2;
  429. }
  430.  
  431. /**
  432. *SizedThumbnailBitmapcontainsthebitmap,whichisdownsampledeitherfrom
  433. *thethumbnailinexiforthefullimage.
  434. *mThumbnailData,mThumbnailWidthandmThumbnailHeightaresettogetheronlyifmThumbnail
  435. *isnotnull.
  436. *
  437. *Thewidth/heightofthesizedbitmapmaybedifferentfrommThumbnailWidth/mThumbnailHeight.
  438. */
  439. privatestaticclassSizedThumbnailBitmap{
  440. publicbyte[]mThumbnailData;
  441. publicBitmapmBitmap;
  442. publicintmThumbnailWidth;
  443. publicintmThumbnailHeight;
  444. }
  445.  
  446. /**
  447. *CreatesabitmapbyeitherdownsamplingfromthethumbnailinEXIForthefullimage.
  448. *ThefunctionsreturnsaSizedThumbnailBitmap,
  449. *whichcontainsadownsampledbitmapandthethumbnaildatainEXIFifexists.
  450. */
  451. privatestaticvoidcreateThumbnailFromEXIF(StringfilePath,inttargetSize,
  452. intmaxPixels,SizedThumbnailBitmapsizedThumbBitmap){
  453. if(filePath==null)return;
  454.  
  455. ExifInterfaceexif=null;
  456. byte[]thumbData=null;
  457. try{
  458. exif=newExifInterface(filePath);
  459. if(exif!=null){
  460. thumbData=exif.getThumbnail();
  461. }
  462. }catch(IOExceptionex){
  463. Log.w(TAG,ex);
  464. }
  465.  
  466. BitmapFactory.OptionsfullOptions=newBitmapFactory.Options();
  467. BitmapFactory.OptionsexifOptions=newBitmapFactory.Options();
  468. intexifThumbWidth=0;
  469. intfullThumbWidth=0;
  470.  
  471. //ComputeexifThumbWidth.
  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. //ComputefullThumbWidth.
  480. fullOptions.inJustDecodeBounds=true;
  481. BitmapFactory.decodeFile(filePath,fullOptions);
  482. fullOptions.inSampleSize=computeSampleSize(fullOptions,targetSize,maxPixels);
  483. fullThumbWidth=fullOptions.outWidth/fullOptions.inSampleSize;
  484.  
  485. //ChoosethelargerthumbnailasthereturningsizedThumbBitmap.
  486. if(thumbData!=null&&exifThumbWidth>=fullThumbWidth){
  487. intwidth=exifOptions.outWidth;
  488. intheight=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. }
相关TAG标签
上一篇:程序员必备的那些Chrome插件
下一篇:express 4.x.x 官方文档翻译
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站