一、问题描述 |
在开发中,当我们需要的有一张大图片同时还需要一些小图片时,我们只需要通过代码对此图片进行不同比例的缩放即可,这样大大节约资源,减小了安装包的尺寸 。除缩放外,我们还经常对图片进行其他操作如裁剪、旋转、存储等。
这样我们可以编写对于图片进行处理的通用组件,方便开发。下面就分享一下对图片进行处理的组件BitmapUtil,案例界面:
二、技术点描述 |
1、通过BitmapFactory取得Bitmap
Bitmap bm=BitmapFactory.decodeStream(InputStream is );
2、Bimap的createBitmap()方法
Bitmap newbm = Bitmap.createBitmap( Bitmap s, int x, int y, int w, int h, Matrix m, boolean f);
该方法可实现位图的缩放、裁剪、旋转操作
参数说明:
Bitmap s:要处理的原始位图
int x ,y:起始位置坐标
int w:要截的图的宽度
int h:要截的图的宽度
Matrix m 矩阵,主要是用于平面的缩放、平移、旋转
boolean f:是否保证等比
返回值:返回处理后的Bitmap
三、BitmapUtil组件 |
可实现对图片进行按比例缩放、图片按比例裁剪、圆形图片处理等方法,实现功能如下:
1、readBitmapById()方法
/** * 通过资源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); }
2、scaleImage()方法,实现按指定宽高缩放图片
执行效果如图:
/** * 缩放图片 * @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; }
3、imageCrop()方法
执行效果如图:
/** * 按照一定的宽高比例裁剪图片 * @param bitmap 要裁剪的图片 * @param num1 长边的比例 * @param num2 短边的比例 * @param isRecycled是否回收原图片 * @return 裁剪后的图片 */ public static Bitmap imageCrop(Bitmap bitmap, int num1, int num2, boolean isRecycled){ if (bitmap == null){ return null; } int w = bitmap.getWidth(); // 得到图片的宽,高 int h = bitmap.getHeight(); int retX, retY; int nw, nh; if (w > h){ if (h > w * num2 / num1){ nw = w; nh = w * num2 / num1; retX = 0; retY = (h - nh) / 2; } else{ nw = h * num1 / num2; nh = h; retX = (w - nw) / 2; retY = 0; } } else{ if (w > h * num2 / num1){ nh = h; nw = h * num2 / num1; retY = 0; retX = (w - nw) / 2; } else{ nh = w * num1 / num2; nw = w; retY = (h - nh) / 2; retX = 0;} } Bitmap bmp = Bitmap.createBitmap(bitmap, retX, retY, nw, nh, null,false); if (isRecycled && bitmap != null && !bitmap.equals(bmp)&& !bitmap.isRecycled()){ bitmap.recycle();//回收原图片 bitmap = null; } return bmp; }
4、toRoundCorner()实现将图片转圆角
执行效果如图:
/** *图片转圆角 * @param bitmap需要转的bitmap * @param pixels转圆角的弧度 * @return 转圆角的bitmap */ public static Bitmap toRoundCorner(Bitmap bitmap, int pixels) { Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888); Canvas canvas = new Canvas(output); final int color = 0xff424242; final Paint paint = new Paint(); final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); final RectF rectF = new RectF(rect); final float roundPx = pixels; paint.setAntiAlias(true); canvas.drawARGB(0, 0, 0, 0); paint.setColor(color); canvas.drawRoundRect(rectF, roundPx, roundPx, paint); paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); canvas.drawBitmap(bitmap, rect, rect, paint); if (bitmap != null && !bitmap.isRecycled()) { bitmap.recycle(); } return output; }
5、toRoundBitmap()方法将图像裁剪成圆形
执行效果如图:
public static Bitmap toRoundBitmap(Bitmap bitmap){ if (bitmap == null){ return null; } int width = bitmap.getWidth(); int height = bitmap.getHeight(); float roundPx; float left, top, right, bottom, dst_left, dst_top, dst_right, dst_bottom; if (width <= height){ roundPx = width / 2; top = 0; bottom = width; left = 0; right = width; height = width; dst_left = 0; dst_top = 0; dst_right = width; dst_bottom = width; } else{ roundPx = height / 2; float clip = (width - height) / 2; left = clip; right = width - clip; top = 0; bottom = height; width = height; dst_left = 0; dst_top = 0; dst_right = height; dst_bottom = height; } Bitmap output = Bitmap.createBitmap(width, height, Config.ARGB_8888); Canvas canvas = new Canvas(output); final int color = 0xff424242; final Paint paint = new Paint(); final Rect src = new Rect((int) left, (int) top, (int) right, (int) bottom); final Rect dst = new Rect((int) dst_left, (int) dst_top, (int) dst_right, (int) dst_bottom); final RectF rectF = new RectF(dst); paint.setAntiAlias(true); canvas.drawARGB(0, 0, 0, 0); paint.setColor(color); canvas.drawRoundRect(rectF, roundPx, roundPx, paint); paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); canvas.drawBitmap(bitmap, src, dst, paint); if (bitmap != null && !bitmap.isRecycled()){ bitmap.recycle(); bitmap = null; } return output; }
6、rotaingImageView()方法,实现旋转图片
执行效果如图:
/** * 旋转图片 * @param angle 旋转角度 * @param bitmap 要处理的Bitmap * @return 处理后的Bitmap */ public static Bitmap rotaingImageView(int angle, Bitmap bitmap) { // 旋转图片 动作 Matrix matrix = new Matrix(); matrix.postRotate(angle); // 创建新的图片 Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); if (resizedBitmap != bitmap && bitmap != null && !bitmap.isRecycled()){ bitmap.recycle(); bitmap = null; } return resizedBitmap; }
7、saveBmpToSd()实现将保存Bitmap到sdcard
public static boolean saveBmpToSd(String dir, Bitmap bm, String filename, int quantity, boolean recyle) { boolean ret = true; if (bm == null) { return false;} File dirPath = new File(dir); if (!exists(dir)) { dirPath.mkdirs(); } if (!dir.endsWith(File.separator)) { dir += File.separator; } File file = new File(dir + filename); OutputStream outStream = null; try { file.createNewFile(); outStream = new FileOutputStream(file); bm.compress(Bitmap.CompressFormat.JPEG, quantity, outStream); } catch (Exception e) { e.printStackTrace(); ret = false; } finally { try { if (outStream != null) outStream.close(); } catch (IOException e) { e.printStackTrace(); } if (recyle && !bm.isRecycled()) { bm.recycle(); bm = null; } } return ret; }