1.工具类BitmapUtils
public class BitmapUtils {public static Bitmap mirror(Bitmap rawBitmap) {Matrix matrix = new Matrix();matrix.postScale(-1f, 1f);return Bitmap.createBitmap(rawBitmap, 0, 0, rawBitmap.getWidth(), rawBitmap.getHeight(), matrix, true);}public static Bitmap rotateBitmap(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;}/*** 将bitmap转换成bytes*/public static byte[] bitmapToBytes(Bitmap bitmap, int quality) {if (bitmap == null) {return null;}int size = bitmap.getWidth() * bitmap.getHeight() * 4;ByteArrayOutputStream out = new ByteArrayOutputStream(size);try {bitmap.compress(Bitmap.CompressFormat.JPEG, quality, out);out.flush();out.close();return out.toByteArray();} catch (IOException e) {return null;}}/*** 将图片保存到磁盘中** @param bitmap* @param file 图片保存目录——不包含图片名* @param path 图片保存文件路径——包含图片名* @return*/public static boolean saveBitmap(Bitmap bitmap, File file, File path) {boolean success = false;byte[] bytes = bitmapToBytes(bitmap, 100);OutputStream out = null;try {if (!file.exists() && file.isDirectory()) {file.mkdirs();}out = new FileOutputStream(path);out.write(bytes);out.flush();success = true;} catch (Exception e) {e.printStackTrace();} finally {if (out != null) {try {out.close();} catch (IOException e) {e.printStackTrace();}}}return success;}/*** 高级图片质量压缩** @param bitmap 位图* @param width 压缩后的宽度,单位像素*/public static Bitmap imageZoom(Bitmap bitmap, double width) {// 将bitmap放至数组中,意在获得bitmap的大小(与实际读取的原文件要大)ByteArrayOutputStream baos = new ByteArrayOutputStream();// 格式、质量、输出流bitmap.compress(Bitmap.CompressFormat.JPEG, 80, baos);byte[] b = baos.toByteArray();Bitmap newBitmap = BitmapFactory.decodeByteArray(b, 0, b.length);// 获取bitmap大小 是允许最大大小的多少倍return scaleWithWH(newBitmap, width,width * newBitmap.getHeight() / newBitmap.getWidth());}/**** 图片缩放*@param bitmap 位图* @param w 新的宽度* @param h 新的高度* @return Bitmap*/public static Bitmap scaleWithWH(Bitmap bitmap, double w, double h) {if (w == 0 || h == 0 || bitmap == null) {return bitmap;} else {int width = bitmap.getWidth();int height = bitmap.getHeight();Matrix matrix = new Matrix();float scaleWidth = (float) (w / width);float scaleHeight = (float) (h / height);matrix.postScale(scaleWidth, scaleHeight);return Bitmap.createBitmap(bitmap, 0, 0, width, height,matrix, true);}}/*** bitmap保存到指定路径** @param file 图片的绝对路径* @param file 位图* @return bitmap*/public static boolean saveFile(String file, Bitmap bmp) {if (TextUtils.isEmpty(file) || bmp == null) return false;File f = new File(file);if (f.exists()) {f.delete();} else {File p = f.getParentFile();if (!p.exists()) {p.mkdirs();}}try {FileOutputStream out = new FileOutputStream(f);bmp.compress(Bitmap.CompressFormat.JPEG, 100, out);out.flush();out.close();} catch (IOException e) {e.printStackTrace();return false;}return true;}/*** 保存bitmap到SD卡,请确认应用有存储权限** @param bmp 获取的bitmap数据* @param picName 自定义的图片名*/public static File saveBmp2Gallery(Context context, String fileSavePath, Bitmap bmp, String picName) {File galleryPath = new File(fileSavePath);if (!galleryPath.exists()) {galleryPath.mkdir();}// 声明文件对象File file = null;// 声明输出流FileOutputStream outStream = null;String fileName = null;try {// 如果有目标文件,直接获得文件对象,否则创建一个以filename为名称的文件file = new File(galleryPath, picName + ".jpg");
// if(file.exists()){
// file.delete();
// file = new File(galleryPath, picName + ".jpg");
// }
// file = new File(galleryPath, photoName);// 获得文件相对路径fileName = file.toString();// 获得输出流,如果文件中有内容,追加内容outStream = new FileOutputStream(fileName);if (null != outStream) {bmp.compress(Bitmap.CompressFormat.JPEG, 100, outStream);}} catch (Exception e) {e.getStackTrace();} finally {try {if (outStream != null) {outStream.flush();outStream.close();}} catch (IOException e) {e.printStackTrace();}}try {MediaScannerConnection.scanFile(context, new String[]{fileName}, null, null);Toast.makeText(context, context.getResources().getString(R.string.pic_save_success), Toast.LENGTH_SHORT).show();} catch (Exception e) {e.printStackTrace();Toast.makeText(context, context.getResources().getString(R.string.pic_save_fail), Toast.LENGTH_SHORT).show();}return file;}public static boolean saveBmp2Gallery2(Context context, String fileSavePath, Bitmap bmp, String picName) {isFolderExists(fileSavePath);File galleryPath = new File(fileSavePath);if (!galleryPath.exists()) {galleryPath.mkdir();}// 声明文件对象File file = null;// 声明输出流FileOutputStream outStream = null;String fileName = null;try {// 如果有目标文件,直接获得文件对象,否则创建一个以filename为名称的文件file = new File(galleryPath, picName + ".jpg");
// if(file.exists()){
// file.delete();
// file = new File(galleryPath, picName + ".jpg");
// }
// file = new File(galleryPath, photoName);// 获得文件相对路径fileName = file.toString();// 获得输出流,如果文件中有内容,追加内容outStream = new FileOutputStream(fileName);if (null != outStream) {bmp.compress(Bitmap.CompressFormat.JPEG, 100, outStream);}} catch (Exception e) {e.getStackTrace();} finally {try {if (outStream != null) {outStream.flush();outStream.close();}} catch (IOException e) {e.printStackTrace();}}try {MediaScannerConnection.scanFile(context, new String[]{fileName}, null, null);Toast.makeText(context, context.getResources().getString(R.string.pic_save_success), Toast.LENGTH_SHORT).show();return true;} catch (Exception e) {e.printStackTrace();Toast.makeText(context, context.getResources().getString(R.string.pic_save_fail), Toast.LENGTH_SHORT).show();}return false;}//判断是否存在,不存在创建文件夹public static boolean isFolderExists(String strFolder) {File file = new File(strFolder);if (!file.exists()) {if (file.mkdirs()) {return true;} else {return false;}}return true;}/*** 把两个位图覆盖合成为一个位图,以底层位图的长宽为基准** @param backBitmap 在底部的位图* @param frontBitmap 盖在上面的位图* @return*/public static Bitmap mergeBitmap(Bitmap backBitmap, Bitmap frontBitmap, int leftFront, int topFront) {if (backBitmap == null || backBitmap.isRecycled()|| frontBitmap == null || frontBitmap.isRecycled()) {return null;}// Bitmap bitmap = backBitmap.copy(Bitmap.Config.ARGB_8888, true);
// Canvas canvas = new Canvas(bitmap);
// canvas.drawBitmap(backBitmap, 0, 0, null);
// canvas.drawBitmap(frontBitmap, leftFront, topFront, null);Bitmap bitmap = frontBitmap.copy(Bitmap.Config.ARGB_8888, true);Canvas canvas = new Canvas(bitmap);float x = (float)(bitmap.getWidth()) / (float)(backBitmap.getWidth());float y = (float)(bitmap.getHeight()) / (float)(backBitmap.getHeight());Matrix matrix = new Matrix();matrix.postScale(x, y); // 缩放比例 大于1为放大backBitmap = Bitmap.createBitmap(backBitmap, 0, 0, backBitmap.getWidth(), backBitmap.getHeight(), matrix, true);canvas.drawBitmap(backBitmap, 0, 0, null);canvas.drawBitmap(frontBitmap, 0, 0, null);return bitmap;}/*** 把两个位图覆盖合成为一个位图,以底层位图的长宽为基准** @param bytes 在底部的位图* @param bytes2 盖在上面的位图*/public static void savaRawFile(byte[] bytes, byte[] bytes2) {try {File path = new File("/sdcard");if (!path.exists() && path.isDirectory()) {path.mkdirs();}File file = new File("/sdcard/", new SimpleDateFormat("_HHmmss_yyMMdd").format(new Date(System.currentTimeMillis())) + ".bin");FileOutputStream fos = new FileOutputStream(file);fos.write(bytes);fos.write(bytes2);fos.close();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}/*** 保存红外数据** @param bytes*/public static void savaIRFile(byte[] bytes) {try {File path = new File("/sdcard");if (!path.exists() && path.isDirectory()) {path.mkdirs();}File file = new File("/sdcard/", "ir" + new SimpleDateFormat("_HHmmss_yyMMdd").format(new Date(System.currentTimeMillis())) + ".bin");FileOutputStream fos = new FileOutputStream(file);fos.write(bytes);fos.close();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}/*** 保存温度数据** @param bytes*/public static void savaTempFile(byte[] bytes) {try {File path = new File("/sdcard");if (!path.exists() && path.isDirectory()) {path.mkdirs();}File file = new File("/sdcard/", "temp" + new SimpleDateFormat("_HHmmss_yyMMdd").format(new Date(System.currentTimeMillis())) + ".bin");FileOutputStream fos = new FileOutputStream(file);fos.write(bytes);fos.close();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}/*** @param context* @param file* @return*/public static boolean isFileExists(Context context, final File file) {if (file == null) return false;if (file.exists()) {return true;}return isFileExists(context, file.getAbsolutePath());}/*** Return whether the file exists.** @param filePath The path of file.* @return {@code true}: yes<br>{@code false}: no*/public static boolean isFileExists(Context context, final String filePath) {File file = new File(filePath);if (file == null) return false;if (file.exists()) {return true;}return isFileExistsApi29(context, filePath);}/*** @param context* @param filePath* @return*/private static boolean isFileExistsApi29(Context context, String filePath) {if (Build.VERSION.SDK_INT >= 29) {try {Uri uri = Uri.parse(filePath);ContentResolver cr = context.getContentResolver();AssetFileDescriptor afd = cr.openAssetFileDescriptor(uri, "r");if (afd == null) return false;try {afd.close();} catch (IOException ignore) {}} catch (FileNotFoundException e) {return false;}return true;}return false;}/*** short数组转byte数组** @param src* @return*/private static byte[] toByteArray(short[] src) {int count = src.length;byte[] dest = new byte[count << 1];for (int i = 0; i < count; i++) {dest[i * 2] = (byte) ((src[i] >> 8) & 0xFF);dest[i * 2 + 1] = (byte) (src[i] & 0xFF);}return dest;}/*** byte数组转short数组** @param src* @return*/public static short[] toShortArray(byte[] src) {int count = src.length >> 1;short[] dest = new short[count];for (int i = 0; i < count; i++) {dest[i] = (short) ((src[i * 2] & 0xFF) << 8 | ((src[2 * i + 1] & 0xFF)));}return dest;}/*** @param bytes* @param fileTitle*/public static void saveShortFile(String fileDir, short[] bytes, String fileTitle) {// 创建目录createOrExistsDir(fileDir);try {File file = new File(fileDir, fileTitle + ".bin");createOrExistsDir(file);Log.i("TAG", "getAbsolutePath = " + file.getAbsolutePath());FileOutputStream fos = new FileOutputStream(file);fos.write(toByteArray(bytes));fos.close();} catch (IOException e) {e.printStackTrace();}}/*** @param file*/private static void createOrExistsDir(File file) {// 文件不存在则创建文件if (!file.exists()) {try {file.createNewFile();} catch (IOException e) {e.printStackTrace();}}}/*** 如果文件夹不存在则创建** @param fileDir*/private static void createOrExistsDir(String fileDir) {File file = new File(fileDir);//如果文件夹不存在则创建if (!file.exists() && !file.isDirectory()) {//不存在file.mkdir();} else {//目录存在}}private static int sBufferSize = 524288;/*** @param context* @param file* @return*/public static byte[] readFile2BytesByStream(Context context, final File file) {if (!isFileExists(context, file)) return null;try {ByteArrayOutputStream os = null;InputStream is = new BufferedInputStream(new FileInputStream(file), sBufferSize);try {os = new ByteArrayOutputStream();byte[] b = new byte[sBufferSize];int len;while ((len = is.read(b, 0, sBufferSize)) != -1) {os.write(b, 0, len);}return os.toByteArray();} catch (IOException e) {e.printStackTrace();return null;} finally {try {is.close();} catch (IOException e) {e.printStackTrace();}try {if (os != null) {os.close();}} catch (IOException e) {e.printStackTrace();}}} catch (FileNotFoundException e) {e.printStackTrace();return null;}}}
2.使用方法
// 保存图片boolean isSucc = BitmapUtils.saveBmp2Gallery2(this, App.getInstance().INFISENSE_SAVE_DIR + File.separator + DateUtils.getCurrentTime_Today("yyyy-MM-dd"), bitmap, "名称");
3.保存地址
/***图片保存的文件夹*/public String INFISENSE_SAVE_DIR;@Overridepublic void onCreate() {super.onCreate();INFISENSE_SAVE_DIR = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getAbsolutePath()+ File.separator + Constant.FOLDER_INFRARED_TEMP;//FOLDER_INFRARED_TEMP文件夹名称File file = new File(INFISENSE_SAVE_DIR);if (!file.exists()){file.mkdirs();}}