358 lines
12 KiB
Java
358 lines
12 KiB
Java
package com.gh.common.util;
|
||
|
||
import android.content.Context;
|
||
import android.graphics.Bitmap;
|
||
import android.graphics.BitmapFactory;
|
||
import android.graphics.Canvas;
|
||
import android.graphics.Matrix;
|
||
import android.graphics.PixelFormat;
|
||
import android.graphics.drawable.Drawable;
|
||
import android.media.ExifInterface;
|
||
import android.os.Build;
|
||
|
||
import com.halo.assistant.HaloApp;
|
||
|
||
import java.io.BufferedOutputStream;
|
||
import java.io.ByteArrayOutputStream;
|
||
import java.io.File;
|
||
import java.io.FileNotFoundException;
|
||
import java.io.FileOutputStream;
|
||
import java.io.IOException;
|
||
|
||
import androidx.annotation.IntRange;
|
||
import androidx.annotation.RequiresApi;
|
||
import androidx.renderscript.Allocation;
|
||
import androidx.renderscript.Element;
|
||
import androidx.renderscript.RenderScript;
|
||
import androidx.renderscript.ScriptIntrinsicBlur;
|
||
|
||
/**
|
||
* Created by LGT on 2016/10/21.
|
||
*/
|
||
public class BitmapUtils {
|
||
|
||
/**
|
||
* 保存图片
|
||
*
|
||
* @param newPath
|
||
* @param filePath
|
||
* @return
|
||
*/
|
||
public static boolean savePicture(String newPath, String filePath) {
|
||
BitmapFactory.Options options = new BitmapFactory.Options();
|
||
options.inJustDecodeBounds = true;
|
||
BitmapFactory.decodeFile(filePath, options);
|
||
options.inSampleSize = 2;
|
||
options.inJustDecodeBounds = false;
|
||
|
||
File file = new File(newPath);
|
||
int quality = 80;
|
||
do {
|
||
try {
|
||
Bitmap bitmap = BitmapFactory.decodeFile(filePath, options);
|
||
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
|
||
bitmap.compress(Bitmap.CompressFormat.JPEG, quality, bos);
|
||
bos.flush();
|
||
bos.close();
|
||
} catch (IOException e) {
|
||
file.delete();
|
||
e.printStackTrace();
|
||
return false;
|
||
}
|
||
quality -= 10;
|
||
if (quality < 10) {
|
||
quality = 10;
|
||
}
|
||
} while (file.length() > 81920 && quality > 10);
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* 保存图片
|
||
*
|
||
* @param newPath
|
||
* @param filePath
|
||
* @return
|
||
*/
|
||
public static boolean savePicture(String newPath, String filePath, int compressSize) {
|
||
if (compressSize > new File(filePath).length()) {
|
||
return false;
|
||
}
|
||
|
||
BitmapFactory.Options options = new BitmapFactory.Options();
|
||
options.inJustDecodeBounds = true;
|
||
BitmapFactory.decodeFile(filePath, options);
|
||
options.inSampleSize = 2;
|
||
options.inJustDecodeBounds = false;
|
||
|
||
Bitmap bitmap = BitmapFactory.decodeFile(filePath, options);
|
||
|
||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||
bitmap.compress(Bitmap.CompressFormat.JPEG, 85, bos);
|
||
float zoom = (float) Math.sqrt(compressSize / (float) bos.toByteArray().length);
|
||
|
||
Matrix matrix = new Matrix();
|
||
matrix.setScale(zoom, zoom);
|
||
Bitmap result = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
|
||
bos.reset();
|
||
bitmap.recycle();
|
||
|
||
result.compress(Bitmap.CompressFormat.JPEG, 85, bos);
|
||
while (bos.toByteArray().length > compressSize) {
|
||
matrix.setScale(0.9f, 0.9f);
|
||
|
||
result = Bitmap.createBitmap(result, 0, 0, result.getWidth(), result.getHeight(), matrix, true);
|
||
bos.reset();
|
||
result.compress(Bitmap.CompressFormat.JPEG, 85, bos);
|
||
}
|
||
|
||
File file = new File(newPath);
|
||
try {
|
||
BufferedOutputStream fbos = new BufferedOutputStream(new FileOutputStream(file));
|
||
result.compress(Bitmap.CompressFormat.JPEG, 85, fbos);
|
||
fbos.flush();
|
||
fbos.close();
|
||
|
||
result.recycle();
|
||
} catch (Exception e) {
|
||
file.delete();
|
||
e.printStackTrace();
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
public static Bitmap getBitmapByFile(String filepath, int w, int h) {
|
||
return getBitmapByFile(filepath, w, h, Bitmap.Config.RGB_565);
|
||
}
|
||
|
||
public static Bitmap getBitmapByFile(String filepath, Bitmap.Config config) {
|
||
return getBitmapByFile(filepath, 0, 0, config);
|
||
}
|
||
|
||
/**
|
||
* 根据文件路径返回bitmap
|
||
*
|
||
* @param filepath 文件路径
|
||
* @param w 宽
|
||
* @param h 高
|
||
* @return bitmap
|
||
*/
|
||
public static Bitmap getBitmapByFile(String filepath, int w, int h, Bitmap.Config config) {
|
||
try {
|
||
BitmapFactory.Options options = new BitmapFactory.Options();
|
||
// 设置为ture只获取图片大小
|
||
options.inJustDecodeBounds = true;
|
||
options.inPreferredConfig = config;
|
||
// 返回为空
|
||
BitmapFactory.decodeFile(filepath, options);
|
||
int width = options.outWidth;
|
||
int height = options.outHeight;
|
||
float scaleWidth = 0.f, scaleHeight = 0.f;
|
||
if (width > w || height > h) {
|
||
// 缩放
|
||
if (w > 0) scaleWidth = ((float) width) / w;
|
||
if (h > 0) scaleHeight = ((float) height) / h;
|
||
}
|
||
options.inJustDecodeBounds = false;
|
||
int scale = (int) Math.ceil(Math.max(scaleWidth, scaleHeight));
|
||
if (scale % 2 == 1) {
|
||
scale += 1;
|
||
}
|
||
options.inSampleSize = scale;
|
||
Bitmap bitmap = BitmapFactory.decodeFile(filepath, options);
|
||
bitmap = rotatePicture(filepath, bitmap);
|
||
if (bitmap != null) {
|
||
return bitmap;
|
||
}
|
||
return null;
|
||
} catch (Exception e) {
|
||
e.printStackTrace();
|
||
return null;
|
||
}
|
||
}
|
||
|
||
public static Bitmap rotatePicture(String path, Bitmap bitmap) {
|
||
int rotate = 0;
|
||
try {
|
||
ExifInterface exifInterface = new ExifInterface(path);
|
||
int orientation = exifInterface.getAttributeInt(
|
||
ExifInterface.TAG_ORIENTATION,
|
||
ExifInterface.ORIENTATION_NORMAL);
|
||
switch (orientation) {
|
||
case ExifInterface.ORIENTATION_ROTATE_90:
|
||
rotate = 90;
|
||
break;
|
||
case ExifInterface.ORIENTATION_ROTATE_180:
|
||
rotate = 180;
|
||
break;
|
||
case ExifInterface.ORIENTATION_ROTATE_270:
|
||
rotate = 270;
|
||
break;
|
||
}
|
||
} catch (IOException e) {
|
||
e.printStackTrace();
|
||
}
|
||
if (rotate != 0) {
|
||
Matrix matrix = new Matrix();
|
||
matrix.setRotate(rotate);
|
||
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
|
||
bitmap.getHeight(), matrix, true);
|
||
} else {
|
||
return bitmap;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Drawable转Bitmap
|
||
*
|
||
* @param isSquare 是否是正方形
|
||
*/
|
||
public static Bitmap drawableToBitmap(Drawable drawable, boolean isSquare) {
|
||
if (drawable == null) {
|
||
return null;
|
||
}
|
||
|
||
int w, h;
|
||
|
||
// 取 drawable 的长宽
|
||
w = drawable.getIntrinsicWidth();
|
||
h = drawable.getIntrinsicHeight();
|
||
|
||
// 在低于 5.1 和运行内存小于 2G 的设备上减小图片大小,避免 OOM,128 * 128 又不是不能看
|
||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP
|
||
|| DeviceUtils.getTotalRamSizeOfDevice(HaloApp.getInstance().getApplication()) < 2000) {
|
||
if (isSquare) {
|
||
w = w > 128 ? 128 : w;
|
||
h = h > 128 ? 128 : h;
|
||
} else {
|
||
w = w > 128 ? w / 2 : w;
|
||
h = h > 128 ? h / 2 : h;
|
||
}
|
||
}
|
||
// 取 drawable 的颜色格式
|
||
Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
|
||
: Bitmap.Config.RGB_565;
|
||
//建立对应的Bitmap
|
||
Bitmap bitmap = Bitmap.createBitmap(w, h, config);
|
||
// 建立对应 bitmap 的画布
|
||
Canvas canvas = new Canvas(bitmap);
|
||
drawable.setBounds(0, 0, w, h);
|
||
// 把 drawable 内容画到画布中
|
||
drawable.draw(canvas);
|
||
|
||
return bitmap;
|
||
}
|
||
|
||
/**
|
||
* 修改bitmap透明度
|
||
*
|
||
* @param sourceImg
|
||
* @param config
|
||
* @param number
|
||
* @return
|
||
*/
|
||
public static Bitmap getTransparentBitmap(Bitmap sourceImg, Bitmap.Config config, 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);
|
||
return sourceImg;
|
||
}
|
||
|
||
|
||
/**
|
||
* 高斯模糊
|
||
*
|
||
* @param context
|
||
* @param image
|
||
* @param radius
|
||
* @return
|
||
*/
|
||
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
|
||
public static Bitmap getBlurBitmap(Context context, Bitmap image, @IntRange(from = 1, to = 25) int radius) {
|
||
// 计算图片缩小后的长宽
|
||
int width = Math.round(image.getWidth() * 0.8f);
|
||
int height = Math.round(image.getHeight() * 0.8f);
|
||
|
||
// 将缩小后的图片做为预渲染的图片。
|
||
Bitmap inputBitmap = Bitmap.createScaledBitmap(image, width, height, false);
|
||
// 创建一张渲染后的输出图片。
|
||
Bitmap outputBitmap = Bitmap.createBitmap(inputBitmap);
|
||
// 创建RenderScript内核对象
|
||
RenderScript rs = RenderScript.create(context);
|
||
// 创建一个模糊效果的RenderScript的工具对象
|
||
ScriptIntrinsicBlur blurScript = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
|
||
|
||
// 由于RenderScript并没有使用VM来分配内存,所以需要使用Allocation类来创建和分配内存空间。
|
||
// 创建Allocation对象的时候其实内存是空的,需要使用copyTo()将数据填充进去。
|
||
Allocation tmpIn = Allocation.createFromBitmap(rs, inputBitmap);
|
||
Allocation tmpOut = Allocation.createTyped(rs, tmpIn.getType());
|
||
// 设置渲染的模糊程度, 25f是最大模糊度
|
||
blurScript.setRadius(radius);
|
||
// 设置blurScript对象的输入内存
|
||
blurScript.setInput(tmpIn);
|
||
// 将输出数据保存到输出内存中
|
||
blurScript.forEach(tmpOut);
|
||
|
||
// 将数据填充到Allocation中
|
||
tmpOut.copyTo(outputBitmap);
|
||
|
||
return outputBitmap;
|
||
}
|
||
|
||
/**
|
||
* 保存图片
|
||
*
|
||
* @param bitmap
|
||
* @param path
|
||
*/
|
||
public static void saveBitmap(Bitmap bitmap, String path) {
|
||
File file = new File(path);
|
||
if (file.exists()) {
|
||
file.delete();
|
||
}
|
||
FileOutputStream out;
|
||
try {
|
||
out = new FileOutputStream(file);
|
||
if (bitmap.compress(Bitmap.CompressFormat.PNG, 80, out)) {
|
||
out.flush();
|
||
out.close();
|
||
}
|
||
} catch (FileNotFoundException e) {
|
||
e.printStackTrace();
|
||
} catch (IOException e) {
|
||
e.printStackTrace();
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* 压缩图片
|
||
*
|
||
* @param bitmap
|
||
* @param compressSize 压缩大小(单位k)
|
||
*/
|
||
public static Bitmap compressBitmap(Bitmap bitmap, int compressSize) {
|
||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||
Matrix matrix = new Matrix();
|
||
Bitmap result = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
|
||
result.compress(Bitmap.CompressFormat.WEBP, 100, bos);
|
||
|
||
while (bos.toByteArray().length > compressSize * 1024) {
|
||
matrix.setScale(0.9f, 0.9f);
|
||
result = Bitmap.createBitmap(result, 0, 0, result.getWidth(), result.getHeight(), matrix, true);
|
||
bos.reset();
|
||
result.compress(Bitmap.CompressFormat.WEBP, 100, bos);
|
||
}
|
||
|
||
return result;
|
||
}
|
||
}
|