转载地址:http://blog.csdn.net/stoppig/article/details/23198809
一、什么是Android中的Bitmap
Bitmap是Android系统中的图像处理的最重要类之一。用它可以获取图像文件信息,进行图像剪切、旋转、缩放等操作,并可以指定格式保存图像文件。二、Bitmap的缩放基本操作
在Android开发中,经常会遇到图片的操作问题,由于Android屏幕尺寸繁多,最经常的是图片的缩放问题。下面为一段Android操作的基本代码- // 获得图片的宽高
- int width = bm.getWidth();
- int height = bm.getHeight();
- // 设置想要的大小
- int newWidth = 320;
- int newHeight = 480;
- // 计算缩放比例
- float scaleWidth = ((float) newWidth) / width;
- float scaleHeight = ((float) newHeight) / height;
- // 取得想要缩放的matrix参数
- Matrix matrix = new Matrix();
- matrix.postScale(scaleWidth, scaleHeight);
- // 得到新的图片
- Bitmap newbm = Bitmap.createBitmap(bm, 0, 0, width, height, matrix,
- true);
三、Bitmap缩放方法的封装
为了使用方便,我们对bitmap方法进行封装
- import java.io.ByteArrayInputStream;
- import java.io.ByteArrayOutputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import android.content.Context;
- import android.content.Intent;
- import android.graphics.Bitmap;
- import android.graphics.Bitmap.Config;
- import android.graphics.BitmapFactory;
- import android.graphics.Canvas;
- import android.graphics.Matrix;
- import android.net.Uri;
- import android.util.Log;
- public class Bitmaptest
- {
- private static final String TAG = "BitmapUtil";
- /**
- * 通过资源id转化成Bitmap
- *
- * @param context
- * @param resId
- * @return
- */
- public static Bitmap ReadBitmapById(Context context, int resId)
- {
- BitmapFactory.Options opt = new BitmapFactory.Options();
- opt.inPreferredConfig = Bitmap.Config.RGB_565;
- opt.inPurgeable = true;
- opt.inInputShareable = true;
- InputStream is = context.getResources().openRawResource(resId);
- return BitmapFactory.decodeStream(is, null, opt);
- }
- /**
- * 缩放Bitmap满屏
- *
- * @param bitmap
- * @param screenWidth
- * @param screenHight
- * @return
- */
- public static Bitmap getBitmap(Bitmap bitmap, int screenWidth,
- int screenHight)
- {
- int w = bitmap.getWidth();
- int h = bitmap.getHeight();
- Matrix matrix = new Matrix();
- float scale = (float) screenWidth / w;
- float scale2 = (float) screenHight / h;
- // scale = scale < scale2 ? scale : scale2;
- matrix.postScale(scale, scale);
- Bitmap bmp = Bitmap.createBitmap(bitmap, 0, 0, w, h, matrix, true);
- if (bitmap != null && !bitmap.equals(bmp) && !bitmap.isRecycled())
- {
- bitmap.recycle();
- bitmap = null;
- }
- return bmp;// Bitmap.createBitmap(bitmap, 0, 0, w, h, matrix, true);
- }
- /**
- * 按最大边按一定大小缩放图片
- * */
- public static Bitmap scaleImage(byte[] buffer, float size)
- {
- // 获取原图宽度
- BitmapFactory.Options options = new BitmapFactory.Options();
- options.inJustDecodeBounds = true;
- options.inPurgeable = true;
- options.inInputShareable = true;
- Bitmap bm = BitmapFactory.decodeByteArray(buffer, 0, buffer.length,
- options);
- // 计算缩放比例
- float reSize = options.outWidth / size;
- if (options.outWidth < options.outHeight)
- {
- reSize = options.outHeight / size;
- }
- // 如果是小图则放大
- if (reSize <= 1)
- {
- int newWidth = 0;
- int newHeight = 0;
- if (options.outWidth > options.outHeight)
- {
- newWidth = (int) size;
- newHeight = options.outHeight * (int) size / options.outWidth;
- } else
- {
- newHeight = (int) size;
- newWidth = options.outWidth * (int) size / options.outHeight;
- }
- bm = BitmapFactory.decodeByteArray(buffer, 0, buffer.length);
- bm = scaleImage(bm, newWidth, newHeight);
- if (bm == null)
- {
- Log.e(TAG, "convertToThumb, decode fail:" + null);
- return null;
- }
- return bm;
- }
- // 缩放
- options.inJustDecodeBounds = false;
- options.inSampleSize = (int) reSize;
- bm = BitmapFactory.decodeByteArray(buffer, 0, buffer.length, options);
- if (bm == null)
- {
- Log.e(TAG, "convertToThumb, decode fail:" + null);
- return null;
- }
- return bm;
- }
- /**
- * 检查图片是否超过一定值,是则缩小
- *
- * @param view
- * @param strFileName
- */
- public static Bitmap convertToThumb(byte[] buffer, float size)
- {
- // 获取原图宽度
- BitmapFactory.Options options = new BitmapFactory.Options();
- options.inJustDecodeBounds = true;
- options.inPurgeable = true;
- options.inInputShareable = true;
- Bitmap bm = BitmapFactory.decodeByteArray(buffer, 0, buffer.length,
- options);
- // 计算缩放比例
- float reSize = options.outWidth / size;
- if (options.outWidth > options.outHeight)
- {
- reSize = options.outHeight / size;
- }
- if (reSize <= 0)
- {
- reSize = 1;
- }
- Log.d(TAG, "convertToThumb, reSize:" + reSize);
- // 缩放
- options.inJustDecodeBounds = false;
- options.inSampleSize = (int) reSize;
- if (bm != null && !bm.isRecycled())
- {
- bm.recycle();
- bm = null;
- Log.e(TAG, "convertToThumb, recyle");
- }
- bm = BitmapFactory.decodeByteArray(buffer, 0, buffer.length, options);
- if (bm == null)
- {
- Log.e(TAG, "convertToThumb, decode fail:" + null);
- return null;
- }
- return bm;
- }
- /**
- * Bitmap --> byte[]
- *
- * @param bmp
- * @return
- */
- private static byte[] readBitmap(Bitmap bmp)
- {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- bmp.compress(Bitmap.CompressFormat.JPEG, 60, baos);
- try
- {
- baos.flush();
- baos.close();
- } catch (IOException e)
- {
- e.printStackTrace();
- }
- return baos.toByteArray();
- }
- /**
- * Bitmap --> byte[]
- *
- * @param bmp
- * @return
- */
- public static byte[] readBitmapFromBuffer(byte[] buffer, float size)
- {
- return readBitmap(convertToThumb(buffer, size));
- }
- /**
- * 以屏幕宽度为基准,显示图片
- *
- * @param iv
- * @param path
- * @param screenW
- * @return
- */
- public static Bitmap decodeStream(Context context, Intent data, float size)
- {
- Bitmap image = null;
- try
- {
- Uri dataUri = data.getData();
- // 获取原图宽度
- BitmapFactory.Options options = new BitmapFactory.Options();
- options.inJustDecodeBounds = true;
- options.inPurgeable = true;
- options.inInputShareable = true;
- BitmapFactory.decodeStream(context.getContentResolver()
- .openInputStream(dataUri), null, options);
- // 计算缩放比例
- float reSize = (int) (options.outWidth / size);
- if (reSize <= 0)
- {
- reSize = 1;
- }
- Log.d(TAG, "old-w:" + options.outWidth + ", llyt-w:" + size
- + ", resize:" + reSize);
- // 缩放
- options.inJustDecodeBounds = false;
- options.inSampleSize = (int) reSize;
- image = BitmapFactory.decodeStream(context.getContentResolver()
- .openInputStream(dataUri), null, options);
- } catch (Exception e)
- {
- e.printStackTrace();
- }
- return image;
- }
- /**
- * 按新的宽高缩放图片
- *
- * @param bm
- * @param newWidth
- * @param newHeight
- * @return
- */
- public static Bitmap scaleImage(Bitmap bm, int newWidth, int newHeight)
- {
- if (bm == null)
- {
- return null;
- }
- int width = bm.getWidth();
- int height = bm.getHeight();
- float scaleWidth = ((float) newWidth) / width;
- float scaleHeight = ((float) newHeight) / height;
- Matrix matrix = new Matrix();
- matrix.postScale(scaleWidth, scaleHeight);
- Bitmap newbm = Bitmap.createBitmap(bm, 0, 0, width, height, matrix,
- true);
- if (bm != null & !bm.isRecycled())
- {
- bm.recycle();
- bm = null;
- }
- return newbm;
- }
- /**
- * fuction: 设置固定的宽度,高度随之变化,使图片不会变形
- *
- * @param target
- * 需要转化bitmap参数
- * @param newWidth
- * 设置新的宽度
- * @return
- */
- public static Bitmap fitBitmap(Bitmap target, int newWidth)
- {
- int width = target.getWidth();
- int height = target.getHeight();
- Matrix matrix = new Matrix();
- float scaleWidth = ((float) newWidth) / width;
- // float scaleHeight = ((float)newHeight) / height;
- int newHeight = (int) (scaleWidth * height);
- matrix.postScale(scaleWidth, scaleWidth);
- // Bitmap result = Bitmap.createBitmap(target,0,0,width,height,
- // matrix,true);
- Bitmap bmp = Bitmap.createBitmap(target, 0, 0, width, height, matrix,
- true);
- if (target != null && !target.equals(bmp) && !target.isRecycled())
- {
- target.recycle();
- target = null;
- }
- return bmp;// Bitmap.createBitmap(target, 0, 0, width, height, matrix,
- // true);
- }
- /**
- * 根据指定的宽度平铺图像
- *
- * @param width
- * @param src
- * @return
- */
- public static Bitmap createRepeater(int width, Bitmap src)
- {
- int count = (width + src.getWidth() - 1) / src.getWidth();
- Bitmap bitmap = Bitmap.createBitmap(width, src.getHeight(),
- Config.ARGB_8888);
- Canvas canvas = new Canvas(bitmap);
- for (int idx = 0; idx < count; ++idx)
- {
- canvas.drawBitmap(src, idx * src.getWidth(), 0, null);
- }
- return bitmap;
- }
- /**
- * 图片的质量压缩方法
- *
- * @param image
- * @return
- */
- public static Bitmap compressImage(Bitmap image)
- {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- image.compress(Bitmap.CompressFormat.JPEG, 100, baos);// 质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
- int options = 100;
- while (baos.toByteArray().length / 1024 > 100)
- { // 循环判断如果压缩后图片是否大于100kb,大于继续压缩
- baos.reset();// 重置baos即清空baos
- image.compress(Bitmap.CompressFormat.JPEG, options, baos);// 这里压缩options%,把压缩后的数据存放到baos中
- options -= 10;// 每次都减少10
- }
- ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());// 把压缩后的数据baos存放到ByteArrayInputStream中
- Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);// 把ByteArrayInputStream数据生成图片
- if (baos != null)
- {
- try
- {
- baos.close();
- } catch (IOException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- if (isBm != null)
- {
- try
- {
- isBm.close();
- } catch (IOException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- if (image != null && !image.isRecycled())
- {
- image.recycle();
- image = null;
- }
- return bitmap;
- }
- /**
- * 图片按比例大小压缩方法(根据Bitmap图片压缩)
- *
- * @param image
- * @return
- */
- public static Bitmap getImage(Bitmap image)
- {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
- if (baos.toByteArray().length / 1024 > 1024)
- {// 判断如果图片大于1M,进行压缩避免在生成图片(BitmapFactory.decodeStream)时溢出
- baos.reset();// 重置baos即清空baos
- image.compress(Bitmap.CompressFormat.JPEG, 50, baos);// 这里压缩50%,把压缩后的数据存放到baos中
- }
- ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
- BitmapFactory.Options newOpts = new BitmapFactory.Options();
- // 开始读入图片,此时把options.inJustDecodeBounds 设回true了
- newOpts.inJustDecodeBounds = true;
- Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
- newOpts.inJustDecodeBounds = false;
- int w = newOpts.outWidth;
- int h = newOpts.outHeight;
- // 现在主流手机比较多是800*480分辨率,所以高和宽我们设置为
- float hh = 800f;// 这里设置高度为800f
- float ww = 480f;// 这里设置宽度为480f
- // 缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
- int be = 1;// be=1表示不缩放
- if (w > h && w > ww)
- {// 如果宽度大的话根据宽度固定大小缩放
- be = (int) (newOpts.outWidth / ww);
- } else if (w < h && h > hh)
- {// 如果高度高的话根据宽度固定大小缩放
- be = (int) (newOpts.outHeight / hh);
- }
- if (be <= 0)
- be = 1;
- newOpts.inSampleSize = be;// 设置缩放比例
- // 重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
- isBm = new ByteArrayInputStream(baos.toByteArray());
- bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
- if (isBm != null)
- {
- try
- {
- isBm.close();
- } catch (IOException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- if (image != null && !image.isRecycled())
- {
- image.recycle();
- image = null;
- }
- return compressImage(bitmap);// 压缩好比例大小后再进行质量压缩
- }
- /**
- * 通过资源id转化成Bitmap 全屏显示
- *
- * @param context
- * @param drawableId
- * @param screenWidth
- * @param screenHight
- * @return
- */
- public static Bitmap ReadBitmapById(Context context, int drawableId,
- int screenWidth, int screenHight)
- {
- BitmapFactory.Options options = new BitmapFactory.Options();
- options.inPreferredConfig = Config.ARGB_8888;
- options.inInputShareable = true;
- options.inPurgeable = true;
- InputStream stream = context.getResources().openRawResource(drawableId);
- Bitmap bitmap = BitmapFactory.decodeStream(stream, null, options);
- return getBitmap(bitmap, screenWidth, screenHight);
- }
- }