大图片文件压缩保存本地,返回本地url

import android.app.ActivityManager;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.os.Build;
import android.os.Environment;
import android.support.v4.util.LruCache;

import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import static android.media.ExifInterface.ORIENTATION_NORMAL;
import static android.media.ExifInterface.ORIENTATION_ROTATE_180;
import static android.media.ExifInterface.ORIENTATION_ROTATE_270;
import static android.media.ExifInterface.ORIENTATION_ROTATE_90;
import static android.media.ExifInterface.TAG_ORIENTATION;

public class ImageFileUtils {
    private static final int widthPixels = 480;
    private static final int heightPixels = 800;
    private static final String PACKAGE_NAME = "com.neobear";
    private static LruCache mAppBitmapCache = null;
    private static Context mContext;

    /**
     * 保存bitmap图片到本地
     *
     * @param filePath
     * @param pathName
     * @param isClearWhenInit
     * @return
     */
    public static String saveBitmap(Context context,String filePath, String pathName, boolean isClearWhenInit) {
        mContext = context;
        Bitmap bitmap = getBitmapWithPath(filePath);

        if (bitmap == null) {
            return "";
        }

        String path = "";
        if (isClearWhenInit) {
            path = getSharePicFile() + pathName;
        } else {
            path = getUploadPicFile() + pathName;
        }
        File file = new File(path);
        if (file.exists()) {
            return path;
        }

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
        int bitmapSize = baos.toByteArray().length / 2;
        Bitmap cacheBitmap = null;
        double imageSize = bitmapSize / 1024 / 1024;
        // 对可用内存进行判断,来决定压缩策略。。。。需要修改的
        if (imageSize >= 1) {
            cacheBitmap = resizeImage(bitmap, 1080, path);
        } else {
            cacheBitmap = resizeImage(bitmap, path);
        }

        if (cacheBitmap == null) {
            path = "";
        }
        if (cacheBitmap != null && !cacheBitmap.isRecycled()) {
            cacheBitmap.recycle();
        }
        return path;
    }

    /**
     * 文件转换成bitmap
     *
     * @param path
     * @return
     */
    private static Bitmap getBitmapWithPath(String path) {
        Bitmap bmp = null;
        try {
            bmp = ImageFileUtils.readNormalPic(path, widthPixels, heightPixels);
        } catch (OutOfMemoryError e) {
            getBitmapCache().evictAll();
            try {
                bmp = ImageFileUtils.readNormalPic(path, widthPixels, heightPixels);
            } catch (OutOfMemoryError e2) {
            }
        }
        return bmp;
    }

    private static Bitmap readNormalPic(String filePath, int reqWidth, int reqHeight) {
        try {
            if (!isExternalStorageMounted()) {
                return null;
            }

            if (!filePath.endsWith(".jpg") && !filePath.endsWith(".gif") && !filePath.endsWith(".png") && !filePath.endsWith(".jpeg"))
                filePath = filePath + ".jpg";

            boolean fileExist = new File(filePath).exists();

            if (!fileExist) {
                return null;
            }

            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            BitmapFactory.decodeFile(filePath, options);

            if (reqHeight > 0 && reqWidth > 0)
                options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
            options.inJustDecodeBounds = false;
            options.inPurgeable = true;
            options.inInputShareable = true;

            Bitmap bitmap = BitmapFactory.decodeFile(filePath, options);

            if (bitmap == null) {
                // this picture is broken,so delete it
                new File(filePath).delete();
                return null;
            }

            if (reqHeight > 0 && reqWidth > 0) {
                int[] size = calcResize(bitmap.getWidth(), bitmap.getHeight(), reqWidth, reqHeight);
                if (size[0] > 0 && size[1] > 0) {
                    Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, size[0], size[1], true);
                    if (scaledBitmap != bitmap) {
                        bitmap.recycle();
                        bitmap = scaledBitmap;
                    }
                }
            }

            int exifRotation = ImageFileUtils.getFileExifRotation(filePath);
            if (exifRotation != 0) {
                Matrix mtx = new Matrix();
                mtx.postRotate(exifRotation);
                Bitmap adjustedBitmap = Bitmap.createBitmap(bitmap, 0, 0,
                        bitmap.getWidth(), bitmap.getHeight(), mtx, true);
                if (adjustedBitmap != bitmap) {
                    bitmap.recycle();
                    bitmap = adjustedBitmap;
                }
            }

            return bitmap;
        } catch (OutOfMemoryError ignored) {
            ignored.printStackTrace();
            return null;
        }
    }

    private static synchronized LruCache getBitmapCache() {
        if (mAppBitmapCache == null) {
            buildCache();
        }
        return mAppBitmapCache;
    }

    private static void buildCache() {
        int memClass = ((ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE)).getMemoryClass();
        int cacheSize = Math.max(1024 * 1024 * 8, 1024 * 1024 * memClass / 6);

        mAppBitmapCache = new LruCache(cacheSize) {
            @Override
            protected int sizeOf(String key, Bitmap bitmap) {

                return bitmap.getRowBytes() * bitmap.getHeight();
            }
        };
    }

    private static boolean isExternalStorageMounted() {
        boolean canRead = Environment.getExternalStorageDirectory().canRead();
        boolean onlyRead = Environment.getExternalStorageState().equals(
                Environment.MEDIA_MOUNTED_READ_ONLY);
        boolean unMounted = Environment.getExternalStorageState().equals(
                Environment.MEDIA_UNMOUNTED);

        return !(!canRead || onlyRead || unMounted);
    }

    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) {
            if (height > reqHeight && reqHeight != 0) {
                inSampleSize = (int) Math.floor((double) height / (double) reqHeight);
            }

            int tmp = 0;

            if (width > reqWidth && reqWidth != 0) {
                tmp = (int) Math.floor((double) width / (double) reqWidth);
            }

            inSampleSize = Math.max(inSampleSize, tmp);

        }
        int roundedSize;
        if (inSampleSize <= 8) {
            roundedSize = 1;
            while (roundedSize < inSampleSize) {
                roundedSize <<= 1;
            }
        } else {
            roundedSize = (inSampleSize + 7) / 8 * 8;
        }

        return roundedSize;
    }

    private static int[] calcResize(int actualWidth, int actualHeight, int reqWidth, int reqHeight) {
        int height = actualHeight;
        int width = actualWidth;

        float betweenWidth = ((float) reqWidth) / (float) actualWidth;
        float betweenHeight = ((float) reqHeight) / (float) actualHeight;

        float min = Math.min(betweenHeight, betweenWidth);

        height = (int) (min * actualHeight);
        width = (int) (min * actualWidth);

        return new int[]{width, height};
    }

    private static int getFileExifRotation(String filePath) {
        try {
            ExifInterface exifInterface = new ExifInterface(filePath);
            int orientation = exifInterface.getAttributeInt(TAG_ORIENTATION,
                    ORIENTATION_NORMAL);
            switch (orientation) {
                case ORIENTATION_ROTATE_90:
                    return 90;
                case ORIENTATION_ROTATE_180:
                    return 180;
                case ORIENTATION_ROTATE_270:
                    return 270;
                default:
                    return 0;
            }
        } catch (IOException e) {
            return 0;
        }
    }

    private static String getSharePicFile() {
        return sdCardIsExist() ? getSDAccessPath() + "/file/share/" : "/data/data/" + PACKAGE_NAME + "/files/share/";
    }

    private static String getUploadPicFile() {
        return sdCardIsExist() ? getSDAccessPath() + "/file/" : "/data/data/" + PACKAGE_NAME + "/files/";
    }

    /**
     * 判断sdCard的状态
     *
     * @author zhangbp
     */
    private static boolean sdCardIsExist() {
        return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
    }

    /**
     * 读取sdCard的路径
     *
     * @author zhangbp
     */
    private static String getSDAccessPath() {
        if (sdCardIsExist()) {
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
                return Environment.getExternalStorageDirectory().getPath() + "/data/" + PACKAGE_NAME;
            } else {
                return mContext.getExternalCacheDir() + "";
            }
        }
        return null;
    }

    private static Bitmap resizeImage(Bitmap bitmap, int w, String filePath) {
        Bitmap BitmapOrg = bitmap;
        int width = BitmapOrg.getWidth();
        int height = BitmapOrg.getHeight();
        int newWidth = 0;
        int newHeight = 0;
        if (width > height) {
            newWidth = w;
            newHeight = (int) (((float) height) / width * w);
        } else {
            newWidth = (int) (((float) width) / height * w);
            newHeight = w;
        }
        // calculate the scale
        float scaleWidth = ((float) newWidth) / width;
        float scaleHeight = ((float) newHeight) / height;
        // create a matrix for the manipulation
        Matrix matrix = new Matrix();
        // resize the Bitmap
        matrix.postScale(scaleWidth, scaleHeight);
        // if you want to rotate the Bitmap
        // matrix.postRotate(readPictureDegree(filePath));
        // recreate the new Bitmap
        Bitmap resizedBitmap = Bitmap.createBitmap(BitmapOrg, 0, 0, width,
                height, matrix, true);
        resizedBitmap = compressImage(resizedBitmap, filePath);
        return resizedBitmap;
    }

    private static Bitmap resizeImage(Bitmap bitmap, String filePath) {
        Bitmap BitmapOrg = bitmap;
        int width = BitmapOrg.getWidth();
        int height = BitmapOrg.getHeight();

        Bitmap resizedBitmap = Bitmap.createBitmap(BitmapOrg, 0, 0, width,
                height, null, true);
        resizedBitmap = compressImage(resizedBitmap, filePath);
        return resizedBitmap;
    }

    private static Bitmap compressImage(Bitmap image, String filePath) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        image.compress(Bitmap.CompressFormat.JPEG, 80, baos);// 质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
        int options = 100;
        while (baos.toByteArray().length / 1024 > 80) { // 循环判断如果压缩后图片是否大于100kb,大于继续压缩
            if (options >= 10) {
                baos.reset();// 重置baos即清空baos
                image.compress(Bitmap.CompressFormat.JPEG, options, baos);// 这里压缩options%,把压缩后的数据存放到baos中
                options -= 10;// 每次都减少10
            } else {
                break;
            }
        }

        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
        final BitmapFactory.Options ops = new BitmapFactory.Options();
        ops.inJustDecodeBounds = false;
        ops.inPreferredConfig = Bitmap.Config.ARGB_8888;
        ops.inPurgeable = true;//允许可清除
        ops.inInputShareable = true;// 以上options的两个属性必须联合使用才会有效果

        Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);// 把ByteArrayInputStream数据生成图片
        try {
            createFile(filePath);
            File file = new File(filePath);
            BufferedOutputStream bos = new BufferedOutputStream(
                    new FileOutputStream(file));
            bitmap.compress(Bitmap.CompressFormat.JPEG, 80, bos);
            bos.flush();
            bos.close();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        if (image != null && !image.isRecycled()) {
            image.recycle();
        }
        return bitmap;
    }

    private static boolean createFile(String destFileName) {
        File file = new File(destFileName);
        if (!file.getParentFile().exists()) {
            // 如果目标文件所在的目录不存在,则创建父目录
            if (!file.getParentFile().mkdirs()) {
                return false;
            }
        }
        if (destFileName.endsWith(File.separator)) {
            return false;
        }
        // 判断目标文件所在的目录是否存在
        // 创建目标文件
        if (file.exists()) {
            return true;
        }
        try {
            return file.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
    }
}

使用

ImageFileUtils.saveBitmap(context,filepath,filename,false);

你可能感兴趣的:(Android)