Bitmap可以说是图像处理中最重要的类,可以实现图像的剪切,旋转,旋转操作,我正在做的就是一个图片处理app,下面我会说一些在项目中遇到的问题和一些解决方案。
View 转换为Bitmap
第一种方式:
/**
* view turnto bitmap
* =======
* 将View转为Bitmap
* >>>>>>> master
*
* @param view
* @return
*/
public static Bitmap getViewBitmap(View view) {
view.clearFocus(); // 清除视图焦点
view.setPressed(false);// 将视图设为不可点击
boolean willNotCache = view.willNotCacheDrawing();// 返回视图是否可以保存他的画图缓存
view.setWillNotCacheDrawing(false);
// Reset the drawing cache background color to fully transparent
// for the duration of this operation //将视图在此操作时置为透明
int color = view.getDrawingCacheBackgroundColor();// 获得绘制缓存位图的背景颜色
view.setDrawingCacheBackgroundColor(0);// 设置绘图背景颜色
if (color != 0) {// 如果获得的背景不是黑色的则释放以前的绘图缓存
view.destroyDrawingCache();// 释放绘图资源所使用的缓存
}
view.buildDrawingCache();// 重新创建绘图缓存,此时的背景色是黑色
Bitmap cacheBitmap = view.getDrawingCache();// 将绘图缓存得到的,注意这里得到的只是一个图像的引用
if (cacheBitmap == null) {
return null;
}
Bitmap bitmap = null;
try {
bitmap = Bitmap.createBitmap(cacheBitmap);// 将位图实例化
} catch (OutOfMemoryError e) {
while (bitmap == null) {
System.gc();
System.runFinalization();
bitmap = createBitmap(cacheBitmap, view.getWidth(), view.getHeight());// 将位图实例化
}
}
view.destroyDrawingCache();// Restore the view //恢复视图
view.setWillNotCacheDrawing(willNotCache);// 返回以前缓存设置
view.setDrawingCacheBackgroundColor(color);// 返回以前的缓存颜色设置
return bitmap;
}
第二种方式;
/**
* 将View转为Bitmap
*
* @param view
* @return
*/
public static Bitmap convertViewToBitmap(View view) {
view.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
view.buildDrawingCache();
Bitmap bitmap = view.getDrawingCache();
return bitmap;
}
截取指定图片的中间部分 并缩放到指定宽度
/**
* @param bitmap 原图
* @param edgeLength 希望得到的正方形部分的边长
* @return 缩放截取正中部分后的位图。
*/
public static Bitmap centerSquareScaleBitmap(Bitmap bitmap, int edgeLength) {
if (null == bitmap || edgeLength <= 0) {
return null;
}
Bitmap result = bitmap.copy(Config.ARGB_8888, true);
int widthOrg = bitmap.getWidth();
int heightOrg = bitmap.getHeight();
int tempWidth = 0;
if (widthOrg < heightOrg) {
tempWidth = widthOrg;
result = Bitmap.createBitmap(result, 0, (heightOrg-widthOrg)/2, tempWidth, tempWidth);
} else if (widthOrg > heightOrg) {
tempWidth = heightOrg;
result = Bitmap.createBitmap(result, (widthOrg - heightOrg)/2, 0, tempWidth, tempWidth);
} else {
//相等 正方形
}
result = Bitmap.createScaledBitmap(result, edgeLength, edgeLength, true);
return result;
}
改变bitmap 透明度
/**
* 改变bitmap 透明度
*
* @param sourceImg
* @param number
* @return
*/
public static Bitmap setTransparentBitmap(Bitmap sourceImg, int number) {
int[] argb = new int[sourceImg.getWidth() * sourceImg.getHeight()];
sourceImg.getPixels(argb, 0, sourceImg.getWidth(), 0, 0, sourceImg
.getWidth(), sourceImg.getHeight());// 获得图片的ARGB值
number = number * 255 / 100;
for (int i = 0; i < argb.length; i++) {
argb[i] = (number << 24) | (argb[i] & 0x00FFFFFF);
}
sourceImg = Bitmap.createBitmap(argb, sourceImg.getWidth(), sourceImg
.getHeight(), Config.ARGB_8888);
return sourceImg;
}
获取圆形Bitmap
/**
* 圆形Bitmap
*
* @param bitmap
* @return
*/
public static Bitmap getRoundedCornerBitmap(Bitmap bitmap) {
Bitmap outBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(outBitmap);
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 = bitmap.getWidth() / 2;
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);
return outBitmap;
}
文件路径或者资源文件获取bitmap对象 给定最大宽高防止内存溢出
// 图片按比例大小压缩方法
public static Bitmap getImageFromPath(String srcPath, int maxWidth, int maxHeight) {
/*if (!isFileAtPath(srcPath)) {
return null;
}*/
try {
BitmapFactory.Options newOpts = new BitmapFactory.Options();
// 开始读入图片,此时把options.inJustDecodeBounds 设回true了
newOpts.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);// 此时返回bm为空
newOpts.inJustDecodeBounds = false;
int w = newOpts.outWidth;
int h = newOpts.outHeight;
LogUtils.i("bSize:newOpts.out.w=" + w + " h=" + h);
float aBili = (float) maxHeight / (float) h;
float bBili = (float) maxWidth / (float) w;
int be = 1;
if (aBili > bBili) {
if (w > maxWidth) {
be = (int) (w / maxWidth);
}
} else {
if (h > maxHeight) {
be = (int) (h / maxHeight);
}
}
if (be <= 1) {//如果是放大,则不放大
be = 1;
}
LogUtils.i("be===" + be);
newOpts.inSampleSize = be;// 设置缩放比例
bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
int bwidth = bitmap.getWidth();
int bheight = bitmap.getHeight();
if (aBili > bBili) {
bitmap = Bitmap.createScaledBitmap(bitmap, maxWidth, (bheight * maxWidth) / bwidth, true);
} else {
bitmap = Bitmap.createScaledBitmap(bitmap, (bwidth * maxHeight) / bheight, maxHeight, true);
}
/*int degree = readPictureDegree(srcPath);
if (degree != 0) {
bitmap = rotaingImageView(degree, bitmap);
}*/
if (bitmap == null) {
LogUtils.i("pic null");
return null;
}
return bitmap;
} catch (Throwable e) {
e.printStackTrace();
return null;
}
}
读取图片属性 旋转的角度
/**
* 读取图片属性:旋转的角度
*
* @param path 图片绝对路径
* @return degree旋转的角度
*/
public static int readPictureDegree(String path) {
int degree = 0;
try {
ExifInterface exifInterface = new ExifInterface(path);
int orientation = exifInterface.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
degree = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
degree = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
degree = 270;
break;
}
} catch (IOException e) {
e.printStackTrace();
}
return degree;
}
保存bitmap为png 当然可以改成其他格式
/**
* 保存图片为JPEG
*
* @param bitmap
* @param path
*/
public static boolean saveJPGE_After(Bitmap bitmap, String path, int quality) {
File file = new File(path);
makeDir(file);
try {
FileOutputStream out = new FileOutputStream(file);
if (bitmap.compress(Bitmap.CompressFormat.JPEG, quality, out)) {
out.flush();
out.close();
}
//更新
context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + path)));
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
Android中Bitmap,byte[],Drawable相互转化
1,Drawable转bitmap:
Resources res = getResources();
Bitmap bmp = BitmapFactory.decodeResource(res, R.drawable.icon);
2,Bitmap → byte[]:
public byte[] Bitmap2Bytes(Bitmap bm) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.PNG, 100, baos);
return baos.toByteArray();
}
3,byte[] → Bitmap:
byte[] b;
BitmapFactory.decodeByteArray(b, 0, b.length);
Bitmap平移,旋转,缩放, 翻转等操作
1 平移:
平移有2种方式:
(1)通过Imageview与Matrix:
Matrix matrix=new Matrix();
int width=bitmap.getWidth();
int height=bitmap.getHeight();
matrix.postTranslate(width, height);
mImageView.setImageMatrix(matrix);
(2)通过Matrix与bitmap:
Matrix matrix=mImageView.getImageMatrix();
int width=bitmap.getWidth();
int height=bitmap.getHeight();
matrix.postTranslate(width, height);
mNewBitmap=Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, false);
mImageView.setImageBitmap(mNewBitmap);
2 旋转:
可以通过matrix.postRotate(rotate, x, y);, 可见Matrix 矩阵的强大,我当时看到这个的时候感受到了数学对于计算机的影响和重要性,第一个参数rotate是旋转的角度,后俩个参数是坐标,围绕哪个坐标来旋转。下面是一个把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);
return resizedBitmap;
}
3 缩放:
进行bitmap的缩放时一定要注意,要进行等比例缩放,如果缩放之后图片变形了就没有了它的意义,下面是我的缩放图片的方法,保持长宽比缩小bitmap:
public static Bitmap resizeBitmap(Bitmap bitmap, int maxWidth, int maxHeight) {
int originWidth = bitmap.getWidth();
int originHeight = bitmap.getHeight();
// no need to resize
if (originWidth < maxWidth && originHeight < maxHeight) {
return bitmap;
}
int width = originWidth;
int height = originHeight;
// 若图片过宽, 则保持长宽比缩放图片
if (originWidth > maxWidth) {
width = maxWidth;
double i = originWidth * 1.0 / maxWidth;
height = (int) Math.floor(originHeight / i);
bitmap = Bitmap.createScaledBitmap(bitmap, width, height, false);
}
// 若图片过长, 则从上端截取
if (height > maxHeight) {
height = maxHeight;
bitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height);
}
return bitmap;
}
4 翻转:
有的时候项目需求要求垂直翻转和水平翻转, sourceBitmap为你要旋转的bitmap
(1)垂直翻转:
Matrix m = new Matrix();
m.postScale(1, -1); //镜像垂直翻转
Bitmap newBitmap = Bitmap.createBitmap(sourceBitmap, 0, 0, sourceBitmap.getWidth(), sourceBitmap.getHeight(), m, true);
(2)水平翻转:
Matrix m = new Matrix();
m.postScale(-1, 1); //镜像水平翻转
Bitmap newBitmap = Bitmap.createBitmap(sourceBitmap, 0, 0, sourceBitmap.getWidth(), sourceBitmap.getHeight(), m, true);
通过bitmap,ColorMatrix改变图片的 亮度,对比度, 饱和度,其中 AppConst.cropperImg为原图
1 改变亮度:
Bitmap brightness_bmp = Bitmap.createBitmap(AppConst.cropperImg.getWidth(), AppConst.cropperImg.getHeight(),
Bitmap.Config.ARGB_8888);
int brightness = 127 - progress;
ColorMatrix brightness_cMatrix = new ColorMatrix();
brightness_cMatrix.set(new float[]{1, 0, 0, 0, brightness, 0, 1,
0, 0, brightness,// 改变亮度
0, 0, 1, 0, brightness, 0, 0, 0, 1, 0});
Paint brightness_paint = new Paint();
Canvas brightness_canvas = new Canvas(brightness_bmp);
brightness_paint.setColorFilter(new ColorMatrixColorFilter(brightness_cMatrix));
// 在Canvas上绘制一个已经存在的Bitmap。这样,dstBitmap就和srcBitmap一摸一样了
brightness_canvas.drawBitmap(AppConst.cropperImg, 0, 0, brightness_paint);
// 将最终图片设置到控件上
beautify_gpuimage.setImage(brightness_bmp);
2 曝光度:
//曝光度
Bitmap contrast_bmp = Bitmap.createBitmap(AppConst.cropperImg.getWidth(), AppConst.cropperImg.getHeight(),
Bitmap.Config.ARGB_8888);
// int brightness = progress - 127;
float contrast = (float) ((progress + 64) / 128.0);
ColorMatrix contrast_cMatrix = new ColorMatrix();
contrast_cMatrix.set(new float[]{contrast, 0, 0, 0, 0, 0,
contrast, 0, 0, 0,// 改变对比度
0, 0, contrast, 0, 0, 0, 0, 0, 1, 0});
Paint contrast_paint = new Paint();
contrast_paint.setColorFilter(new ColorMatrixColorFilter(contrast_cMatrix));
Canvas contrast_canvas = new Canvas(contrast_bmp);
// 在Canvas上绘制一个已经存在的Bitmap。这样,dstBitmap就和srcBitmap一摸一样了
contrast_canvas.drawBitmap(AppConst.cropperImg, 0, 0, contrast_paint);
beautify_gpuimage.setImage(contrast_bmp);
3, 对比度:
//对比度
Bitmap bmp = Bitmap.createBitmap(AppConst.cropperImg.getWidth(), AppConst.cropperImg.getHeight(),
Bitmap.Config.ARGB_8888);
ColorMatrix cMatrix = new ColorMatrix();
// 设置饱和度
cMatrix.setSaturation((float) (progress / 100.0));
Paint paint = new Paint();
paint.setColorFilter(new ColorMatrixColorFilter(cMatrix));
Canvas canvas = new Canvas(bmp);
// 在Canvas上绘制一个已经存在的Bitmap。这样,dstBitmap就和srcBitmap一摸一样了
canvas.drawBitmap(AppConst.cropperImg, 0, 0, paint);
beautify_gpuimage.setImage(bmp);
以上都是在做项目的过程中用到的对图片操作的总结,基本通过Bitmap都可以做到