Android 处理大图片

来源:互联网 发布:网络电视显示无信号 编辑:程序博客网 时间:2024/05/16 02:08
package com.example.utils;import java.io.ByteArrayOutputStream;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.nio.ByteBuffer;import java.nio.channels.Channels;import java.nio.channels.ReadableByteChannel;import android.annotation.SuppressLint;import android.content.Context;import android.content.Intent;import android.content.res.Resources;import android.graphics.Bitmap;import android.graphics.Bitmap.CompressFormat;import android.graphics.BitmapFactory;import android.graphics.BitmapFactory.Options;import android.graphics.Matrix;import android.media.ExifInterface;import android.net.Uri;import android.os.Build;public class BitmapUtils {    public final static int getDegress(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 rotateBitmap(Bitmap bitmap, int degress) {        if (bitmap != null) {            Matrix m = new Matrix();            m.postRotate(degress);             bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), m, true);            return bitmap;        }        return bitmap;    }    public final static int caculateInSampleSize(BitmapFactory.Options options, int rqsW, int rqsH) {        final int height = options.outHeight;        final int width = options.outWidth;        int inSampleSize = 1;        if (rqsW == 0 || rqsH == 0) return 1;        if (height > rqsH || width > rqsW) {            final int heightRatio = Math.round((float) height/ (float) rqsH);            final int widthRatio = Math.round((float) width / (float) rqsW);            inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;        }        return inSampleSize;    }    /**     * 压缩指定路径的图片,并得到图片对象     * @param context     * @param path bitmap source path     * @return Bitmap {@link android.graphics.Bitmap}     */    public final static Bitmap compressBitmap(String path, int rqsW, int rqsH) {        final BitmapFactory.Options options = new BitmapFactory.Options();        options.inJustDecodeBounds = true;        BitmapFactory.decodeFile(path, options);        options.inSampleSize = caculateInSampleSize(options, rqsW, rqsH);        options.inJustDecodeBounds = false;        return BitmapFactory.decodeFile(path, options);    }    /**     * 压缩指定路径图片,并将其保存在缓存目录中,通过isDelSrc判定是否删除源文件,并获取到缓存后的图片路径     * @param context     * @param srcPath     * @param rqsW     * @param rqsH     * @param isDelSrc     * @return     */    public final static String compressBitmap(Context context, String srcPath,String desPath, int rqsW, int rqsH, boolean isDelSrc) {        Bitmap bitmap = compressBitmap(srcPath, rqsW, rqsH);        File srcFile = new File(srcPath);        int degree = getDegress(srcPath);        try {            if (degree != 0) bitmap = rotateBitmap(bitmap, degree);            File file = new File(desPath);            if(srcFile.getAbsolutePath() != file.getAbsolutePath()){                FileOutputStream  fos = new FileOutputStream(file);                bitmap.compress(Bitmap.CompressFormat.PNG, 40, fos);                fos.close();            }            if (isDelSrc) srcFile.deleteOnExit();        } catch (Exception e) {            e.printStackTrace();        }        return desPath;    }    /**     * 刷新相册     * @param context     * @param imgFileName     */    private static void scanPhoto(Context context, String imgFileName)    {        Intent mediaScanIntent = new Intent("android.intent.action.MEDIA_SCANNER_SCAN_FILE");        File file = new File(imgFileName);        Uri contentUri = Uri.fromFile(file);        mediaScanIntent.setData(contentUri);        context.sendBroadcast(mediaScanIntent);    }    /**     * 压缩某个输入流中的图片,可以解决网络输入流压缩问题,并得到图片对象     * @param context     * @param path bitmap source path     * @return Bitmap {@link android.graphics.Bitmap}     */    public final static Bitmap compressBitmap(InputStream is, int reqsW, int reqsH) {        try {            ByteArrayOutputStream baos = new ByteArrayOutputStream();            ReadableByteChannel channel = Channels.newChannel(is);            ByteBuffer buffer = ByteBuffer.allocate(1024);            while (channel.read(buffer) != -1) {                buffer.flip();                while (buffer.hasRemaining()) baos.write(buffer.get());                buffer.clear();            }            byte[] bts = baos.toByteArray();            Bitmap bitmap = compressBitmap(bts, reqsW, reqsH);            is.close();            channel.close();            baos.close();            return bitmap;        } catch (Exception e) {            e.printStackTrace();            return null;        }    }    /**     * 压缩指定byte[]图片,并得到压缩后的图像     * @param bts     * @param reqsW     * @param reqsH     * @return     */    public final static Bitmap compressBitmap(byte[] bts, int reqsW, int reqsH) {        final Options options = new Options();        options.inJustDecodeBounds = true;        BitmapFactory.decodeByteArray(bts, 0, bts.length, options);        options.inSampleSize = caculateInSampleSize(options, reqsW, reqsH);        options.inJustDecodeBounds = false;        return BitmapFactory.decodeByteArray(bts, 0, bts.length, options);    }    /**     * 压缩已存在的图片对象,并返回压缩后的图片     * @param bitmap     * @param reqsW     * @param reqsH     * @return     */    public final static Bitmap compressBitmap(Bitmap bitmap, int reqsW, int reqsH) {        try {            ByteArrayOutputStream baos = new ByteArrayOutputStream();            bitmap.compress(CompressFormat.PNG, 100, baos);            byte[] bts = baos.toByteArray();            Bitmap res = compressBitmap(bts, reqsW, reqsH);            baos.close();            return res;        } catch (IOException e) {            e.printStackTrace();            return bitmap;        }    }    /**     * 压缩资源图片,并返回图片对象     * @param res {@link android.content.res.Resources}     * @param resID     * @param reqsW     * @param reqsH     * @return     */    public final static Bitmap compressBitmap(Resources res, int resID, int reqsW, int reqsH) {        final Options options = new Options();        options.inJustDecodeBounds = true;        BitmapFactory.decodeResource(res, resID, options);        options.inSampleSize = caculateInSampleSize(options, reqsW, reqsH);        options.inJustDecodeBounds = false;        return BitmapFactory.decodeResource(res, resID, options);    }    /**     * 基于质量的压缩算法, 此方法未 解决压缩后图像失真问题     * <br> 可先调用比例压缩适当压缩图片后,再调用此方法可解决上述问题     * @param bts     * @param maxBytes 压缩后的图像最大大小 单位为byte     * @return     */    public final static Bitmap compressBitmap(Bitmap bitmap, long maxBytes) {        try {            ByteArrayOutputStream baos = new ByteArrayOutputStream();            bitmap.compress(CompressFormat.PNG, 100, baos);            int options = 90;            while (baos.toByteArray().length > maxBytes) {                baos.reset();                bitmap.compress(CompressFormat.PNG, options, baos);                options -= 10;            }            byte[] bts = baos.toByteArray();            Bitmap bmp = BitmapFactory.decodeByteArray(bts, 0, bts.length);            baos.close();            return bmp;        } catch (IOException e) {            e.printStackTrace();            return null;        }    }    /**     * 得到指定路径图片的options     * @param srcPath     * @return Options {@link android.graphics.BitmapFactory.Options}     */    public final static Options getBitmapOptions(String srcPath) {        BitmapFactory.Options options = new BitmapFactory.Options();        options.inJustDecodeBounds = true;        BitmapFactory.decodeFile(srcPath, options);        return options;    }    /**     * 获取本地图片byte[]     * @param bmp     * @param needRecycle     * @return     */    public static byte[] bmpToByteArray(final Bitmap bmp, final boolean needRecycle) {        ByteArrayOutputStream output = new ByteArrayOutputStream();        bmp.compress(CompressFormat.PNG, 100, output);        if (needRecycle) {            bmp.recycle();        }        byte[] result = output.toByteArray();        try {            output.close();        } catch (Exception e) {            e.printStackTrace();        }        return result;    }    public static void closeStream(OutputStream os){        if(os != null){            try {                os.close();            } catch (IOException e) {                e.printStackTrace();            }        }    }    public static void closeStream(InputStream os){        if(os != null){            try {                os.close();            } catch (IOException e) {                e.printStackTrace();            }        }    }    @SuppressLint("NewApi")    public static int getBitmapsize(Bitmap bp){        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1) {            return bp.getByteCount() / 1024;        }        return bp.getRowBytes() * bp.getHeight() / 1024;    }    /**     * 初步处理大图片 :大小压缩     * @param imgFilePath     * @param smartSpace     * @return     */    public static Bitmap scaleCompressBp(String imgFilePath,long smartSpace){        File file = new File(imgFilePath);        if(!file.exists() || !file.isFile()){            throw new IllegalArgumentException("file not exists or file is not a image file");        }        long scalebefore = (file.length()/1024)/smartSpace;        double sqrt = Math.sqrt(scalebefore);        BitmapFactory.Options options = new BitmapFactory.Options();        options.inJustDecodeBounds = false;        if((int)sqrt <= 1) sqrt = 1;        options.inSampleSize = (int) sqrt;        return BitmapFactory.decodeFile(imgFilePath,options);    }    /**     * 进一步处理图片 : 进行质量压缩     * desSize 不能太小失真很严重     * @param bitmap     * @param desSize     * @return     */    private static byte[] qualityCompressBp(Bitmap bitmap,int desSize) {          byte[] desBytes = null;        ByteArrayOutputStream baos = new ByteArrayOutputStream();          bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);        int options = 100;          int length = baos.toByteArray().length;        while (length / 1024 > desSize) {              baos.reset();            bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);            options -= 3;            if(options <= 10) break;        }          desBytes = baos.toByteArray();        closeStream(baos);        return desBytes;      }    /**     * 对图片进行压缩处理      * 在 华为4x 1300万摄像头下进行测试的结果 原始图片 2.49M 压缩后在300kb左右 其中smartSpace 50  desSize 300     * 根据处理文件大小的不同 来设置相应的smartSpace因子 和 desSize;     * @param imgFilePath  原始图片文件路径     * @param smartSpace     * @return     */    public static Bitmap smartCompressBp(String imgFilePath,long smartSpace,int desSize){        Bitmap scaleCompressBp = scaleCompressBp(imgFilePath,smartSpace);        byte[] qualityCompressBp = qualityCompressBp(scaleCompressBp,desSize);        return BitmapFactory.decodeByteArray(qualityCompressBp, 0, qualityCompressBp.length);    }    // 初步压缩  :大小压缩    public static Bitmap scaleCompressBp(Bitmap bp,long smartSpace){        long scalebefore = getBitmapsize(bp)/smartSpace;        double sqrt = Math.sqrt(scalebefore);        BitmapFactory.Options options = new BitmapFactory.Options();        options.inJustDecodeBounds = false;        if((int)sqrt <= 1) sqrt = 1;        options.inSampleSize = (int) sqrt;        ByteArrayOutputStream aos = new ByteArrayOutputStream();        bp.compress(Bitmap.CompressFormat.JPEG, 100, aos);        return BitmapFactory.decodeByteArray(aos.toByteArray(), 0, aos.toByteArray().length);    }    // 对中等大小的图片进行处理 比如对 700kb大图片进行处理    public static Bitmap smartCompressBp(Bitmap srcBitmap,long smartSpace,int desSize){        Bitmap scaleCompressBp = scaleCompressBp(srcBitmap,smartSpace);        byte[] qualityCompressBp = qualityCompressBp(scaleCompressBp,desSize);        return BitmapFactory.decodeByteArray(qualityCompressBp, 0, qualityCompressBp.length);    }}
0 0
原创粉丝点击