From b09089542ec7db5e00dfbb0ba9e0d831dcd2eaea Mon Sep 17 00:00:00 2001 From: LiuShilin <503233512@qq.com> Date: Wed, 26 Apr 2017 09:18:04 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B0=9D=E8=AF=95=E8=A7=A3=E5=86=B3width,heigh?= =?UTF-8?q?t=20must=20be=20>=200?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../nanchen/compressimage/MainActivity.java | 2 +- .../nanchen/compresshelper/BitmapUtil.java | 303 +++++++++++------- .../compresshelper/CompressHelper.java | 17 +- .../com/nanchen/compresshelper/FileUtil.java | 4 +- .../com/nanchen/compresshelper/ImageUtil.java | 303 +++++++----------- .../{StringUtils.java => StringUtil.java} | 4 +- 6 files changed, 324 insertions(+), 309 deletions(-) rename compresshelper/src/main/java/com/nanchen/compresshelper/{StringUtils.java => StringUtil.java} (98%) diff --git a/app/src/main/java/com/nanchen/compressimage/MainActivity.java b/app/src/main/java/com/nanchen/compressimage/MainActivity.java index ba031c3..3a2418b 100644 --- a/app/src/main/java/com/nanchen/compressimage/MainActivity.java +++ b/app/src/main/java/com/nanchen/compressimage/MainActivity.java @@ -49,7 +49,7 @@ private void initInstances() { public void compress(View view) { // 默认的压缩方法,多张图片只需要直接加入循环即可 - newFile = CompressHelper.getDefault(this).compressToFile(oldFile); + newFile = CompressHelper.getDefault(getApplicationContext()).compressToFile(oldFile); // String yourFileName = "123.jpg"; diff --git a/compresshelper/src/main/java/com/nanchen/compresshelper/BitmapUtil.java b/compresshelper/src/main/java/com/nanchen/compresshelper/BitmapUtil.java index 3a784c0..7e45b2f 100644 --- a/compresshelper/src/main/java/com/nanchen/compresshelper/BitmapUtil.java +++ b/compresshelper/src/main/java/com/nanchen/compresshelper/BitmapUtil.java @@ -1,159 +1,230 @@ package com.nanchen.compresshelper; -import android.content.res.Resources; +import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; +import android.graphics.Canvas; +import android.graphics.Matrix; +import android.graphics.Paint; import android.media.ExifInterface; +import android.net.Uri; +import android.text.TextUtils; import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; /** - * Bitmap 压缩相关操作工具类 - * - * - * - * 原理不明白请查看我博客:http://www.cnblogs.com/liushilin/p/6116759.html + * 图片处理工具类 * * Author: nanchen * Email: liushilin520@foxmail.com - * Date: 2017-02-13 15:43 + * Date: 2017-03-08 9:03 */ public class BitmapUtil { - /** - * 计算图片的压缩比率 - * - * @param options 参数 - * @param reqWidth 目标的宽度 - * @param reqHeight 目标的高度 - * @param pathName 路径 - * @return 计算的SampleSize - */ - private static int calculateInSampleSize(BitmapFactory.Options options,String pathName, int reqWidth, int reqHeight) { - // 源图片的高度和宽度 - int height = options.outHeight; - int width = options.outWidth; - if (height == -1 || width == -1) { + + private BitmapUtil() { + throw new UnsupportedOperationException("u can't instantiate me..."); + } + + static Bitmap getScaledBitmap(Context context, Uri imageUri, float maxWidth, float maxHeight, Bitmap.Config bitmapConfig) { + String filePath = FileUtil.getRealPathFromURI(context, imageUri); + Bitmap scaledBitmap = null; + + BitmapFactory.Options options = new BitmapFactory.Options(); + + //by setting this field as true, the actual bitmap pixels are not loaded in the memory. Just the bounds are loaded. If + //you try the use the bitmap here, you will get null. + options.inJustDecodeBounds = true; + Bitmap bmp = BitmapFactory.decodeFile(filePath, options); + if (bmp == null) { + InputStream inputStream = null; + try { + inputStream = new FileInputStream(filePath); + BitmapFactory.decodeStream(inputStream, null, options); + inputStream.close(); + } catch (FileNotFoundException exception) { + exception.printStackTrace(); + } catch (IOException exception) { + exception.printStackTrace(); + } + } + + int actualHeight = options.outHeight; + int actualWidth = options.outWidth; + + if (actualHeight == -1 || actualWidth == -1){ try { - ExifInterface exifInterface = new ExifInterface(pathName); - height = exifInterface.getAttributeInt(ExifInterface.TAG_IMAGE_LENGTH, ExifInterface.ORIENTATION_NORMAL);//获取图片的高度 - width = exifInterface.getAttributeInt(ExifInterface.TAG_IMAGE_WIDTH, ExifInterface.ORIENTATION_NORMAL);//获取图片的宽度 + ExifInterface exifInterface = new ExifInterface(filePath); + actualHeight = exifInterface.getAttributeInt(ExifInterface.TAG_IMAGE_LENGTH, ExifInterface.ORIENTATION_NORMAL);//获取图片的高度 + actualWidth = exifInterface.getAttributeInt(ExifInterface.TAG_IMAGE_WIDTH, ExifInterface.ORIENTATION_NORMAL);//获取图片的宽度 } catch (IOException e) { e.printStackTrace(); } } - int inSampleSize = 1; - if (height > reqHeight || width > reqWidth) { - final int halfHeight = height / 2; - final int halfWidth = width / 2; - // Calculate the largest inSampleSize value that is a power of 2 and keeps both - // height and width larger than the requested height and width. - while ((halfHeight / inSampleSize) > reqHeight - && (halfWidth / inSampleSize) > reqWidth) { - inSampleSize *= 2; + + if (actualWidth <= 0 || actualHeight <= 0) { + Bitmap bitmap2 = BitmapFactory.decodeFile(filePath); + if (bitmap2 != null){ + actualWidth = bitmap2.getWidth(); + actualHeight = bitmap2.getHeight(); + }else{ + return null; } } - return inSampleSize; - } + float imgRatio = (float) actualWidth / actualHeight; + float maxRatio = maxWidth / maxHeight; - /** - * 计算图片的压缩比率 - * - * @param options 参数 - * @param reqWidth 目标的宽度 - * @param reqHeight 目标的高度 - * @return 计算的SampleSize - */ - private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { - // 源图片的高度和宽度 - int height = options.outHeight; - int width = options.outWidth; - int inSampleSize = 1; - if (height > reqHeight || width > reqWidth) { - final int halfHeight = height / 2; - final int halfWidth = width / 2; - // Calculate the largest inSampleSize value that is a power of 2 and keeps both - // height and width larger than the requested height and width. - while ((halfHeight / inSampleSize) > reqHeight - && (halfWidth / inSampleSize) > reqWidth) { - inSampleSize *= 2; + //width and height values are set maintaining the aspect ratio of the image + if (actualHeight > maxHeight || actualWidth > maxWidth) { + if (imgRatio < maxRatio) { + imgRatio = maxHeight / actualHeight; + actualWidth = (int) (imgRatio * actualWidth); + actualHeight = (int) maxHeight; + } else if (imgRatio > maxRatio) { + imgRatio = maxWidth / actualWidth; + actualHeight = (int) (imgRatio * actualHeight); + actualWidth = (int) maxWidth; + } else { + actualHeight = (int) maxHeight; + actualWidth = (int) maxWidth; } } - return inSampleSize; - } - /** - * 从Resources中加载图片 - * - * @param res Resource - * @param resId 资源id - * @param reqWidth 请求宽度 - * @param reqHeight 请求高度 - * @return Bitmap - */ - public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) { - final BitmapFactory.Options options = new BitmapFactory.Options(); - options.inJustDecodeBounds = true; // 设置成了true,不占用内存,只获取bitmap宽高 - BitmapFactory.decodeResource(res, resId, options); // 读取图片长款 - options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); // 调用上面定义的方法计算inSampleSize值 - // 使用获取到的inSampleSize值再次解析图片 + //setting inSampleSize value allows to load a scaled down version of the original image + options.inSampleSize = calculateInSampleSize(options, actualWidth, actualHeight); + + //inJustDecodeBounds set to false to load the actual bitmap options.inJustDecodeBounds = false; - Bitmap src = BitmapFactory.decodeResource(res, resId, options); // 载入一个稍大的缩略图 - return createScaleBitmap(src, reqWidth, reqHeight, options.inSampleSize); // 进一步得到目标大小的缩略图 - } - /** - * 通过传入的bitmap,进行压缩,得到符合标准的bitmap - * - * @param src Bitmap源图 - * @param dstWidth 宽度 - * @param dstHeight 高度 - * @return 新的Bitmap - */ - private static Bitmap createScaleBitmap(Bitmap src, int dstWidth, int dstHeight, int inSampleSize) { - //如果inSampleSize是2的倍数,也就说这个src已经是我们想要的缩略图了,直接返回即可。 - if (inSampleSize % 2 == 0) { - return src; + //this options allow android to claim the bitmap memory if it runs low on memory + options.inPurgeable = true; + options.inInputShareable = true; + options.inTempStorage = new byte[16 * 1024]; + + try { + // load the bitmap getTempFile its path + bmp = BitmapFactory.decodeFile(filePath, options); + if (bmp == null) { + InputStream inputStream = null; + try { + inputStream = new FileInputStream(filePath); + BitmapFactory.decodeStream(inputStream, null, options); + inputStream.close(); + } catch (IOException exception) { + exception.printStackTrace(); + } + } + } catch (OutOfMemoryError exception) { + exception.printStackTrace(); } - if (src == null){ + if (actualHeight <= 0 || actualWidth <= 0){ return null; } - // 如果是放大图片,filter决定是否平滑,如果是缩小图片,filter无影响,我们这里是缩小图片,所以直接设置为false - Bitmap dst = Bitmap.createScaledBitmap(src, dstWidth, dstHeight, false); - if (src != dst) { // 如果没有缩放,那么不回收 - src.recycle(); // 释放Bitmap的native像素数组 + + try { + scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight, bitmapConfig); + } catch (OutOfMemoryError exception) { + exception.printStackTrace(); } - return dst; + + float ratioX = actualWidth / (float) options.outWidth; + float ratioY = actualHeight / (float) options.outHeight; + + Matrix scaleMatrix = new Matrix(); + scaleMatrix.setScale(ratioX, ratioY, 0, 0); + + Canvas canvas = new Canvas(scaledBitmap); + canvas.setMatrix(scaleMatrix); + canvas.drawBitmap(bmp, 0, 0, new Paint(Paint.FILTER_BITMAP_FLAG)); + + //check the rotation of the image and display it properly + ExifInterface exif; + try { + exif = new ExifInterface(filePath); + int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0); + Matrix matrix = new Matrix(); + if (orientation == 6) { + matrix.postRotate(90); + } else if (orientation == 3) { + matrix.postRotate(180); + } else if (orientation == 8) { + matrix.postRotate(270); + } + scaledBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0, + scaledBitmap.getWidth(), scaledBitmap.getHeight(), + matrix, true); + } catch (IOException e) { + e.printStackTrace(); + } + + return scaledBitmap; } - /** - * 从SD卡上加载图片 - * - * @param pathName 路径 - * @param reqWidth 请求宽度 - * @param reqHeight 请求高度 - * @return Bitmap - */ - public static Bitmap decodeSampledBitmapFromFile(String pathName, int reqWidth, int reqHeight) { - final BitmapFactory.Options options = new BitmapFactory.Options(); - options.inJustDecodeBounds = true; - BitmapFactory.decodeFile(pathName, options); - options.inSampleSize = calculateInSampleSize(options, pathName,reqWidth, reqHeight); - options.inJustDecodeBounds = false; - Bitmap src = BitmapFactory.decodeFile(pathName, options); - return createScaleBitmap(src, reqWidth, reqHeight, options.inSampleSize); + static File compressImage(Context context, Uri imageUri, float maxWidth, float maxHeight, + Bitmap.CompressFormat compressFormat, Bitmap.Config bitmapConfig, + int quality, String parentPath, String prefix, String fileName) { + FileOutputStream out = null; + String filename = generateFilePath(context, parentPath, imageUri, compressFormat.name().toLowerCase(), prefix, fileName); + try { + out = new FileOutputStream(filename); + //write the compressed bitmap at the destination specified by filename. + BitmapUtil.getScaledBitmap(context, imageUri, maxWidth, maxHeight, bitmapConfig).compress(compressFormat, quality, out); + + } catch (FileNotFoundException e) { + e.printStackTrace(); + } finally { + try { + if (out != null) { + out.close(); + } + } catch (IOException ignored) { + } + } + + return new File(filename); + } + + private static String generateFilePath(Context context, String parentPath, Uri uri, + String extension, String prefix, String fileName) { + File file = new File(parentPath); + if (!file.exists()) { + file.mkdirs(); + } + /** if prefix is null, set prefix "" */ + prefix = TextUtils.isEmpty(prefix) ? "" : prefix; + /** reset fileName by prefix and custom file name */ + fileName = TextUtils.isEmpty(fileName) ? prefix + FileUtil.splitFileName(FileUtil.getFileName(context, uri))[0] : fileName; + return file.getAbsolutePath() + File.separator + fileName + "." + extension; } + /** - * 删除临时图片 - * @param path 图片路径 + * 计算inSampleSize */ - public static void deleteTempFile(String path){ - File file = new File(path); - if (file.exists()){ - file.delete(); + private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { + final int height = options.outHeight; + final int width = options.outWidth; + int inSampleSize = 1; + + if (height > reqHeight || width > reqWidth) { + final int heightRatio = Math.round((float) height / (float) reqHeight); + final int widthRatio = Math.round((float) width / (float) reqWidth); + inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio; + } + + final float totalPixels = width * height; + final float totalReqPixelsCap = reqWidth * reqHeight * 2; + + while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) { + inSampleSize++; } + + return inSampleSize; } } diff --git a/compresshelper/src/main/java/com/nanchen/compresshelper/CompressHelper.java b/compresshelper/src/main/java/com/nanchen/compresshelper/CompressHelper.java index 4405e25..df7d5c6 100644 --- a/compresshelper/src/main/java/com/nanchen/compresshelper/CompressHelper.java +++ b/compresshelper/src/main/java/com/nanchen/compresshelper/CompressHelper.java @@ -15,6 +15,8 @@ */ public class CompressHelper { + private static volatile CompressHelper INSTANCE; + private Context context; /** * 最大宽度,默认为720 @@ -50,6 +52,17 @@ public class CompressHelper { */ private String fileName; + public static CompressHelper getDefault(Context context) { + if (INSTANCE == null) { + synchronized (CompressHelper.class) { + if (INSTANCE == null) { + INSTANCE = new CompressHelper(context); + } + } + } + return INSTANCE; + } + private CompressHelper(Context context) { this.context = context; @@ -62,7 +75,7 @@ private CompressHelper(Context context) { * @return 压缩后的文件 */ public File compressToFile(File file) { - return ImageUtil.compressImage(context, Uri.fromFile(file), maxWidth, maxHeight, + return BitmapUtil.compressImage(context, Uri.fromFile(file), maxWidth, maxHeight, compressFormat, bitmapConfig, quality, destinationDirectoryPath, fileNamePrefix, fileName); } @@ -73,7 +86,7 @@ public File compressToFile(File file) { * @return 压缩后的Bitmap */ public Bitmap compressToBitmap(File file) { - return ImageUtil.getScaledBitmap(context, Uri.fromFile(file), maxWidth, maxHeight, bitmapConfig); + return BitmapUtil.getScaledBitmap(context, Uri.fromFile(file), maxWidth, maxHeight, bitmapConfig); } diff --git a/compresshelper/src/main/java/com/nanchen/compresshelper/FileUtil.java b/compresshelper/src/main/java/com/nanchen/compresshelper/FileUtil.java index 110920f..ce068a4 100644 --- a/compresshelper/src/main/java/com/nanchen/compresshelper/FileUtil.java +++ b/compresshelper/src/main/java/com/nanchen/compresshelper/FileUtil.java @@ -38,7 +38,7 @@ private FileUtil() { * @return 文件 */ public static File getFileByPath(String filePath) { - return StringUtils.isSpace(filePath) ? null : new File(filePath); + return StringUtil.isSpace(filePath) ? null : new File(filePath); } /** @@ -86,7 +86,7 @@ public static boolean rename(File file, String newName) { // 文件不存在返回false if (!file.exists()) return false; // 新的文件名为空返回false - if (StringUtils.isSpace(newName)) return false; + if (StringUtil.isSpace(newName)) return false; // 如果文件名没有改变返回true if (newName.equals(file.getName())) return true; File newFile = new File(file.getParent() + File.separator + newName); diff --git a/compresshelper/src/main/java/com/nanchen/compresshelper/ImageUtil.java b/compresshelper/src/main/java/com/nanchen/compresshelper/ImageUtil.java index 942b5d0..f035300 100644 --- a/compresshelper/src/main/java/com/nanchen/compresshelper/ImageUtil.java +++ b/compresshelper/src/main/java/com/nanchen/compresshelper/ImageUtil.java @@ -1,228 +1,159 @@ package com.nanchen.compresshelper; -import android.content.Context; +import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; -import android.graphics.Canvas; -import android.graphics.Matrix; -import android.graphics.Paint; import android.media.ExifInterface; -import android.net.Uri; -import android.text.TextUtils; import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; import java.io.IOException; -import java.io.InputStream; /** - * 图片处理工具类 + * Bitmap 压缩相关操作工具类 + * + * + * + * 原理不明白请查看我博客:http://www.cnblogs.com/liushilin/p/6116759.html * * Author: nanchen * Email: liushilin520@foxmail.com - * Date: 2017-03-08 9:03 + * Date: 2017-02-13 15:43 */ public class ImageUtil { - - private ImageUtil() { - throw new UnsupportedOperationException("u can't instantiate me..."); - } - - static Bitmap getScaledBitmap(Context context, Uri imageUri, float maxWidth, float maxHeight, Bitmap.Config bitmapConfig) { - String filePath = FileUtil.getRealPathFromURI(context, imageUri); - Bitmap scaledBitmap = null; - - BitmapFactory.Options options = new BitmapFactory.Options(); - - //by setting this field as true, the actual bitmap pixels are not loaded in the memory. Just the bounds are loaded. If - //you try the use the bitmap here, you will get null. - options.inJustDecodeBounds = true; - Bitmap bmp = BitmapFactory.decodeFile(filePath, options); - if (bmp == null) { - InputStream inputStream = null; - try { - inputStream = new FileInputStream(filePath); - BitmapFactory.decodeStream(inputStream, null, options); - inputStream.close(); - } catch (FileNotFoundException exception) { - exception.printStackTrace(); - } catch (IOException exception) { - exception.printStackTrace(); - } - } - - int actualHeight = options.outHeight; - int actualWidth = options.outWidth; - - if (actualHeight == -1 || actualWidth == -1){ + /** + * 计算图片的压缩比率 + * + * @param options 参数 + * @param reqWidth 目标的宽度 + * @param reqHeight 目标的高度 + * @param pathName 路径 + * @return 计算的SampleSize + */ + private static int calculateInSampleSize(BitmapFactory.Options options,String pathName, int reqWidth, int reqHeight) { + // 源图片的高度和宽度 + int height = options.outHeight; + int width = options.outWidth; + if (height == -1 || width == -1) { try { - ExifInterface exifInterface = new ExifInterface(filePath); - actualHeight = exifInterface.getAttributeInt(ExifInterface.TAG_IMAGE_LENGTH, ExifInterface.ORIENTATION_NORMAL);//获取图片的高度 - actualWidth = exifInterface.getAttributeInt(ExifInterface.TAG_IMAGE_WIDTH, ExifInterface.ORIENTATION_NORMAL);//获取图片的宽度 + ExifInterface exifInterface = new ExifInterface(pathName); + height = exifInterface.getAttributeInt(ExifInterface.TAG_IMAGE_LENGTH, ExifInterface.ORIENTATION_NORMAL);//获取图片的高度 + width = exifInterface.getAttributeInt(ExifInterface.TAG_IMAGE_WIDTH, ExifInterface.ORIENTATION_NORMAL);//获取图片的宽度 } catch (IOException e) { e.printStackTrace(); } } - - if (actualWidth < 0 || actualHeight < 0) { - Bitmap bitmap2 = BitmapFactory.decodeFile(filePath); - if (bitmap2 != null){ - actualWidth = bitmap2.getWidth(); - actualHeight = bitmap2.getHeight(); - }else{ - return null; + int inSampleSize = 1; + if (height > reqHeight || width > reqWidth) { + final int halfHeight = height / 2; + final int halfWidth = width / 2; + // Calculate the largest inSampleSize value that is a power of 2 and keeps both + // height and width larger than the requested height and width. + while ((halfHeight / inSampleSize) > reqHeight + && (halfWidth / inSampleSize) > reqWidth) { + inSampleSize *= 2; } } + return inSampleSize; + } - float imgRatio = (float) actualWidth / actualHeight; - float maxRatio = maxWidth / maxHeight; - //width and height values are set maintaining the aspect ratio of the image - if (actualHeight > maxHeight || actualWidth > maxWidth) { - if (imgRatio < maxRatio) { - imgRatio = maxHeight / actualHeight; - actualWidth = (int) (imgRatio * actualWidth); - actualHeight = (int) maxHeight; - } else if (imgRatio > maxRatio) { - imgRatio = maxWidth / actualWidth; - actualHeight = (int) (imgRatio * actualHeight); - actualWidth = (int) maxWidth; - } else { - actualHeight = (int) maxHeight; - actualWidth = (int) maxWidth; + /** + * 计算图片的压缩比率 + * + * @param options 参数 + * @param reqWidth 目标的宽度 + * @param reqHeight 目标的高度 + * @return 计算的SampleSize + */ + private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { + // 源图片的高度和宽度 + int height = options.outHeight; + int width = options.outWidth; + int inSampleSize = 1; + if (height > reqHeight || width > reqWidth) { + final int halfHeight = height / 2; + final int halfWidth = width / 2; + // Calculate the largest inSampleSize value that is a power of 2 and keeps both + // height and width larger than the requested height and width. + while ((halfHeight / inSampleSize) > reqHeight + && (halfWidth / inSampleSize) > reqWidth) { + inSampleSize *= 2; } } + return inSampleSize; + } - //setting inSampleSize value allows to load a scaled down version of the original image - options.inSampleSize = calculateInSampleSize(options, actualWidth, actualHeight); - - //inJustDecodeBounds set to false to load the actual bitmap + /** + * 从Resources中加载图片 + * + * @param res Resource + * @param resId 资源id + * @param reqWidth 请求宽度 + * @param reqHeight 请求高度 + * @return Bitmap + */ + public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) { + final BitmapFactory.Options options = new BitmapFactory.Options(); + options.inJustDecodeBounds = true; // 设置成了true,不占用内存,只获取bitmap宽高 + BitmapFactory.decodeResource(res, resId, options); // 读取图片长款 + options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); // 调用上面定义的方法计算inSampleSize值 + // 使用获取到的inSampleSize值再次解析图片 options.inJustDecodeBounds = false; + Bitmap src = BitmapFactory.decodeResource(res, resId, options); // 载入一个稍大的缩略图 + return createScaleBitmap(src, reqWidth, reqHeight, options.inSampleSize); // 进一步得到目标大小的缩略图 + } - //this options allow android to claim the bitmap memory if it runs low on memory - options.inPurgeable = true; - options.inInputShareable = true; - options.inTempStorage = new byte[16 * 1024]; - - try { - //load the bitmap getTempFile its path - bmp = BitmapFactory.decodeFile(filePath, options); - if (bmp == null) { - InputStream inputStream = null; - try { - inputStream = new FileInputStream(filePath); - BitmapFactory.decodeStream(inputStream, null, options); - inputStream.close(); - } catch (FileNotFoundException exception) { - exception.printStackTrace(); - } catch (IOException exception) { - exception.printStackTrace(); - } - } - } catch (OutOfMemoryError exception) { - exception.printStackTrace(); - } - try { - scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight, bitmapConfig); - } catch (OutOfMemoryError exception) { - exception.printStackTrace(); + /** + * 通过传入的bitmap,进行压缩,得到符合标准的bitmap + * + * @param src Bitmap源图 + * @param dstWidth 宽度 + * @param dstHeight 高度 + * @return 新的Bitmap + */ + private static Bitmap createScaleBitmap(Bitmap src, int dstWidth, int dstHeight, int inSampleSize) { + //如果inSampleSize是2的倍数,也就说这个src已经是我们想要的缩略图了,直接返回即可。 + if (inSampleSize % 2 == 0) { + return src; } - - float ratioX = actualWidth / (float) options.outWidth; - float ratioY = actualHeight / (float) options.outHeight; - - Matrix scaleMatrix = new Matrix(); - scaleMatrix.setScale(ratioX, ratioY, 0, 0); - - Canvas canvas = new Canvas(scaledBitmap); - canvas.setMatrix(scaleMatrix); - canvas.drawBitmap(bmp, 0, 0, new Paint(Paint.FILTER_BITMAP_FLAG)); - - //check the rotation of the image and display it properly - ExifInterface exif; - try { - exif = new ExifInterface(filePath); - int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0); - Matrix matrix = new Matrix(); - if (orientation == 6) { - matrix.postRotate(90); - } else if (orientation == 3) { - matrix.postRotate(180); - } else if (orientation == 8) { - matrix.postRotate(270); - } - scaledBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0, - scaledBitmap.getWidth(), scaledBitmap.getHeight(), - matrix, true); - } catch (IOException e) { - e.printStackTrace(); + if (src == null){ + return null; } - - return scaledBitmap; - } - - static File compressImage(Context context, Uri imageUri, float maxWidth, float maxHeight, - Bitmap.CompressFormat compressFormat, Bitmap.Config bitmapConfig, - int quality, String parentPath, String prefix, String fileName) { - FileOutputStream out = null; - String filename = generateFilePath(context, parentPath, imageUri, compressFormat.name().toLowerCase(), prefix, fileName); - try { - out = new FileOutputStream(filename); - //write the compressed bitmap at the destination specified by filename. - ImageUtil.getScaledBitmap(context, imageUri, maxWidth, maxHeight, bitmapConfig).compress(compressFormat, quality, out); - - } catch (FileNotFoundException e) { - e.printStackTrace(); - } finally { - try { - if (out != null) { - out.close(); - } - } catch (IOException ignored) { - } + // 如果是放大图片,filter决定是否平滑,如果是缩小图片,filter无影响,我们这里是缩小图片,所以直接设置为false + Bitmap dst = Bitmap.createScaledBitmap(src, dstWidth, dstHeight, false); + if (src != dst) { // 如果没有缩放,那么不回收 + src.recycle(); // 释放Bitmap的native像素数组 } - - return new File(filename); + return dst; } - private static String generateFilePath(Context context, String parentPath, Uri uri, - String extension, String prefix, String fileName) { - File file = new File(parentPath); - if (!file.exists()) { - file.mkdirs(); - } - /** if prefix is null, set prefix "" */ - prefix = TextUtils.isEmpty(prefix) ? "" : prefix; - /** reset fileName by prefix and custom file name */ - fileName = TextUtils.isEmpty(fileName) ? prefix + FileUtil.splitFileName(FileUtil.getFileName(context, uri))[0] : fileName; - return file.getAbsolutePath() + File.separator + fileName + "." + extension; + /** + * 从SD卡上加载图片 + * + * @param pathName 路径 + * @param reqWidth 请求宽度 + * @param reqHeight 请求高度 + * @return Bitmap + */ + public static Bitmap decodeSampledBitmapFromFile(String pathName, int reqWidth, int reqHeight) { + final BitmapFactory.Options options = new BitmapFactory.Options(); + options.inJustDecodeBounds = true; + BitmapFactory.decodeFile(pathName, options); + options.inSampleSize = calculateInSampleSize(options, pathName,reqWidth, reqHeight); + options.inJustDecodeBounds = false; + Bitmap src = BitmapFactory.decodeFile(pathName, options); + return createScaleBitmap(src, reqWidth, reqHeight, options.inSampleSize); } - /** - * 计算inSampleSize + * 删除临时图片 + * @param path 图片路径 */ - private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { - final int height = options.outHeight; - final int width = options.outWidth; - int inSampleSize = 1; - - if (height > reqHeight || width > reqWidth) { - final int heightRatio = Math.round((float) height / (float) reqHeight); - final int widthRatio = Math.round((float) width / (float) reqWidth); - inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio; - } - - final float totalPixels = width * height; - final float totalReqPixelsCap = reqWidth * reqHeight * 2; - - while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) { - inSampleSize++; + public static void deleteTempFile(String path){ + File file = new File(path); + if (file.exists()){ + file.delete(); } - - return inSampleSize; } } diff --git a/compresshelper/src/main/java/com/nanchen/compresshelper/StringUtils.java b/compresshelper/src/main/java/com/nanchen/compresshelper/StringUtil.java similarity index 98% rename from compresshelper/src/main/java/com/nanchen/compresshelper/StringUtils.java rename to compresshelper/src/main/java/com/nanchen/compresshelper/StringUtil.java index 89905fa..706d27a 100644 --- a/compresshelper/src/main/java/com/nanchen/compresshelper/StringUtils.java +++ b/compresshelper/src/main/java/com/nanchen/compresshelper/StringUtil.java @@ -9,9 +9,9 @@ * Date: 2017-02-19 9:52 */ -public class StringUtils { +public class StringUtil { - private StringUtils() { + private StringUtil() { throw new UnsupportedOperationException("u can't instantiate me..."); }