Bitmap用法

转载自http://www.jb51.net/article/32366.htm

  1 package com.testbitmapscale;
  2 
  3 import java.io.File;
  4 import java.io.FileInputStream;
  5 import java.io.FileOutputStream;
  6 import java.io.IOException;
  7 import java.io.InputStream;
  8 import java.util.Iterator;
  9 import com.testbitmapscale.R.drawable;
 10 import android.app.Activity;
 11 import android.graphics.Bitmap;
 12 import android.graphics.Bitmap.Config;
 13 import android.graphics.BitmapFactory;
 14 import android.graphics.Canvas;
 15 import android.graphics.Matrix;
 16 import android.graphics.Paint;
 17 import android.graphics.PorterDuff.Mode;
 18 import android.graphics.PorterDuffXfermode;
 19 import android.graphics.Rect;
 20 import android.graphics.RectF;
 21 import android.graphics.drawable.BitmapDrawable;
 22 import android.graphics.drawable.Drawable;
 23 import android.media.ThumbnailUtils;
 24 import android.os.Bundle;
 25 import android.os.Environment;
 26 import android.view.View;
 27 import android.widget.ImageView;
 28 //方法: 
 29 //1 生成圆角Bitmap图片 
 30 //2 生成Bitmap缩量图 
 31 //3 压缩图片场长宽以及kB 
 32 //注意: 
 33 //以上代码,测试其中一个方法时最好注释掉其余的代码 
 34 
 35 public class MainActivity extends Activity {
 36     private ImageView imageView;
 37     private Bitmap copyRawBitmap1;
 38     private Bitmap copyRawBitmap2;
 39     private Bitmap copyRawBitmap3;
 40 
 41     @Override
 42     public void onCreate(Bundle savedInstanceState) {
 43         super.onCreate(savedInstanceState);
 44         setContentView(R.layout.main);
 45         imageView = (ImageView) findViewById(R.id.imageView);
 46         // 第一种方式:从资源文件中得到图片
 47         Bitmap rawBitmap = BitmapFactory.decodeResource(getResources(),
 48                 R.drawable.haha);
 49         copyRawBitmap1 = rawBitmap;
 50         copyRawBitmap2 = rawBitmap;
 51         copyRawBitmap3 = rawBitmap;
 52         // 第二种方式:从SD卡中得到图片(方法1)
 53         String SDCarePath = Environment.getExternalStorageDirectory()
 54                 .toString();
 55         String filePath = SDCarePath + "/" + "haha.jpg";
 56         Bitmap rawBitmap1 = BitmapFactory.decodeFile(filePath, null);
 57         // 第二种方式:从SD卡中得到图片(方法2)
 58         InputStream inputStream = getBitmapInputStreamFromSDCard("haha.jpg");
 59         Bitmap rawBitmap2 = BitmapFactory.decodeStream(inputStream);
 60 
 61         // ————>以下为将设置图片的圆角
 62         Bitmap roundCornerBitmap = this.toRoundCorner(rawBitmap, 40);
 63         imageView.setImageBitmap(roundCornerBitmap);
 64         // ————>以上为将设置图片的圆角
 65 
 66         // ————>以下为将图片高宽和的大小kB压缩
 67         // 得到图片原始的高宽
 68         int rawHeight = rawBitmap.getHeight();
 69         int rawWidth = rawBitmap.getWidth();
 70         // 设定图片新的高宽
 71         int newHeight = 500;
 72         int newWidth = 500;
 73         // 计算缩放因子
 74         float heightScale = ((float) newHeight) / rawHeight;
 75         float widthScale = ((float) newWidth) / rawWidth;
 76         // 新建立矩阵
 77         Matrix matrix = new Matrix();
 78         matrix.postScale(heightScale, widthScale);
 79         // 设置图片的旋转角度
 80         // matrix.postRotate(-30);
 81         // 设置图片的倾斜
 82         // matrix.postSkew(0.1f, 0.1f);
 83         // 将图片大小压缩
 84         // 压缩后图片的宽和高以及kB大小均会变化
 85         Bitmap newBitmap = Bitmap.createBitmap(rawBitmap, 0, 0, rawWidth,
 86                 rawWidth, matrix, true);
 87         // 将Bitmap转换为Drawable
 88         Drawable newBitmapDrawable = new BitmapDrawable(newBitmap);
 89         imageView.setImageDrawable(newBitmapDrawable);
 90         // 然后将Bitmap保存到SDCard中,方便于原图片的比较
 91         this.compressAndSaveBitmapToSDCard(newBitmap, "xx100.jpg", 80);
 92         // 问题:
 93         // 原图大小为625x690 90.2kB
 94         // 如果设置图片500x500 压缩后大小为171kB.即压缩后kB反而变大了.
 95         // 原因是将:compress(Bitmap.CompressFormat.JPEG, quality, fileOutputStream);
 96         // 第二个参数quality设置得有些大了(比如100).
 97         // 常用的是80,刚设100太大了造成的.
 98         // ————>以上为将图片高宽和的大小kB压缩
 99 
100         // ————>以下为将图片的kB压缩,宽高不变
101         this.compressAndSaveBitmapToSDCard(copyRawBitmap1, "0011fa.jpg", 80);
102         // ————>以上为将图片的kB压缩,宽高不变
103 
104         // ————>以下为获取SD卡图片的缩略图方法1
105         String SDCarePath1 = Environment.getExternalStorageDirectory()
106                 .toString();
107         String filePath1 = SDCarePath1 + "/" + "haha.jpg";
108         Bitmap bitmapThumbnail1 = this.getBitmapThumbnail(filePath1);
109         imageView.setImageBitmap(bitmapThumbnail1);
110         // ————>以上为获取SD卡图片的缩略图方法1
111 
112         // ————>以下为获取SD卡图片的缩略图方法2
113         String SDCarePath2 = Environment.getExternalStorageDirectory()
114                 .toString();
115         String filePath2 = SDCarePath2 + "/" + "haha.jpg";
116         Bitmap tempBitmap = BitmapFactory.decodeFile(filePath2);
117         Bitmap bitmapThumbnail2 = ThumbnailUtils.extractThumbnail(tempBitmap,
118                 100, 100);
119         imageView.setImageBitmap(bitmapThumbnail2);
120         // ————>以上为获取SD卡图片的缩略图方法2
121 
122     }
123 
124     // 读取SD卡下的图片
125     private InputStream getBitmapInputStreamFromSDCard(String fileName) {
126         if (Environment.getExternalStorageState().equals(
127                 Environment.MEDIA_MOUNTED)) {
128             String SDCarePath = Environment.getExternalStorageDirectory()
129                     .toString();
130             String filePath = SDCarePath + File.separator + fileName;
131             File file = new File(filePath);
132             try {
133                 FileInputStream fileInputStream = new FileInputStream(file);
134                 return fileInputStream;
135             } catch (Exception e) {
136                 e.printStackTrace();
137             }
138 
139         }
140         return null;
141     }
142 
143     // 获取SDCard的目录路径功能
144     private String getSDCardPath() {
145         String SDCardPath = null;
146         // 判断SDCard是否存在
147         boolean IsSDcardExist = Environment.getExternalStorageState().equals(
148                 android.os.Environment.MEDIA_MOUNTED);
149         if (IsSDcardExist) {
150             SDCardPath = Environment.getExternalStorageDirectory().toString();
151         }
152         return SDCardPath;
153     }
154 
155     // 压缩且保存图片到SDCard
156     private void compressAndSaveBitmapToSDCard(Bitmap rawBitmap,
157             String fileName, int quality) {
158         String saveFilePaht = this.getSDCardPath() + File.separator + fileName;
159         File saveFile = new File(saveFilePaht);
160         if (!saveFile.exists()) {
161             try {
162                 saveFile.createNewFile();
163                 FileOutputStream fileOutputStream = new FileOutputStream(
164                         saveFile);
165                 if (fileOutputStream != null) {
166                     // imageBitmap.compress(format, quality, stream);
167                     // 把位图的压缩信息写入到一个指定的输出流中
168                     // 第一个参数format为压缩的格式
169                     // 第二个参数quality为图像压缩比的值,0-100.0 意味着小尺寸压缩,100意味着高质量压缩
170                     // 第三个参数stream为输出流
171                     rawBitmap.compress(Bitmap.CompressFormat.JPEG, quality,
172                             fileOutputStream);
173                 }
174                 fileOutputStream.flush();
175                 fileOutputStream.close();
176             } catch (IOException e) {
177                 e.printStackTrace();
178 
179             }
180         }
181     }
182 
183     // 获取图片的缩略图
184     private Bitmap getBitmapThumbnail(String filePath) {
185         BitmapFactory.Options options = new BitmapFactory.Options();
186         // true那么将不返回实际的bitmap对象,不给其分配内存空间但是可以得到一些解码边界信息即图片大小等信息
187         options.inJustDecodeBounds = true;
188         // 此时rawBitmap为null
189         Bitmap rawBitmap = BitmapFactory.decodeFile(filePath, options);
190         if (rawBitmap == null) {
191             System.out.println("此时rawBitmap为null");
192         }
193         // inSampleSize表示缩略图大小为原始图片大小的几分之一,若该值为3
194         // 则取出的缩略图的宽和高都是原始图片的1/3,图片大小就为原始大小的1/9
195         // 计算sampleSize
196         int sampleSize = computeSampleSize(options, 150, 200 * 200);
197         // 为了读到图片,必须把options.inJustDecodeBounds设回false
198         options.inJustDecodeBounds = false;
199         options.inSampleSize = sampleSize;
200         // 原图大小为625x690 90.2kB
201         // 测试调用computeSampleSize(options, 100, 200*100);
202         // 得到sampleSize=8
203         // 得到宽和高位79和87
204         // 79*8=632 87*8=696
205         Bitmap thumbnailBitmap = BitmapFactory.decodeFile(filePath, options);
206         // 保存到SD卡方便比较
207         this.compressAndSaveBitmapToSDCard(thumbnailBitmap, "15.jpg", 80);
208         return thumbnailBitmap;
209     }
210 
211     // 参考资料:
212     // http://my.csdn.net/zljk000/code/detail/18212
213     // 第一个参数:原本Bitmap的options
214     // 第二个参数:希望生成的缩略图的宽高中的较小的值
215     // 第三个参数:希望生成的缩量图的总像素
216     public static int computeSampleSize(BitmapFactory.Options options,
217             int minSideLength, int maxNumOfPixels) {
218         int initialSize = computeInitialSampleSize(options, minSideLength,
219                 maxNumOfPixels);
220         int roundedSize;
221         if (initialSize <= 8) {
222             roundedSize = 1;
223             while (roundedSize < initialSize) {
224                 roundedSize <<= 1;
225             }
226         } else {
227             roundedSize = (initialSize + 7) / 8 * 8;
228         }
229         return roundedSize;
230     }
231 
232     private static int computeInitialSampleSize(BitmapFactory.Options options,
233             int minSideLength, int maxNumOfPixels) {
234         // 原始图片的宽
235         double w = options.outWidth;
236         // 原始图片的高
237         double h = options.outHeight;
238         System.out.println("========== w=" + w + ",h=" + h);
239         int lowerBound = (maxNumOfPixels == -1) ? 1 : (int) Math.ceil(Math
240                 .sqrt(w * h / maxNumOfPixels));
241         int upperBound = (minSideLength == -1) ? 128 : (int) Math.min(
242                 Math.floor(w / minSideLength), Math.floor(h / minSideLength));
243         if (upperBound < lowerBound) {
244             // return the larger one when there is no overlapping zone.
245             return lowerBound;
246         }
247         if ((maxNumOfPixels == -1) && (minSideLength == -1)) {
248             return 1;
249         } else if (minSideLength == -1) {
250             return lowerBound;
251         } else {
252             return upperBound;
253         }
254     }
255 
256     /**
257      * @param bitmap
258      *            需要修改的图片
259      * @param pixels
260      *            圆角的弧度
261      * @return 圆角图片
262      */
263     // 参考资料:
264     // http://blog.csdn.net/c8822882/article/details/6906768
265     public Bitmap toRoundCorner(Bitmap bitmap, int pixels) {
266         Bitmap roundCornerBitmap = Bitmap.createBitmap(bitmap.getWidth(),
267                 bitmap.getHeight(), Config.ARGB_8888);
268         Canvas canvas = new Canvas(roundCornerBitmap);
269         int color = 0xff424242;// int color = 0xff424242;
270         Paint paint = new Paint();
271         paint.setColor(color);
272         // 防止锯齿
273         paint.setAntiAlias(true);
274         Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
275         RectF rectF = new RectF(rect);
276         float roundPx = pixels;
277         // 相当于清屏
278         canvas.drawARGB(0, 0, 0, 0);
279         // 先画了一个带圆角的矩形
280         canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
281         paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
282         // 再把原来的bitmap画到现在的bitmap!!!注意这个理解
283         canvas.drawBitmap(bitmap, rect, rect, paint);
284         return roundCornerBitmap;
285     }
286 
287 }

 

posted @ 2015-03-26 20:27  陶修瑕  阅读(495)  评论(0)    收藏  举报