图片处理工具类

1

package com.example.util;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.os.Environment;
import android.util.Log;
import android.widget.Toast;

import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.ImageRequest;
import com.example.volley.VolleyQueue;
import com.will.main.WillApplication;

/**
 * @author JL 一个Bitmap到底占用多大内存?系统给每个应用程序分配多大内存?
 * 
 *         Bitmap占用的内存为:像素总数 *
 *         每个像素占用的内存。在Android中,Bitmap有四种像素类型:ARGB_8888、ARGB_4444
 *         、ARGB_565、ALPHA_8 他们每个像素占用的字节数分别为4、2、2、1。
 *         因此,一个2000*1000的ARGB_8888类型的Bitmap占用的内存为2000 *1000*4=8000000B=8MB。
 */
public class PhotoUtil {
    private static String tag = "PhotoUtil";
    private final static String ALBUM_PATH = Environment
            .getExternalStorageDirectory() + "/Real/Image/";

    /**
     * 读取图片属性:旋转的角度
     * 
     * @param path
     *            图片绝对路径
     * @return degree旋转的角度
     */
    public static int readPictureDegree(String path) {
        int degree = 0;
        try {
            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;
    }

    public static Bitmap rotaingImageView(int degree, Bitmap bm) {
        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();
        }
        if (returnBm == null) {
            returnBm = bm;
        }
        if (bm != returnBm) {
            bm.recycle();
        }
        return returnBm;
    }

    // 缩放图片
    public static Bitmap zoomImg(Bitmap bm, int newWidth, int newHeight) {
        // 获得图片的宽高
        int width = bm.getWidth();
        int height = bm.getHeight();
        // 计算缩放比例
        float scaleWidth = ((float) newWidth) / width;
        float scaleHeight = ((float) newHeight) / height;
        // 取得想要缩放的matrix参数
        Matrix matrix = new Matrix();
        matrix.postScale(scaleWidth, scaleHeight);
        // 得到新的图片
        Bitmap newbm = null;
        try {
            newbm = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, true);
        } catch (OutOfMemoryError e) {
            e.printStackTrace();
        }
        if (newbm == null) {
            newbm = bm;
        }
        if (bm != newbm) {
            bm.recycle();
        }
        return newbm;
    }

    /**
     * 根据宽来等比例约束图片的大小
     * 
     * @param path
     * @param width
     * @return
     */
    public static BitmapFactory.Options getBitmapSize(String path) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        // 如果值设为true,那么将不返回实际的bitmap,也不给其分配内存空间,只去加载图片的外边缘,这样就避免了内存溢出。
        options.inJustDecodeBounds = true;
        // 最终大小是1/inSampleSize
        // options.inSampleSize = 1;
        Bitmap bm = BitmapFactory.decodeFile(path, options);
        return options;
    }

    public static Bitmap decodebitmapByWidthWithRotate(String path,
            int widthPixels) {
        // TODO Auto-generated method stub
        int degree = PhotoUtil.readPictureDegree(path);
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = false;
        Bitmap bitmap = null;
        try {
            bitmap = BitmapFactory.decodeFile(path, options);
            bitmap = PhotoUtil.rotaingImageView(degree, bitmap);
        } catch (OutOfMemoryError e) {
            e.printStackTrace();
        }
        if (bitmap == null) {
            // 这里能出来,是因为options.inJustDecodeBounds = true;
            // 只是options被赋值了
            return null;
        }

        float rate = (float) widthPixels / bitmap.getWidth();

        Bitmap resizeBmp = Bitmap.createScaledBitmap(bitmap, widthPixels,
                (int) (rate * bitmap.getHeight()), true);
        bitmap.recycle();
        return resizeBmp;
    }

    public static void saveImageByUrl(String imageUrl) {
        if (!Environment.getExternalStorageState().equals(
                Environment.MEDIA_MOUNTED)) {
            // new File(File dir, String name);在dir的目录下建一个name文件夹并返回
            // getExternalCacheDir的路径是/sdcard/Android/data/<application
            // package>/cache
            Toast.makeText(WillApplication.getInstance(), "未找到sd卡",
                    Toast.LENGTH_SHORT).show();
            return;
        }
        ImageRequest imageRequest = new ImageRequest(imageUrl,
                new Response.Listener<Bitmap>() {
                    @Override
                    public void onResponse(Bitmap response) {
                        saveImageByBitmap(response);
                    }
                }, 0, 0, Config.RGB_565, new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {

                        Toast.makeText(WillApplication.getInstance(),
                                "出错了,请稍后重试", Toast.LENGTH_SHORT).show();
                    }
                });
        VolleyQueue.getInstance().add(imageRequest);
    }

    public static void saveImageByBitmap(Bitmap bitmap) {
        if (!Environment.getExternalStorageState().equals(
                Environment.MEDIA_MOUNTED)) {
            // new File(File dir, String name);在dir的目录下建一个name文件夹并返回
            // getExternalCacheDir的路径是/sdcard/Android/data/<application
            // package>/cache
            Toast.makeText(WillApplication.getInstance(), "未找到sd卡",
                    Toast.LENGTH_SHORT).show();
            return;
        }

        FileOutputStream fileOutputStream = null;
        try {
            File dirFile = new File(ALBUM_PATH);
            if (!dirFile.exists()) {
                dirFile.mkdirs();
            }
            File imageFile = new File(dirFile, bitmap.hashCode() + ".jpg");

            if (!imageFile.exists()) {
                imageFile.createNewFile(); // 新建文件
            }
            fileOutputStream = new FileOutputStream(imageFile);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 60, fileOutputStream);
            Log.i(tag,  imageFile.getName());
            Toast.makeText(WillApplication.getInstance(),
                    "图片保存至/sdcard/Real/Image" + imageFile.getName(),
                    Toast.LENGTH_SHORT).show();

        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {

            try {
                if (fileOutputStream != null) {
                    fileOutputStream.flush();
                    fileOutputStream.close();
                }
                if (bitmap.isRecycled()) {
                    bitmap.recycle();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }

}

Done!

原文地址:https://www.cnblogs.com/xingyyy/p/4356717.html