public class BitmapUtil {
/**
* 质量压缩 (仅仅在文件存储的时候使用此压缩即可,否则没有任何作用)
* <p>
* 此压缩,只针对文件存储或者文件传输,在内存中,大小是不会改变的
* 如果想要不崩溃,还是得进行尺寸的压缩,真正的缩小内存占用
*
* @param image
* @param maxSize 压缩的大小 单位kb
* @return
*/
public static ByteArrayOutputStream compressQuality(Bitmap image, int maxSize) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 100, baos);// 质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
int options = 90;
while (baos.toByteArray().length / 1024 > maxSize) { // 循环判断如果压缩后图片是否大于maxSize kb,大于继续压缩
baos.reset(); // 重置baos即清空baos
image.compress(Bitmap.CompressFormat.JPEG, options, baos);// 这里压缩options%,把压缩后的数据存放到baos中
options -= 10;// 每次都减少10
if (options <= 0) {
break;
}
}
// ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());// 把压缩后的数据baos存放到ByteArrayInputStream中
return baos;
}
/**
* 尺寸压缩
* 默认压缩宽高 480 * 800
*
* @param srcPath
* @return
*/
public static Bitmap compressSize(String srcPath) {
return compressSize(srcPath, 480f, 800f);
}
/**
* 尺寸压缩
* 图片按比例
* 如果是从file中读取图片,加载到内存,然后显示,小图无所谓,大图,最好调用此方法,压缩一下,避免oom
*
* @param srcPath (根据路径获取图片并压缩)
* @return
*/
public static Bitmap compressSize(String srcPath, float pixelW, float pixelH) {
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;
float hh = pixelH;
float ww = pixelW;
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了
bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
return bitmap;
}
/**
* 截取webView快照(webView加载的整个内容的大小)
*
* @param webView
* @return
*/
public static Bitmap captureWebView(WebView webView) {
//获取Picture对象
Picture snapShot = webView.capturePicture();
//得到图片的宽和高(没有reflect图片内容)
int width = snapShot.getWidth();
int height = snapShot.getHeight();
if (width > 0 && height > 0) {
//创建位图
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
//绘制(会调用native方法,完成图形绘制)
snapShot.draw(canvas);
return bitmap;
}
return null;
}
/**
* 保存Bitmap至本地固定位置
* 先质量压缩一下,这样file文件会变小
* 默认 128kb
*
* @param bitmap
* @param fileName
* @param isCover 如果文件存在,是否覆盖
* @return 文件路径
*/
public static String saveBitmapToAppDir(Bitmap bitmap, String fileName, boolean isCover) {
File f = null;
try {
f = new File(FileUtils.getPictureAppDir(), fileName);
if (f.exists() && !isCover) {
LogUtil.e(f.getName() + "已经存在");
return f.getAbsolutePath();
} else {
if (!f.exists() && !f.createNewFile()) {
LogUtil.e(fileName + "创建失败!");
} else {
//将bitmap质量压缩,
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);// 质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
int options = 90;
while (baos.toByteArray().length / 1024 > 128) { // 循环判断如果压缩后图片是否大于maxSize kb,大于继续压缩
baos.reset(); // 重置baos即清空baos
bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);// 这里压缩options%,把压缩后的数据存放到baos中
options -= 10;// 每次都减少10
if (options <= 0) {
break;
}
}
FileOutputStream fOut = null;
fOut = new FileOutputStream(f);
fOut.write(baos.toByteArray());
fOut.flush();
fOut.close();
}
}
} catch (Exception e) {
e.printStackTrace();
}
return f == null ? null : f.getAbsolutePath();
}
/**
* 保存Bitmap至本地固定位置 png格式,比较慢
* 先质量压缩一下,这样file文件会变小
* 默认 128kb
*
* @param bitmap
* @param fileName
* @param isCover 如果文件存在,是否覆盖
* @return 文件路径
*/
public static String saveBitmapToAppDirByPng(Bitmap bitmap, String fileName, boolean isCover) {
File f = null;
try {
f = new File(FileUtils.getPictureAppDir(), fileName);
if (f.exists() && !isCover) {
LogUtil.e(f.getName() + "已经存在");
return f.getAbsolutePath();
} else {
if (!f.exists() && !f.createNewFile()) {
LogUtil.e(fileName + "创建失败!");
} else {
//将bitmap质量压缩,
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);// 质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
int options = 90;
while (baos.toByteArray().length / 1024 > 128) { // 循环判断如果压缩后图片是否大于maxSize kb,大于继续压缩
baos.reset(); // 重置baos即清空baos
bitmap.compress(Bitmap.CompressFormat.PNG, options, baos);// 这里压缩options%,把压缩后的数据存放到baos中
options -= 10;// 每次都减少10
if (options <= 0) {
break;
}
}
FileOutputStream fOut = null;
fOut = new FileOutputStream(f);
fOut.write(baos.toByteArray());
fOut.flush();
fOut.close();
}
}
} catch (Exception e) {
e.printStackTrace();
}
return f == null ? null : f.getAbsolutePath();
}
public static String saveBitmapToPhoneDir(Context context, String src, String fileName) {
return saveBitmapToPhoneDir(context, BitmapFactory.decodeFile(src), fileName);
}
/**
* 保存Bitmap至本地固定位置
*
* @param bitmap
*/
public static String saveBitmapToPhoneDir(Context context, Bitmap bitmap, String fileName) {
File f = null;
try {
f = new File(FileUtils.getPicturePhoneDir(), System.currentTimeMillis() + fileName);
//将bitmap质量压缩,
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);// 质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
int options = 90;
while (baos.toByteArray().length / 1024 > 128) { // 循环判断如果压缩后图片是否大于maxSize kb,大于继续压缩
baos.reset(); // 重置baos即清空baos
bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);// 这里压缩options%,把压缩后的数据存放到baos中
options -= 10;// 每次都减少10
if (options <= 0) {
break;
}
}
FileOutputStream fOut = null;
fOut = new FileOutputStream(f);
fOut.write(baos.toByteArray());
fOut.flush();
fOut.close();
} catch (Exception e) {
e.printStackTrace();
}
if (f != null) {
context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + f.getAbsolutePath())));
return f.getAbsolutePath();
} else {
return null;
}
}
/**
* 把两个位图覆盖合成为一个位图,上下拼接
*
* @param topBitmap
* @param bottomBitmap
* @param isBaseMax 是否以宽度大的位图为准,true则小图等比拉伸,false则大图等比压缩
* @return
*/
public static Bitmap mergeBitmap_TB(Bitmap topBitmap, Bitmap bottomBitmap, boolean isBaseMax) {
if (topBitmap == null || topBitmap.isRecycled()
|| bottomBitmap == null || bottomBitmap.isRecycled()) {
LogUtil.e("topBitmap=" + topBitmap + ";bottomBitmap=" + bottomBitmap);
return null;
}
int width = 0;
if (isBaseMax) {
width = topBitmap.getWidth() > bottomBitmap.getWidth() ? topBitmap.getWidth() : bottomBitmap.getWidth();
} else {
width = topBitmap.getWidth() < bottomBitmap.getWidth() ? topBitmap.getWidth() : bottomBitmap.getWidth();
}
Bitmap tempBitmapT = topBitmap;
Bitmap tempBitmapB = bottomBitmap;
if (topBitmap.getWidth() != width) {
tempBitmapT = Bitmap.createScaledBitmap(topBitmap, width, (int) (topBitmap.getHeight() * 1f / topBitmap.getWidth() * width), false);
} else if (bottomBitmap.getWidth() != width) {
tempBitmapB = Bitmap.createScaledBitmap(bottomBitmap, width, (int) (bottomBitmap.getHeight() * 1f / bottomBitmap.getWidth() * width), false);
}
int height = tempBitmapT.getHeight() + tempBitmapB.getHeight();
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Rect topRect = new Rect(0, 0, tempBitmapT.getWidth(), tempBitmapT.getHeight());
Rect bottomRect = new Rect(0, 0, tempBitmapB.getWidth(), tempBitmapB.getHeight());
Rect bottomRectT = new Rect(0, tempBitmapT.getHeight(), width, height);
canvas.drawBitmap(tempBitmapT, topRect, topRect, null);
canvas.drawBitmap(tempBitmapB, bottomRect, bottomRectT, null);
return bitmap;
}
/**
* 把两个位图覆盖合成为一个位图,左右拼接
*
* @param leftBitmap
* @param rightBitmap
* @param isBaseMax 是否以宽度大的位图为准,true则小图等比拉伸,false则大图等比压缩
* @return
*/
public static Bitmap mergeBitmap_LR(Bitmap leftBitmap, Bitmap rightBitmap, boolean isBaseMax) {
if (leftBitmap == null || leftBitmap.isRecycled()
|| rightBitmap == null || rightBitmap.isRecycled()) {
LogUtil.e("leftBitmap=" + leftBitmap + ";rightBitmap=" + rightBitmap);
return null;
}
int height = 0; // 拼接后的高度,按照参数取大或取小
if (isBaseMax) {
height = leftBitmap.getHeight() > rightBitmap.getHeight() ? leftBitmap.getHeight() : rightBitmap.getHeight();
} else {
height = leftBitmap.getHeight() < rightBitmap.getHeight() ? leftBitmap.getHeight() : rightBitmap.getHeight();
}
// 缩放之后的bitmap
Bitmap tempBitmapL = leftBitmap;
Bitmap tempBitmapR = rightBitmap;
if (leftBitmap.getHeight() != height) {
tempBitmapL = Bitmap.createScaledBitmap(leftBitmap, (int) (leftBitmap.getWidth() * 1f / leftBitmap.getHeight() * height), height, false);
} else if (rightBitmap.getHeight() != height) {
tempBitmapR = Bitmap.createScaledBitmap(rightBitmap, (int) (rightBitmap.getWidth() * 1f / rightBitmap.getHeight() * height), height, false);
}
// 拼接后的宽度
int width = tempBitmapL.getWidth() + tempBitmapR.getWidth();
// 定义输出的bitmap
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
// 缩放后两个bitmap需要绘制的参数
Rect leftRect = new Rect(0, 0, tempBitmapL.getWidth(), tempBitmapL.getHeight());
Rect rightRect = new Rect(0, 0, tempBitmapR.getWidth(), tempBitmapR.getHeight());
// 右边图需要绘制的位置,往右边偏移左边图的宽度,高度是相同的
Rect rightRectT = new Rect(tempBitmapL.getWidth(), 0, width, height);
canvas.drawBitmap(tempBitmapL, leftRect, leftRect, null);
canvas.drawBitmap(tempBitmapR, rightRect, rightRectT, null);
return bitmap;
}
/**
* 把两个位图覆盖合成为一个位图,以底层位图的长宽为基准
*
* @param backBitmap 在底部的位图
* @param frontBitmap 盖在上面的位图
* @return
*/
public static Bitmap mergeBitmap(Bitmap backBitmap, Bitmap frontBitmap, Bitmap bitmap2) {
if (backBitmap == null || backBitmap.isRecycled()
|| frontBitmap == null || frontBitmap.isRecycled()) {
LogUtil.e("backBitmap=" + backBitmap + ";frontBitmap=" + frontBitmap);
return null;
}
Bitmap bitmap = backBitmap.copy(Bitmap.Config.ARGB_8888, true);
Canvas canvas = new Canvas(bitmap);
//根据需要,调整位置
Rect baseRect = new Rect(0, backBitmap.getHeight() - frontBitmap.getHeight() * 5 + DensityUtil.dip2px(100), backBitmap.getWidth(), backBitmap.getHeight() - frontBitmap.getHeight() * 4 + DensityUtil.dip2px(100));
Rect frontRect = new Rect(0, 0, frontBitmap.getWidth(), frontBitmap.getHeight());
canvas.drawBitmap(frontBitmap, frontRect, baseRect, null);
//根据需要,调整位置
Rect baseRect2 = new Rect(backBitmap.getWidth() - DensityUtil.dip2px(172), DensityUtil.dip2px(258), backBitmap.getWidth() - DensityUtil.dip2px(52), DensityUtil.dip2px(258) + bitmap2.getHeight());
Rect frontRect2 = new Rect(0, 0, bitmap2.getWidth(), bitmap2.getHeight());
canvas.drawBitmap(bitmap2, frontRect2, baseRect2, null);
return bitmap;
}
/**
* 在图片右下角添加水印
*
* @param srcBMP 原图
* @param markBMP 水印图片
* @return 合成水印后的图片
*/
public static Bitmap composeWatermark(Bitmap srcBMP, Bitmap markBMP) {
if (srcBMP == null) {
return null;
}
// 创建一个新的和SRC长度宽度一样的位图
Bitmap newb = Bitmap.createBitmap(srcBMP.getWidth(),
srcBMP.getHeight(), Bitmap.Config.ARGB_8888);
Canvas cv = new Canvas(newb);
// 在 0,0坐标开始画入原图
cv.drawBitmap(srcBMP, 0, 0, null);
// 在原图的右下角画入水印
cv.drawBitmap(markBMP, srcBMP.getWidth() - markBMP.getWidth() * 4 / 5,
srcBMP.getHeight() * 2 / 7, null);
// 保存
cv.save(Canvas.ALL_SAVE_FLAG);
// 存储
cv.restore();
return newb;
}
/**
* 给图片添加加背景
*/
public static Bitmap addBg(Bitmap foreground, Bitmap background) {
int bgWidth = background.getWidth();
int bgHeight = background.getHeight();
int fgWidth = foreground.getWidth();
int fgHeight = foreground.getHeight();
Bitmap newmap = Bitmap
.createBitmap(bgWidth, bgHeight, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(newmap);
canvas.drawBitmap(background, 0, 0, null);
canvas.drawBitmap(foreground, (bgWidth - fgWidth) / 2,
(bgHeight - fgHeight) * 3 / 5 + 70, null);
canvas.save(Canvas.ALL_SAVE_FLAG);
canvas.restore();
return newmap;
}
//通过网络地址url获取bitmap
public static Bitmap getBitmapByUrl(String url) {
return getBitmapByUrl(url, R.drawable.ic_launcher_background);
}
public static Bitmap getBitmapByUrl(String url, int defaultId) {
Bitmap bitmap = null;
try {
bitmap = BitmapFactory.decodeStream(new URL(url).openStream());
} catch (Exception e) {
LogUtil.e("URL------>error");
} finally {
if (bitmap == null && defaultId != -1) {
bitmap = BitmapFactory.decodeResource(
BaseApplication.getContext().getResources(), defaultId);
}
return bitmap;
}
}
/**
* 根据给定的宽和高进行拉伸
*
* @param origin 原图
* @param newWidth 新图的宽
* @param newHeight 新图的高
* @return new Bitmap
*/
private Bitmap scaleBitmap(Bitmap origin, int newWidth, int newHeight) {
if (origin == null) {
return null;
}
int height = origin.getHeight();
int width = origin.getWidth();
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);// 使用后乘
Bitmap newBM = Bitmap.createBitmap(origin, 0, 0, width, height, matrix, false);
if (!origin.isRecycled()) {
origin.recycle();
}
return newBM;
}
/**
* 按比例缩放图片
*
* @param origin 原图
* @param ratio 比例
* @return 新的bitmap
*/
private 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);
if (newBM.equals(origin)) {
return newBM;
}
origin.recycle();
return newBM;
}
/**
* 裁剪
*
* @param bitmap 原图
* @return 裁剪后的图像
*/
private Bitmap cropBitmap(Bitmap bitmap) {
int w = bitmap.getWidth(); // 得到图片的宽,高
int h = bitmap.getHeight();
int cropWidth = w >= h ? h : w;// 裁切后所取的正方形区域边长
cropWidth /= 2;
int cropHeight = (int) (cropWidth / 1.2);
return Bitmap.createBitmap(bitmap, w / 3, 0, cropWidth, cropHeight, null, false);
}
/**
* 选择变换
*
* @param origin 原图
* @param alpha 旋转角度,可正可负
* @return 旋转后的图片
*/
private Bitmap rotateBitmap(Bitmap origin, float alpha) {
if (origin == null) {
return null;
}
int width = origin.getWidth();
int height = origin.getHeight();
Matrix matrix = new Matrix();
matrix.setRotate(alpha);
// 围绕原地进行旋转
Bitmap newBM = Bitmap.createBitmap(origin, 0, 0, width, height, matrix, false);
if (newBM.equals(origin)) {
return newBM;
}
origin.recycle();
return newBM;
}
/**
* 偏移效果
* @param origin 原图
* @return 偏移后的bitmap
*/
private Bitmap skewBitmap(Bitmap origin) {
if (origin == null) {
return null;
}
int width = origin.getWidth();
int height = origin.getHeight();
Matrix matrix = new Matrix();
matrix.postSkew(-0.6f, -0.3f);
Bitmap newBM = Bitmap.createBitmap(origin, 0, 0, width, height, matrix, false);
if (newBM.equals(origin)) {
return newBM;
}
origin.recycle();
return newBM;
}
/**
* 注意这是一个耗时的操作需要异步处理
*
* @param imageUri 通过URL得到 Bitmap
* @return
*/
public static Bitmap getBitmap(String imageUri) {
// 显示网络上的图片
Bitmap bitmap = null;
try {
URL myFileUrl = new URL(imageUri);
HttpURLConnection conn = (HttpURLConnection) myFileUrl
.openConnection();
conn.setDoInput(true);
conn.connect();
InputStream is = conn.getInputStream();
bitmap = BitmapFactory.decodeStream(is);
is.close();
Log.v(TAG, "image download finished." + imageUri);
} catch (OutOfMemoryError e) {
e.printStackTrace();
bitmap = null;
} catch (IOException e) {
e.printStackTrace();
Log.v(TAG, "getbitmap bmp fail---");
bitmap = null;
}
return bitmap;
}
}
操作Bitmap的一些工具类
最新推荐文章于 2023-06-01 15:03:08 发布