zoukankan      html  css  js  c++  java
  • 36、Android Bitmap 全面解析

    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
     
    Android Bitmap 全面解析(四)图片处理效果对比
     
     
     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 }
  • 相关阅读:
    TestNG 单元测试框架的使用
    HDU1255 覆盖的面积(线段树+扫描线)
    AcWing1169 糖果(差分约数)
    牛客 Treepath(树形dp)
    牛客 Shortest Path (dfs+思维)
    牛客 树(dfs序)
    牛客 城市网络(倍增)
    牛客 Borrow Classroom (LCA)
    CF710E Generate a String(dp)
    c#委托
  • 原文地址:https://www.cnblogs.com/androidsj/p/3983043.html
Copyright © 2011-2022 走看看