在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. <?xmlversion="1.0"encoding="utf-8"?>
  2. <LinearLayoutxmlns: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. packagecom.linc.ResolvePicture;
  2. importjava.io.File;
  3. importjava.io.FileNotFoundException;
  4. importjava.io.FileOutputStream;
  5. importjava.io.IOException;
  6. importandroid.app.Activity;
  7. importandroid.graphics.Bitmap;
  8. importandroid.graphics.BitmapFactory;
  9. importandroid.graphics.Matrix;
  10. importandroid.graphics.drawable.BitmapDrawable;
  11. importandroid.graphics.drawable.Drawable;
  12. importandroid.media.ThumbnailUtils;
  13. importandroid.os.Bundle;
  14. importandroid.util.Log;
  15. importandroid.widget.ImageView;
  16. importandroid.widget.TextView;
  17. publicclassResolvePictureextendsActivity{
  18. privatestaticStringtag="ResolvePicture";
  19. DrawablebmImg;
  20. ImageViewimView;
  21. ImageViewimView2;
  22. TextViewtext;
  23. StringtheTime;
  24. longstart,stop;
  25. /**Calledwhentheactivityisfirstcreated.*/
  26. @Override
  27. publicvoidonCreate(BundlesavedInstanceState){
  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. Bitmapbitmap=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. StringtheTime=String.format("\n1iterative:(%dmsec)",
  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("\n2iterative:(%dmsec)",
  46. stop-start);
  47. text.setText(theTime);
  48. }
  49. //使用Bitmap加Matrix来缩放
  50. publicstaticDrawableresizeImage(Bitmapbitmap,intw,inth)
  51. {
  52. BitmapBitmapOrg=bitmap;
  53. intwidth=BitmapOrg.getWidth();
  54. intheight=BitmapOrg.getHeight();
  55. intnewWidth=w;
  56. intnewHeight=h;
  57. floatscaleWidth=((float)newWidth)/width;
  58. floatscaleHeight=((float)newHeight)/height;
  59. Matrixmatrix=newMatrix();
  60. matrix.postScale(scaleWidth,scaleHeight);
  61. //ifyouwanttorotatetheBitmap
  62. //matrix.postRotate(45);
  63. BitmapresizedBitmap=Bitmap.createBitmap(BitmapOrg,0,0,width,
  64. height,matrix,true);
  65. returnnewBitmapDrawable(resizedBitmap);
  66. }
  67. //使用BitmapFactory.Options的inSampleSize参数来缩放
  68. publicstaticDrawableresizeImage2(Stringpath,
  69. intwidth,intheight)
  70. {
  71. BitmapFactory.Optionsoptions=newBitmapFactory.Options();
  72. options.inJustDecodeBounds=true;//不加载bitmap到内存中
  73. BitmapFactory.decodeFile(path,options);
  74. intoutWidth=options.outWidth;
  75. intoutHeight=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. intsampleSize=(outWidth/width+outHeight/height)/2;
  82. Log.d(tag,"sampleSize="+sampleSize);
  83. options.inSampleSize=sampleSize;
  84. }
  85. options.inJustDecodeBounds=false;
  86. returnnewBitmapDrawable(BitmapFactory.decodeFile(path,options));
  87. }
  88. //图片保存
  89. privatevoidsaveThePicture(Bitmapbitmap)
  90. {
  91. Filefile=newFile("/sdcard/2.jpeg");
  92. try
  93. {
  94. FileOutputStreamfos=newFileOutputStream(file);
  95. if(bitmap.compress(Bitmap.CompressFormat.JPEG,100,fos))
  96. {
  97. fos.flush();
  98. fos.close();
  99. }
  100. }
  101. catch(FileNotFoundExceptione1)
  102. {
  103. e1.printStackTrace();
  104. }
  105. catch(IOExceptione2)
  106. {
  107. e2.printStackTrace();
  108. }
  109. }
  110. }

ThumbnailUtils源码:
[java] view plain copy
  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. packageandroid.media;
  17. importandroid.content.ContentResolver;
  18. importandroid.content.ContentUris;
  19. importandroid.content.ContentValues;
  20. importandroid.database.Cursor;
  21. importandroid.graphics.Bitmap;
  22. importandroid.graphics.BitmapFactory;
  23. importandroid.graphics.Canvas;
  24. importandroid.graphics.Matrix;
  25. importandroid.graphics.Rect;
  26. importandroid.media.MediaMetadataRetriever;
  27. importandroid.media.MediaFile.MediaFileType;
  28. importandroid.net.Uri;
  29. importandroid.os.ParcelFileDescriptor;
  30. importandroid.provider.BaseColumns;
  31. importandroid.provider.MediaStore.Images;
  32. importandroid.provider.MediaStore.Images.Thumbnails;
  33. importandroid.util.Log;
  34. importjava.io.FileInputStream;
  35. importjava.io.FileDescriptor;
  36. importjava.io.IOException;
  37. importjava.io.OutputStream;
  38. /**
  39. *Thumbnailgenerationroutinesformediaprovider.
  40. */
  41. publicclassThumbnailUtils{
  42. privatestaticfinalStringTAG="ThumbnailUtils";
  43. /*Maximumpixelssizeforcreatedbitmap.*/
  44. privatestaticfinalintMAX_NUM_PIXELS_THUMBNAIL=512*384;
  45. privatestaticfinalintMAX_NUM_PIXELS_MICRO_THUMBNAIL=128*128;
  46. privatestaticfinalintUNCONSTRAINED=-1;
  47. /*Optionsusedinternally.*/
  48. privatestaticfinalintOPTIONS_NONE=0x0;
  49. privatestaticfinalintOPTIONS_SCALE_UP=0x1;
  50. /**
  51. *Constantusedtoindicateweshouldrecycletheinputin
  52. *{@link#extractThumbnail(Bitmap,int,int,int)}unlesstheoutputistheinput.
  53. */
  54. publicstaticfinalintOPTIONS_RECYCLE_INPUT=0x2;
  55. /**
  56. *Constantusedtoindicatethedimensionofminithumbnail.
  57. *@hideOnlyusedbymediaframeworkandmediaproviderinternally.
  58. */
  59. publicstaticfinalintTARGET_SIZE_MINI_THUMBNAIL=320;
  60. /**
  61. *Constantusedtoindicatethedimensionofmicrothumbnail.
  62. *@hideOnlyusedbymediaframeworkandmediaproviderinternally.
  63. */
  64. publicstaticfinalintTARGET_SIZE_MICRO_THUMBNAIL=96;
  65. /**
  66. *ThismethodfirstexaminesifthethumbnailembeddedinEXIFisbiggerthanourtarget
  67. *size.Ifnot,thenit'llcreateathumbnailfromoriginalimage.Duetoefficiency
  68. *consideration,wewanttoletMediaThumbRequestavoidcallingthismethodtwicefor
  69. *bothkinds,soitonlyrequestsforMICRO_KINDandsetsaveImagetotrue.
  70. *
  71. *Thismethodalwaysreturnsa"squarethumbnail"forMICRO_KINDthumbnail.
  72. *
  73. *@paramfilePaththepathofimagefile
  74. *@paramkindcouldbeMINI_KINDorMICRO_KIND
  75. *@returnBitmap
  76. *
  77. *@hideThismethodisonlyusedbymediaframeworkandmediaproviderinternally.
  78. */
  79. publicstaticBitmapcreateImageThumbnail(StringfilePath,intkind){
  80. booleanwantMini=(kind==Images.Thumbnails.MINI_KIND);
  81. inttargetSize=wantMini
  82. ?TARGET_SIZE_MINI_THUMBNAIL
  83. :TARGET_SIZE_MICRO_THUMBNAIL;
  84. intmaxPixels=wantMini
  85. ?MAX_NUM_PIXELS_THUMBNAIL
  86. :MAX_NUM_PIXELS_MICRO_THUMBNAIL;
  87. SizedThumbnailBitmapsizedThumbnailBitmap=newSizedThumbnailBitmap();
  88. Bitmapbitmap=null;
  89. MediaFileTypefileType=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. FileDescriptorfd=newFileInputStream(filePath).getFD();
  97. BitmapFactory.Optionsoptions=newBitmapFactory.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. returnnull;
  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(IOExceptionex){
  112. Log.e(TAG,"",ex);
  113. }
  114. }
  115. if(kind==Images.Thumbnails.MICRO_KIND){
  116. //nowwemakeita"squarethumbnail"forMICRO_KINDthumbnail
  117. bitmap=extractThumbnail(bitmap,
  118. TARGET_SIZE_MICRO_THUMBNAIL,
  119. TARGET_SIZE_MICRO_THUMBNAIL,OPTIONS_RECYCLE_INPUT);
  120. }
  121. returnbitmap;
  122. }
  123. /**
  124. *Createavideothumbnailforavideo.Mayreturnnullifthevideois
  125. *corruptortheformatisnotsupported.
  126. *
  127. *@paramfilePaththepathofvideofile
  128. *@paramkindcouldbeMINI_KINDorMICRO_KIND
  129. */
  130. publicstaticBitmapcreateVideoThumbnail(StringfilePath,intkind){
  131. Bitmapbitmap=null;
  132. MediaMetadataRetrieverretriever=newMediaMetadataRetriever();
  133. try{
  134. retriever.setMode(MediaMetadataRetriever.MODE_CAPTURE_FRAME_ONLY);
  135. retriever.setDataSource(filePath);
  136. bitmap=retriever.captureFrame();
  137. }catch(IllegalArgumentExceptionex){
  138. //Assumethisisacorruptvideofile
  139. }catch(RuntimeExceptionex){
  140. //Assumethisisacorruptvideofile.
  141. }finally{
  142. try{
  143. retriever.release();
  144. }catch(RuntimeExceptionex){
  145. //Ignorefailureswhilecleaningup.
  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. returnbitmap;
  155. }
  156. /**
  157. *Createsacenteredbitmapofthedesiredsize.
  158. *
  159. *@paramsourceoriginalbitmapsource
  160. *@paramwidthtargetedwidth
  161. *@paramheighttargetedheight
  162. */
  163. publicstaticBitmapextractThumbnail(
  164. Bitmapsource,intwidth,intheight){
  165. returnextractThumbnail(source,width,height,OPTIONS_NONE);
  166. }
  167. /**
  168. *Createsacenteredbitmapofthedesiredsize.
  169. *
  170. *@paramsourceoriginalbitmapsource
  171. *@paramwidthtargetedwidth
  172. *@paramheighttargetedheight
  173. *@paramoptionsoptionsusedduringthumbnailextraction
  174. */
  175. publicstaticBitmapextractThumbnail(
  176. Bitmapsource,intwidth,intheight,intoptions){
  177. if(source==null){
  178. returnnull;
  179. }
  180. floatscale;
  181. if(source.getWidth()<source.getHeight()){
  182. scale=width/(float)source.getWidth();
  183. }else{
  184. scale=height/(float)source.getHeight();
  185. }
  186. Matrixmatrix=newMatrix();
  187. matrix.setScale(scale,scale);
  188. Bitmapthumbnail=transform(matrix,source,width,height,
  189. OPTIONS_SCALE_UP|options);
  190. returnthumbnail;
  191. }
  192. /*
  193. *ComputethesamplesizeasafunctionofminSideLength
  194. *andmaxNumOfPixels.
  195. *minSideLengthisusedtospecifythatminimalwidthorheightofa
  196. *bitmap.
  197. *maxNumOfPixelsisusedtospecifythemaximalsizeinpixelsthatis
  198. *tolerableintermsofmemoryusage.
  199. *
  200. *Thefunctionreturnsasamplesizebasedontheconstraints.
  201. *BothsizeandminSideLengthcanbepassedinasIImage.UNCONSTRAINED,
  202. *whichindicatesnocareofthecorrespondingconstraint.
  203. *Thefunctionsprefersreturningasamplesizethat
  204. *generatesasmallerbitmap,unlessminSideLength=IImage.UNCONSTRAINED.
  205. *
  206. *Also,thefunctionroundsupthesamplesizetoapowerof2ormultiple
  207. *of8becauseBitmapFactoryonlyhonorssamplesizethisway.
  208. *Forexample,BitmapFactorydownsamplesanimageby2eventhoughthe
  209. *requestis3.SoweroundupthesamplesizetoavoidOOM.
  210. */
  211. privatestaticintcomputeSampleSize(BitmapFactory.Optionsoptions,
  212. intminSideLength,intmaxNumOfPixels){
  213. intinitialSize=computeInitialSampleSize(options,minSideLength,
  214. maxNumOfPixels);
  215. introundedSize;
  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. returnroundedSize;
  225. }
  226. privatestaticintcomputeInitialSampleSize(BitmapFactory.Optionsoptions,
  227. intminSideLength,intmaxNumOfPixels){
  228. doublew=options.outWidth;
  229. doubleh=options.outHeight;
  230. intlowerBound=(maxNumOfPixels==UNCONSTRAINED)?1:
  231. (int)Math.ceil(Math.sqrt(w*h/maxNumOfPixels));
  232. intupperBound=(minSideLength==UNCONSTRAINED)?128:
  233. (int)Math.min(Math.floor(w/minSideLength),
  234. Math.floor(h/minSideLength));
  235. if(upperBound<lowerBound){
  236. //returnthelargeronewhenthereisnooverlappingzone.
  237. returnlowerBound;
  238. }
  239. if((maxNumOfPixels==UNCONSTRAINED)&&
  240. (minSideLength==UNCONSTRAINED)){
  241. return1;
  242. }elseif(minSideLength==UNCONSTRAINED){
  243. returnlowerBound;
  244. }else{
  245. returnupperBound;
  246. }
  247. }
  248. /**
  249. *MakeabitmapfromagivenUri,minimalsidelength,andmaximumnumberofpixels.
  250. *Theimagedatawillbereadfromspecifiedpfdifit'snotnull,otherwise
  251. *anewinputstreamwillbecreatedusingspecifiedContentResolver.
  252. *
  253. *ClientsareallowedtopasstheirownBitmapFactory.Optionsusedforbitmapdecoding.A
  254. *newBitmapFactory.Optionswillbecreatedifoptionsisnull.
  255. */
  256. privatestaticBitmapmakeBitmap(intminSideLength,intmaxNumOfPixels,
  257. Uriuri,ContentResolvercr,ParcelFileDescriptorpfd,
  258. BitmapFactory.Optionsoptions){
  259. Bitmapb=null;
  260. try{
  261. if(pfd==null)pfd=makeInputStream(uri,cr);
  262. if(pfd==null)returnnull;
  263. if(options==null)options=newBitmapFactory.Options();
  264. FileDescriptorfd=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. returnnull;
  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(OutOfMemoryErrorex){
  279. Log.e(TAG,"Gotoomexception",ex);
  280. returnnull;
  281. }finally{
  282. closeSilently(pfd);
  283. }
  284. returnb;
  285. }
  286. privatestaticvoidcloseSilently(ParcelFileDescriptorc){
  287. if(c==null)return;
  288. try{
  289. c.close();
  290. }catch(Throwablet){
  291. //donothing
  292. }
  293. }
  294. privatestaticParcelFileDescriptormakeInputStream(
  295. Uriuri,ContentResolvercr){
  296. try{
  297. returncr.openFileDescriptor(uri,"r");
  298. }catch(IOExceptionex){
  299. returnnull;
  300. }
  301. }
  302. /**
  303. *TransformsourceBitmaptotargetedwidthandheight.
  304. */
  305. privatestaticBitmaptransform(Matrixscaler,
  306. Bitmapsource,
  307. inttargetWidth,
  308. inttargetHeight,
  309. intoptions){
  310. booleanscaleUp=(options&OPTIONS_SCALE_UP)!=0;
  311. booleanrecycle=(options&OPTIONS_RECYCLE_INPUT)!=0;
  312. intdeltaX=source.getWidth()-targetWidth;
  313. intdeltaY=source.getHeight()-targetHeight;
  314. if(!scaleUp&&(deltaX<0||deltaY<0)){
  315. /*
  316. *Inthiscasethebitmapissmaller,atleastinonedimension,
  317. *thanthetarget.Transformitbyplacingasmuchoftheimage
  318. *aspossibleintothetargetandleavingthetop/bottomor
  319. *left/right(orboth)black.
  320. */
  321. Bitmapb2=Bitmap.createBitmap(targetWidth,targetHeight,
  322. Bitmap.Config.ARGB_8888);
  323. Canvasc=newCanvas(b2);
  324. intdeltaXHalf=Math.max(0,deltaX/2);
  325. intdeltaYHalf=Math.max(0,deltaY/2);
  326. Rectsrc=newRect(
  327. deltaXHalf,
  328. deltaYHalf,
  329. deltaXHalf+Math.min(targetWidth,source.getWidth()),
  330. deltaYHalf+Math.min(targetHeight,source.getHeight()));
  331. intdstX=(targetWidth-src.width())/2;
  332. intdstY=(targetHeight-src.height())/2;
  333. Rectdst=newRect(
  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. returnb2;
  343. }
  344. floatbitmapWidthF=source.getWidth();
  345. floatbitmapHeightF=source.getHeight();
  346. floatbitmapAspect=bitmapWidthF/bitmapHeightF;
  347. floatviewAspect=(float)targetWidth/targetHeight;
  348. if(bitmapAspect>viewAspect){
  349. floatscale=targetHeight/bitmapHeightF;
  350. if(scale<.9F||scale>1F){
  351. scaler.setScale(scale,scale);
  352. }else{
  353. scaler=null;
  354. }
  355. }else{
  356. floatscale=targetWidth/bitmapWidthF;
  357. if(scale<.9F||scale>1F){
  358. scaler.setScale(scale,scale);
  359. }else{
  360. scaler=null;
  361. }
  362. }
  363. Bitmapb1;
  364. if(scaler!=null){
  365. //thisisusedforminithumbandcrop,sowewanttofilterhere.
  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. intdx1=Math.max(0,b1.getWidth()-targetWidth);
  375. intdy1=Math.max(0,b1.getHeight()-targetHeight);
  376. Bitmapb2=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. returnb2;
  388. }
  389. /**
  390. *SizedThumbnailBitmapcontainsthebitmap,whichisdownsampledeitherfrom
  391. *thethumbnailinexiforthefullimage.
  392. *mThumbnailData,mThumbnailWidthandmThumbnailHeightaresettogetheronlyifmThumbnail
  393. *isnotnull.
  394. *
  395. *Thewidth/heightofthesizedbitmapmaybedifferentfrommThumbnailWidth/mThumbnailHeight.
  396. */
  397. privatestaticclassSizedThumbnailBitmap{
  398. publicbyte[]mThumbnailData;
  399. publicBitmapmBitmap;
  400. publicintmThumbnailWidth;
  401. publicintmThumbnailHeight;
  402. }
  403. /**
  404. *CreatesabitmapbyeitherdownsamplingfromthethumbnailinEXIForthefullimage.
  405. *ThefunctionsreturnsaSizedThumbnailBitmap,
  406. *whichcontainsadownsampledbitmapandthethumbnaildatainEXIFifexists.
  407. */
  408. privatestaticvoidcreateThumbnailFromEXIF(StringfilePath,inttargetSize,
  409. intmaxPixels,SizedThumbnailBitmapsizedThumbBitmap){
  410. if(filePath==null)return;
  411. ExifInterfaceexif=null;
  412. byte[]thumbData=null;
  413. try{
  414. exif=newExifInterface(filePath);
  415. if(exif!=null){
  416. thumbData=exif.getThumbnail();
  417. }
  418. }catch(IOExceptionex){
  419. Log.w(TAG,ex);
  420. }
  421. BitmapFactory.OptionsfullOptions=newBitmapFactory.Options();
  422. BitmapFactory.OptionsexifOptions=newBitmapFactory.Options();
  423. intexifThumbWidth=0;
  424. intfullThumbWidth=0;
  425. //ComputeexifThumbWidth.
  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. //ComputefullThumbWidth.
  433. fullOptions.inJustDecodeBounds=true;
  434. BitmapFactory.decodeFile(filePath,fullOptions);
  435. fullOptions.inSampleSize=computeSampleSize(fullOptions,targetSize,maxPixels);
  436. fullThumbWidth=fullOptions.outWidth/fullOptions.inSampleSize;
  437. //ChoosethelargerthumbnailasthereturningsizedThumbBitmap.
  438. if(thumbData!=null&&exifThumbWidth>=fullThumbWidth){
  439. intwidth=exifOptions.outWidth;
  440. intheight=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. }

更多相关文章

  1. Android中快速为Recyclerview添加头部
  2. Android(安卓)图片加载笔记
  3. mysql错误:Access denied for user 'root'@'172.19.100.123' to d
  4. Android事件总线框架设计:EventBus3.0源码详解与架构分析(中)
  5. android 判断手机是否是国内的手机的方法
  6. Android(安卓)ViewPager切换的N种动画
  7. Android(安卓)touch事件的派发流程
  8. android kotlin 学习笔记基础篇(一)
  9. 下载最新android adt的方法

随机推荐

  1. http协议请求方法都有哪些?网络安全学习提
  2. 【第554期】Webpack 一探究竟
  3. Android(安卓)设置dialog背景全透明无边
  4. 单页应用 & 多页应用的区别
  5. F5 同 Ctrl+F5 的区别你可了解
  6. 【同说】小天童鞋:“不断学习,不断成长”
  7. 熔断器 Hystrix 源码解析 —— 命令执行(
  8. 关于前端学习路线的一些建议(含面试自测题
  9. 关于 Babel 你必须知道的基础知识
  10. 继 GitHub 后微软又收购了 npm