Android——图片压缩

本文主要介绍了在Android开发中遇到的图片处理问题,包括图片压缩和角度判断。总结了从SD卡路径压缩图片的方法,并提及图片可能存在的旋转问题。提供了一个相关工具类的来源链接。
摘要由CSDN通过智能技术生成

曾经遇到的坑:
1、对图片进行处理时,忘记了非空判断
2、对ImageView设置图片时,没有做角度判断,有的图片是旋转了90度的
3 ……

下面的工具类转自:http://blog.csdn.net/pengkv/article/details/50174985
1、根据SD卡中路径压缩图片

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Environment;
import android.text.TextUtils;
import android.util.Log;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import utils.ImageRotateUtil;

/**
 * Created by pengkv on 15/12/2.
 * 图片压缩工具类
 */
public class ImageCompressUtil {

    private static List<String> mImageList = new ArrayList<>();// 临时图片集合
    private static String mImagePath = ""; // 单个临时图片
    public static String cachePath = "";
    public static int reqWidth = 320;
    public static int reqHeight = 480;

    //压缩单张图片方法
    public static void compressImage(final Context ctx, final String filePath, final ProcessImgCallBack callBack) {
        mImagePath = "";//清空路径

        new Thread(new Runnable() {
            @Override
            public void run() {
                //如果路径是图片,则进行压缩
                if (isImage(filePath)) {
                    mImagePath = compress(ctx, filePath);
                }
                callBack.compressSuccess(mImagePath);
            }
        }).start();
    }

    //压缩图片集合方法
    public static void compressImageList(final Context ctx, final List<String> fileList, final ProcessImgListCallBack callBack) {
        mImageList.clear();//清空集合
        if (fileList == null || fileList.isEmpty()) {
            callBack.compressSuccess(mImageList);
            return;
        }
        new Thread(new Runnable() {
            @Override
            public void run() {
                String tempPath = "";
                for (String imagePath : fileList) {
                    if (isImage(imagePath)) {
                        tempPath = compress(ctx, imagePath);
                        mImageList.add(tempPath);
                    }
                }
                callBack.compressSuccess(mImageList);
            }
        }).start();

    }

    //图片压缩的方法
    public static String compress(Context ctx, String filePath) {

        if (TextUtils.isEmpty(filePath))
            return filePath;

        File file = new File(filePath);
        if (!file.exists())//判断路径是否存在
            return filePath;

        if (file.length() < 1)//文件是否为空
            return null;

        File tempFile = getDiskCacheDir(ctx);
        String outImagePath = tempFile.getAbsolutePath(); // 输出图片文件路径


        int degree = ImageRotateUtil.getBitmapDegree(filePath); // 检查图片的旋转角度

        //谷歌官网压缩图片
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(filePath, options);
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
        options.inJustDecodeBounds = false;
        Bitmap bitmap = BitmapFactory.decodeFile(filePath, options);

        // 旋转:这步处理主要是为了处理三星手机拍的照片
        if (degree > 0) {
            bitmap = ImageRotateUtil.rotateBitmapByDegree(bitmap, degree);
        }

        // 写入文件
        FileOutputStream fos;
        try {
            fos = new FileOutputStream(tempFile);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 70, fos);
            fos.flush();
            fos.close();
            bitmap.recycle();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return filePath;
        } catch (Exception e) {
            e.printStackTrace();
            return filePath;
        }

        return outImagePath;
    }


    /**
     * 计算压缩比例值
     * 按照2、3、4...倍压缩
     *
     * @param options   解析图片的配置信息
     * @param reqWidth  所需图片压缩尺寸最小宽度
     * @param reqHeight 所需图片压缩尺寸最小高度
     * @return
     */
    public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
        final int picheight = options.outHeight;
        final int picwidth = options.outWidth;
        Log.i("--->", "原尺寸:" + picwidth + "*" + picheight);

        int targetheight = picheight;
        int targetwidth = picwidth;
        int inSampleSize = 1;

        if (targetheight > reqHeight || targetwidth > reqWidth) {
            while (targetheight >= reqHeight && targetwidth >= reqWidth) {
                inSampleSize += 1;
                targetheight = picheight / inSampleSize;
                targetwidth = picwidth / inSampleSize;
            }
        }

        Log.i("--->", "最终压缩比例:" + inSampleSize + "倍/新尺寸:" + targetwidth + "*" + targetheight);
        return inSampleSize;
    }


    //图片集合压缩成功后的回调接口
    public interface ProcessImgListCallBack {
        void compressSuccess(List<String> imgList);
    }

    //单张图片压缩成功后的回调接口
    public interface ProcessImgCallBack {
        void compressSuccess(String imgPath);
    }


    /**
     * 获取文件后缀名
     *
     * @param fileName
     * @return 文件后缀名
     */
    public static String getFileType(String fileName) {
        if (!TextUtils.isEmpty(fileName)) {
            int typeIndex = fileName.lastIndexOf(".");
            if (typeIndex != -1) {
                String fileType = fileName.substring(typeIndex + 1).toLowerCase();
                return fileType;
            }
        }
        return "";
    }

    /**
     * 判断是否是图片
     *
     * @param fileName
     * @return 是否是图片类型
     */
    public static boolean isImage(String fileName) {
        String type = getFileType(fileName);
        if (!TextUtils.isEmpty(type) && (type.equals("jpg") || type.equals("gif")
                || type.equals("png") || type.equals("jpeg")
                || type.equals("bmp") || type.equals("wbmp")
                || type.equals("ico") || type.equals("jpe"))) {
            return true;
        }
        return false;
    }

    /**
     * 将压缩后的图片存储在缓存中
     */
    public static File getDiskCacheDir(Context ctx) {
        if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())
                || !Environment.isExternalStorageRemovable()) {
            cachePath = ctx.getExternalCacheDir().getPath();
        } else {
            cachePath = ctx.getCacheDir().getPath();
        }
        String uniqueName = System.currentTimeMillis() + "_tmp.jpg";
        return new File(cachePath + File.separator + uniqueName);
    }

    /**
     * 清理缓存文件夹
     */
    public static void clearCache(Context ctx) {
        File file = new File(cachePath);
        File[] childFile = file.listFiles();
        if (childFile == null || childFile.length == 0) {
            return;
        }

        for (File f : childFile) {
            f.delete(); // 循环删除子文件
        }
    }


    /**
     * 从图片路径读取出图片
     *
     * @param imagePath
     * @return
     */
    private Bitmap decodeFile(String imagePath) {
        Bitmap bitmap = null;
        try {
            File file = new File(imagePath);
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = false;
            FileInputStream fis = new FileInputStream(file);
            bitmap = BitmapFactory.decodeStream(fis, null, options);
            fis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return bitmap;
    }
}

图片旋转

import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.media.ExifInterface;

import java.io.IOException;

/**
 * Created by pengkv on 15/12/2.
 * 图片旋转工具类
 */
public class ImageRotateUtil {

    /**
     * 读取图片的旋转的角度
     *
     * @param path 图片绝对路径
     * @return 图片的旋转角度
     */
    public static int getBitmapDegree(String path) {
        int degree = 0;
        try {
            // 从指定路径下读取图片,并获取其EXIF信息
            ExifInterface exifInterface = new ExifInterface(path);
            // 获取图片的旋转信息
            int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,
                    ExifInterface.ORIENTATION_NORMAL);
            switch (orientation) {
                case ExifInterface.ORIENTATION_ROTATE_90:
                    degree = 90;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    degree = 180;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                    degree = 270;
                    break;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return degree;
    }

    /**
     * 将图片按照某个角度进行旋转
     *
     * @param bm     需要旋转的图片
     * @param degree 旋转角度
     * @return 旋转后的图片
     */
    public static Bitmap rotateBitmapByDegree(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) {
            e.printStackTrace();
            //当内存溢出时,利用递归进行重新旋转
            while (returnBm == null) {
                System.gc();
                System.runFinalization();
                returnBm = rotateBitmapByDegree(bm, degree);
            }
        }
        if (returnBm == null) {
            returnBm = bm;
        }
        if (bm != returnBm) {
            bm.recycle();
        }
        return returnBm;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值