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; } }