1.介绍
Bitmap,即位图。它本质上就是一张图片的内容在内存中的表达形式
1、Bitmap.Config
Config是Bitmap的一个枚举内部类,它表示的就是每个像素点对ARGB通道值的存储方案。取值有以下四种:
ARGB_8888:这种方案就是上面所说的每个通道值采8bit来表示,每个像素点需要4字节的内存空间来存储数据。该方案图片质量是最高的,但是占用的内存也是最大的
ARGB_4444:这种方案每个通道都是4位,每个像素占用2个字节,图片的失真比较严重。一般不用这种方案。
RGB_565:这种方案RGB通道值分别占5、6、5位,但是没有存储A通道值,所以不支持透明度。每个像素点占用2字节,是ARGB_8888方案的一半。
ALPHA_8:这种方案不支持颜色值,只存储透明度A通道值,使用场景特殊,比如设置遮盖效果等。
比较分析:一般我们在ARGB_8888方式和RGB_565方式中进行选取:不需要设置透明度时,比如拍摄的照片等,RGB_565是个节省内存空间的不错的选择;既要设置透明度,对图片质量要求又高,就用ARGB_8888。
Bitmap工具类
质量压缩
public class BitmapUtil {
/*
* 质量压缩法:将图片文件压缩,压缩是耗时操作
*/
public static void compressFile(CompressFileBean compressFileBean, CompressFileCallback compressFileCallback) {
new CompressFileThread(compressFileBean, compressFileCallback).start();
}
}
/**
* 压缩bitmap的执行线程
*/
private static class CompressFileThread extends Thread {
private Handler handler_deliver = new Handler(Looper.getMainLooper());
private CompressFileBean compressFileBean;
private CompressFileCallback compressFileCallback;
public CompressFileThread(CompressFileBean compressFileBean, CompressFileCallback compressFileCallback) {
this.compressFileBean = compressFileBean;
this.compressFileCallback = compressFileCallback;
}
@Override
public void run() {
super.run();
//将base64转成bitmap
Bitmap bitmap = Base64Utils.base64ToBitmap(compressFileBean.getBase64());
//判断是否要进行图片宽高进行修改缩放
if (compressFileBean.getReqHeight()!=0&&compressFileBean.getReqWidth()!=0){
int height =0;
int weight =0;
if (compressFileBean.getReqHeight()==0){
height =bitmap.getHeight();
}else {
height=compressFileBean.getReqHeight();
}
if (compressFileBean.getReqWidth()==0){
weight =bitmap.getHeight();
}else {
weight=compressFileBean.getReqWidth();
}
bitmap = setImgSize(bitmap,weight, height);
}
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
// 从质量100开始压缩
int quality = 100;
//压缩格式选取JPEG就行了,quality,压缩精度尽量不要低于50,否则影响清晰度
bitmap.compress(Bitmap.CompressFormat.JPEG, quality, byteArrayOutputStream);
//开始循环压缩,当压缩至满足质量或者kb中一条时则不再压缩
while (byteArrayOutputStream.toByteArray().length / 1024 > compressFileBean.getKb_max() && quality > compressFileBean.getQuality_max()) {
// 循环判断如果压缩后图片是否大于kb_max kb,大于继续压缩,
byteArrayOutputStream.reset();
//质量每次减少10
quality -= 10;
bitmap.compress(Bitmap.CompressFormat.JPEG, quality, byteArrayOutputStream);
}
Bitmap finalBitmap = bitmap;
runOnUiThread(new Runnable() {
@Override
public void run() {
//压缩成功
compressFileCallback.onCompressFileFinished(finalBitmap);
}
});
}
private void runOnUiThread(Runnable run) {
handler_deliver.post(run);
}
}
/**
* 期望bitmap的参数的bean
*/
public static class CompressFileBean {
private int kb_max = 200;//压缩到多少KB,不能精确,只能<=kb_max
private int quality_max = 50;//压缩精度,尽量>=50
private int reqWidth;//期望的图片宽度
private int reqHeight ;//期望的图片高度
private String base64;
public String getBase64() {
return base64;
}
public void setBase64(String base64) {
this.base64 = base64;
}
private CompressFileBean(Builder builder) {
this.kb_max = builder.getKb_max();
this.quality_max = builder.getQuality_max();
this.reqWidth = builder.getReqWidth();
this.reqHeight = builder.getReqHeight();
this.base64 = builder.getBase64();
}
public static class Builder {
private int kb_max = 100;//压缩到多少KB,不能精确,只能<=kb_max
private int quality_max = 50;//压缩精度,尽量>=50
private int reqWidth = 100;//期望的图片宽度
private int reqHeight = 100;//期望的图片高度
private String base64;
public String getBase64() {
return base64;
}
public Builder setBase64(String base64) {
this.base64 = base64;
return this;
}
public int getKb_max() {
return kb_max;
}
public Builder setKb_max(int kb_max) {
this.kb_max = kb_max;
return this;
}
public int getQuality_max() {
return quality_max;
}
public Builder setQuality_max(int quality_max) {
this.quality_max = quality_max;
return this;
}
public int getReqWidth() {
return reqWidth;
}
public Builder setReqWidth(int reqWidth) {
this.reqWidth = reqWidth;
return this;
}
public int getReqHeight() {
return reqHeight;
}
public Builder setReqHeight(int reqHeight) {
this.reqHeight = reqHeight;
return this;
}
public CompressFileBean build() {
return new CompressFileBean(this);
}
}
public int getKb_max() {
return kb_max;
}
public int getQuality_max() {
return quality_max;
}
public int getReqWidth() {
return reqWidth;
}
public int getReqHeight() {
return reqHeight;
}
}
/**
* bitmap 压缩回调
*/
public interface CompressFileCallback {
//图片压缩成功
void onCompressFileFinished(Bitmap bitmap);
//图片压缩失败
void onCompressFileFailed(String errorMsg);
}
/**
*
* @param bm bitmap 位图
* @param newWidth 图片宽度
* @param newHeight 图片高度
* @return bitmap 位图
*/
public static Bitmap setImgSize(Bitmap bm, int newWidth, int newHeight) {
// 获得图片的宽高.
int width = bm.getWidth();
int height = bm.getHeight();
// 计算缩放比例.
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);
return newbm;
}
bitmap 和base64互转
/**
* base64转为bitmap
* @param base64Data
* @return
*/
public static Bitmap base64ToBitmap(String base64Data) {
byte[] bytes = Base64.decode(base64Data, Base64.DEFAULT);
return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
}
/**
* bitmap转为base64 如果转JPEG后有黑底的话,可以尝试转PNG
* @param bitmap
* @param format bitmap转byte的图片类型 Bitmap.CompressFormat.JPEG PNG WEBP 三种
* @return
*/
public static String bitmapToBase64(Bitmap bitmap, Bitmap.CompressFormat format) {
String result = null;
ByteArrayOutputStream baos = null;
try {
if (bitmap != null) {
baos = new ByteArrayOutputStream();
bitmap.compress(format, 100, baos);
baos.flush();
baos.close();
byte[] bitmapBytes = baos.toByteArray();
result = Base64.encodeToString(bitmapBytes, Base64.DEFAULT);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (baos != null) {
baos.flush();
baos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
}
其他
/**
* 对View进行量测,布局后截图
*
* @param view
* @return
*/
public static Bitmap captureViewToBitmap(View view, int reqWidth, int reqHeight) {
view.layout(0, 0, reqWidth, reqHeight);
Bitmap bitmap = Bitmap.createBitmap(reqWidth, reqHeight, Bitmap.Config.RGB_565);
Canvas canvas = new Canvas(bitmap);
view.draw(canvas);
return bitmap;
}
/**
* 将图片按照某个角度进行旋转
*
* @param bm 需要旋转的图片
* @param degree 旋转角度
* @return 旋转后的图片
*/
public static Bitmap rotateBitmapByDegree(Bitmap bm, int degree) {
Bitmap returnBm = null;
// 根据旋转角度,生成旋转矩阵
Matrix matrix = new Matrix();
matrix.postRotate(degree);
try {
// 将原始图片按照旋转矩阵进行旋转,并得到新的图片
returnBm = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true);
} catch (OutOfMemoryError e) {
}
if (returnBm == null) {
returnBm = bm;
}
if (bm != returnBm) {
bm.recycle();
}
return returnBm;
}
/**
* 裁剪
*
* @param bitmap 原图
* @return 裁剪后的图像
*/
public static Bitmap cropBitmap(Bitmap bitmap, float hRatioW) {
int w = bitmap.getWidth(); // 得到图片的宽,高
int h = bitmap.getHeight();
return Bitmap.createBitmap(bitmap, 0, 0, w, (int) (w * hRatioW), null, false);
}
/**
* 按比例缩放图片
*
* @param origin 原图
* @param ratio 比例
* @return 新的bitmap
*/
public static Bitmap scaleBitmap(Bitmap origin, float ratio) {
if (origin == null) {
return null;
}
int width = origin.getWidth();
int height = origin.getHeight();
Matrix matrix = new Matrix();
matrix.preScale(ratio, ratio);
Bitmap newBM = Bitmap.createBitmap(origin, 0, 0, width, height, matrix, false);
return newBM;
}