Android Bitmap 全面解析(一)加载大尺寸图片

http://www.eoeandroid.com/thread-331669-1-1.html

Android Bitmap 全面解析(二)加载多张图片的缓存处理
http://www.eoeandroid.com/thread-332399-1-1.html

Android Bitmap 全面解析(三)开源图片框架分析1-UIL(上)
http://www.eoeandroid.com/thread-333220-1-1.html

Android Bitmap 全面解析(三)开源图片框架分析1-UIL(下)
http://www.eoeandroid.com/thread-333229-1-1.html
Android Bitmap 全面解析(三)开源图片框架分析2-ImageLoader和Volley http://www.eoeandroid.com/thread-334315-1-1.html Android Bitmap 全面解析(四)图片处理效果对比 http://www.eoeandroid.com/thread-334752-1-1.html
 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  2  xmlns:tools="http://schemas.android.com/tools"  3  android:layout_width="match_parent"  4  android:layout_height="match_parent"  5  android:orientation="vertical"  6  tools:context=".MainActivity" >  7  8 <LinearLayout  9 android:layout_width="fill_parent" 10  android:layout_height="wrap_content" 11  android:orientation="horizontal" > 12 <ImageView 13 android:id="@+id/iv1" 14  android:layout_width="150dp" 15  android:layout_height="150dp" /> 16 <ImageView 17 android:id="@+id/iv2" 18  android:layout_width="150dp" 19  android:layout_height="150dp" 20  android:layout_marginLeft="20dp" 21  android:scaleType="centerCrop" /> 22 </LinearLayout> 23 24 <LinearLayout 25 android:layout_marginTop="50dp" 26  android:layout_width="fill_parent" 27  android:layout_height="wrap_content" 28  android:orientation="horizontal" > 29 <ImageView 30 android:id="@+id/iv3" 31  android:layout_width="150dp" 32  android:layout_height="150dp" /> 33 <ImageView 34 android:id="@+id/iv4" 35  android:layout_width="150dp" 36  android:layout_height="150dp" 37  android:layout_marginLeft="20dp" 38  android:scaleType="centerCrop" /> 39 </LinearLayout> 40 41 </LinearLayout>
  1 package com.example.bdimagescale;  2  3 import android.app.Activity;  4 import android.content.res.Resources;  5 import android.graphics.Bitmap;  6 import android.graphics.BitmapFactory;  7 import android.os.Bundle;  8 import android.view.Menu;  9 import android.widget.ImageView;  10  11 public class MainActivity extends Activity {  12  13 private static final int FIT_INSIDE = 1;  14 private static final int CROP = 2;  15  16 private ImageView iv1;// 默认缩放类型,即FIT_INSIDE  17 private ImageView iv2;// centerCrop缩放类型,即CROP  18 private ImageView iv3;// 默认缩放类型,即FIT_INSIDE  19 private ImageView iv4;// centerCrop缩放类型,即CROP  20  21  @Override  22 protected void onCreate(Bundle savedInstanceState) {  23 super.onCreate(savedInstanceState);  24  setContentView(R.layout.activity_main);  25  26 // // 10000以内随机宽高  27 // for(int i=0; i<20; i++) {  28 // int width = (int)(Math.random()*9000+1000);  29 // int height = (int)(Math.random()*9000+1000);  30 // test(width, height, 400, 200, 200, 200);  31 // // compareInSampleSize(width, height, 400, 200);  32 // }  33  34 iv1 = (ImageView) findViewById(R.id.iv1);  35 iv2 = (ImageView) findViewById(R.id.iv2);  36 iv3 = (ImageView) findViewById(R.id.iv3);  37 iv4 = (ImageView) findViewById(R.id.iv4);  38  testLongImage();  39 // testNormalImage();  40  }  41  42  @Override  43 public boolean onCreateOptionsMenu(Menu menu) {  44 // Inflate the menu; this adds items to the action bar if it is present.  45  getMenuInflater().inflate(R.menu.main, menu);  46 return true;  47  }  48  49 // 数据对比  50 public void test(int width, int height, int limitWidth, 
int limitHeight,int viewWidth, int viewHeight) { 52 System.out.println("原图宽高=" + width + ":" + height); 53 System.out.println("限定宽高=" + limitWidth + ":" + limitHeight); 54 System.out.println("控件大小=" + viewWidth + ":" + viewHeight); 55 float densityOfINSIDE0 = calculateImagePxDensityOfINSIDE(
limitWidth,
limitHeight, viewWidth, viewHeight); 57 System.out.println("默认即INDESE情况下目标像素密度为="
+ densityOfINSIDE0); 58 float densityOfCROP0 = calculateImagePxDensityOfCROP(limitWidth, 59 limitHeight, viewWidth, viewHeight); 60 System.out.println("CROP情况下目标像素密度为=" + densityOfCROP0); 61 System.out.println("---------------------"); 62 63 int inSampleSize1 = calculateInSampleSize(
width, height, limitWidth,
limitHeight); 65 int imageWidth = width / inSampleSize1; 66 int imageHeight = height / inSampleSize1; 67 System.out.println("官方:对应缩放后图片大小="
+ imageWidth + ":" + imageHeight); 68 float densityOfINSIDE = calculateImagePxDensityOfINSIDE(
imageWidth,
imageHeight, viewWidth, viewHeight); 70 System.out.println("默认即INDESE情况下像素密度为="
+ densityOfINSIDE); 71 float densityOfCROP = calculateImagePxDensityOfCROP(imageWidth, 72 imageHeight, viewWidth, viewHeight); 73 System.out.println("CROP情况下像素密度为=" + densityOfCROP); 74 System.out.println("---------------------"); 75 76 int reWidth = getResizedDimension(limitWidth, limitHeight,
width,
height); 78 int reHeight = getResizedDimension(limitHeight, limitWidth,
height,
width); 80 // System.out.println("处理后限定宽高="+reWidth+":"+reHeight); 81 int inSampleSize2 = findBestSampleSize(width, height, reWidth,
reHeight);
82 int imageWidth2 = width / inSampleSize2; 83 int imageHeight2 = height / inSampleSize2; 84 System.out.println("Volley:对应缩放后图片大小=" + imageWidth2 + ":" 85 + imageHeight2); 86 float densityOfINSIDE2 = calculateImagePxDensityOfINSIDE(
imageWidth2,
imageHeight2, viewWidth, viewHeight); 88 System.out.println("默认即INDESE情况下像素密度为="
+ densityOfINSIDE2); 89 float densityOfCROP2 = calculateImagePxDensityOfCROP(imageWidth2, 90 imageHeight2, viewWidth, viewHeight); 91 System.out.println("CROP情况下像素密度为=" + densityOfCROP2); 92 System.out.println("---------------------"); 93 94 int inSampleSize3OfINSIDE = computeImageSampleSize(width, height, 95 limitWidth, limitHeight, FIT_INSIDE, true); 96 int imageWidthOfINSIDE = width / inSampleSize3OfINSIDE; 97 int imageHeightOfINSIDE = height / inSampleSize3OfINSIDE; 98 System.out.println("UIL FIT_INSIDE:对应缩放后图片大小=" + imageWidthOfINSIDE 99 + ":" + imageHeightOfINSIDE); 100 float densityOfINSIDE3 = calculateImagePxDensityOfINSIDE( 101 imageWidthOfINSIDE, imageHeightOfINSIDE, viewWidth, viewHeight); 102 System.out.println("默认即INDESE情况下像素密度为=" + densityOfINSIDE3); 103 int inSampleSize3OfCROP = computeImageSampleSize(width, height, 104 limitWidth, limitHeight, CROP, true); 105 int imageWidthOfCROP = width / inSampleSize3OfCROP; 106 int imageHeightOfCROP = height / inSampleSize3OfCROP; 107 System.out.println("UIL CROP:对应缩放后图片大小=" + imageWidthOfCROP + ":" 108 + imageHeightOfCROP); 109 float densityOfCROP3 = calculateImagePxDensityOfCROP(imageWidthOfCROP, 110 imageHeightOfCROP, viewWidth, viewHeight); 111 System.out.println("CROP情况下像素密度为=" + densityOfCROP3); 112 System.out.println("---------------------"); 113 114 System.out.println(); 115 } 116 117 // inSampleSize对比 118 public void compareInSampleSize(int imageWidth, int imageHeight, 119 int reqWidth, int reqHeight) { 120 System.out.println("原图片 " + imageWidth + ":" + imageHeight); 121 System.out.print("官方 " 122 + calculateInSampleSize(imageWidth, imageHeight, reqWidth, 123 reqHeight)); 124 System.out.print(" ... "); 125 System.out.print("UIL " 126 + computeImageSampleSize(imageWidth, imageHeight, reqWidth, 127 reqHeight, CROP, true)); 128 System.out.print(" ... "); 129 System.out.print("Volley " 130 + findBestSampleSize(imageWidth, imageHeight, reqWidth, 131 reqHeight)); 132 System.out.println(); 133 System.out.println(); 134 } 135 136 public void testLongImage() { 137 Bitmap vbitmap = decodeByVolley(getResources(), R.drawable.longimage, 138 300, 300); 139 // UIL框架中会自行判断处理viewScaleType,这里为了简单临时手写了 140 Bitmap ubitmap_inside = decodeByUIL(getResources(), 141 R.drawable.longimage, 300, 300, FIT_INSIDE); 142 Bitmap ubitmap_crop = decodeByUIL(getResources(), R.drawable.longimage, 143 300, 300, CROP); 144 145 iv1.setImageBitmap(vbitmap); 146 iv2.setImageBitmap(vbitmap); 147 148 iv3.setImageBitmap(ubitmap_inside); 149 iv4.setImageBitmap(ubitmap_crop); 150 } 151 152 public void testNormalImage() { 153 Bitmap vbitmap = decodeByVolley(getResources(), R.drawable.normalimage, 154 300, 300); 155 // UIL框架中会自行判断处理viewScaleType,这里为了简单临时手写了 156 Bitmap ubitmap_inside = decodeByUIL(getResources(), 157 R.drawable.normalimage, 300, 300, FIT_INSIDE); 158 Bitmap ubitmap_crop = decodeByUIL(getResources(), 159 R.drawable.normalimage, 300, 300, CROP); 160 161 iv1.setImageBitmap(vbitmap); 162 iv2.setImageBitmap(vbitmap); 163 164 iv3.setImageBitmap(ubitmap_inside); 165 iv4.setImageBitmap(ubitmap_crop); 166 } 167 168 public Bitmap decodeByVolley(Resources res, int resId, int limitWidth, 169 int limitHeight) { 170 171 // 首先不加载图片,仅获取图片尺寸 172 final BitmapFactory.Options options = new BitmapFactory.Options(); 173 // 当inJustDecodeBounds设为true时,不会加载图片仅获取图片尺寸信息 174 options.inJustDecodeBounds = true; 175 // 此时仅会将图片信息会保存至options对象内,decode方法不会返回bitmap对象 176 BitmapFactory.decodeResource(res, resId, options); 177 178 int reWidth = getResizedDimension(limitWidth, limitHeight, 179 options.outWidth, options.outHeight); 180 int reHeight = getResizedDimension(limitHeight, limitWidth, 181 options.outHeight, options.outWidth); 182 183 // 计算压缩比例,如inSampleSize=4时,图片会压缩成原图的1/4 184 options.inSampleSize = findBestSampleSize(options.outWidth, 185 options.outHeight, reWidth, reHeight); 186 187 // 当inJustDecodeBounds设为false时,BitmapFactory.decode...就会返回图片对象了 188 options.inJustDecodeBounds = false; 189 // 利用计算的比例值获取压缩后的图片对象 190 return BitmapFactory.decodeResource(res, resId, options); 191 } 192 193 public Bitmap decodeByUIL(Resources res, int resId, int limitWidth, 194 int limitHeight, int scaleType) { 195 196 // 首先不加载图片,仅获取图片尺寸 197 final BitmapFactory.Options options = new BitmapFactory.Options(); 198 // 当inJustDecodeBounds设为true时,不会加载图片仅获取图片尺寸信息 199 options.inJustDecodeBounds = true; 200 // 此时仅会将图片信息会保存至options对象内,decode方法不会返回bitmap对象 201 BitmapFactory.decodeResource(res, resId, options); 202 203 // 计算压缩比例,如inSampleSize=4时,图片会压缩成原图的1/4 204 options.inSampleSize = computeImageSampleSize(options.outWidth, 205 options.outWidth, limitWidth, limitHeight, scaleType, true); 206 207 // 当inJustDecodeBounds设为false时,BitmapFactory.decode...就会返回图片对象了 208 options.inJustDecodeBounds = false; 209 // 利用计算的比例值获取压缩后的图片对象 210 return BitmapFactory.decodeResource(res, resId, options); 211 } 212 213 // 计算FIT_INSIDE时像素密度 214 static float calculateImagePxDensityOfINSIDE(int imageWidth, 215 int imageHeight, int viewWidth, int viewHeight) { 216 float density = -1; 217 if (imageWidth >= imageHeight) { 218 density = (float) imageWidth / (float) viewWidth; 219 } else { 220 density = (float) imageHeight / (float) viewHeight; 221 } 222 return density * density; 223 } 224 225 // 计算CROP时像素密度 226 static float calculateImagePxDensityOfCROP(int imageWidth, int imageHeight, 227 int viewWidth, int viewHeight) { 228 float density = -1; 229 if (imageWidth >= imageHeight) { 230 density = (float) imageHeight / (float) viewHeight; 231 } else { 232 density = (float) imageWidth / (float) viewWidth; 233 } 234 return density * density; 235 } 236 237 // ////////////////// 官方 //////////////////////////////// 238 int calculateInSampleSize(int width, int height, int reqWidth, int reqHeight) { 239 // 初始化压缩比例为1 240 int inSampleSize = 1; 241 242 // 当图片宽高值任何一个大于所需压缩图片宽高值时,进入循环计算系统 243 if (height > reqHeight || width > reqWidth) { 244 245 final int halfHeight = height / 2; 246 final int halfWidth = width / 2; 247 248 // 压缩比例值每次循环两倍增加, 249 // 直到原图宽高值的一半除以压缩值后都~大于所需宽高值为止(将>改成了>=) 250 while ((halfHeight / inSampleSize) >= reqHeight 251 && (halfWidth / inSampleSize) >= reqWidth) { 252 inSampleSize *= 2; 253 } 254 } 255 return inSampleSize; 256 } 257 258 // ////////////////// UIL //////////////////////////////// 259 int computeImageSampleSize(int width, int height, int limitWidth, 260 int limitHeight, int viewScaleType, boolean powerOf2Scale) { 261 262 int scale = 1; 263 264 int widthScale = width / limitWidth; 265 int heightScale = height / limitHeight; 266 267 switch (viewScaleType) { 268 case FIT_INSIDE: 269 if (powerOf2Scale) { 270 while (width / 2 >= limitWidth || height / 2 >= limitHeight) { // || 271 width /= 2; 272 height /= 2; 273 scale *= 2; 274 } 275 } else { 276 scale = Math.max(widthScale, heightScale); // max 277 } 278 break; 279 case CROP: 280 if (powerOf2Scale) { 281 while (width / 2 >= limitWidth && height / 2 >= limitHeight) { // && 282 width /= 2; 283 height /= 2; 284 scale *= 2; 285 } 286 } else { 287 scale = Math.min(widthScale, heightScale); // min 288 } 289 break; 290 } 291 292 if (scale < 1) { 293 scale = 1; 294 } 295 296 return scale; 297 } 298 299 // ////////////////// Volley //////////////////////////////// 300 int findBestSampleSize(int actualWidth, int actualHeight, int desiredWidth, 301 int desiredHeight) { 302 double wr = (double) actualWidth / desiredWidth; 303 double hr = (double) actualHeight / desiredHeight; 304 double ratio = Math.min(wr, hr); 305 float n = 1.0f; 306 while ((n * 2) <= ratio) { 307 n *= 2; 308 } 309 310 return (int) n; 311 } 312 313 int getResizedDimension(int maxPrimary, int maxSecondary, 314 int actualPrimary, int actualSecondary) { 315 // If no dominant value at all, just return the actual. 316 if (maxPrimary == 0 && maxSecondary == 0) { 317 return actualPrimary; 318 } 319 320 // If primary is unspecified, scale primary to match secondary's scaling 321 // ratio. 322 if (maxPrimary == 0) { 323 double ratio = (double) maxSecondary / (double) actualSecondary; 324 return (int) (actualPrimary * ratio); 325 } 326 327 if (maxSecondary == 0) { 328 return maxPrimary; 329 } 330 331 double ratio = (double) actualSecondary / (double) actualPrimary; 332 int resized = maxPrimary; 333 if (resized * ratio > maxSecondary) { 334 resized = (int) (maxSecondary / ratio); 335 } 336 return resized; 337 } 338 339 }

更多相关文章

  1. Android可缩放矢量图形(SVG)
  2. android photoview 图片放大缩放功能 ImageView
  3. Android图片太大导致无法正常显示
  4. 不停地切换两张图片ViewFlipper
  5. Android实现图片缩放与旋转
  6. Android Studio点击按钮更换背景图片
  7. android图片放大 缩小 旋转
  8. Android 怎么给图片添加一个边框

随机推荐

  1. Android(安卓)获取控件高度宽度三种方法
  2. Android App动态显示多个入口
  3. android java.net.UnknownHostException:
  4. Android 手写签名实例
  5. Android(安卓)自定义EditText输入框 带清
  6. [置顶] Android 之 Binder与进程间通信
  7. 为Android添加Java层服务
  8. Android探索之路(一)——消息处理机制
  9. Android NDK——实战演练之使用Android S
  10. Google Android介绍..