Android高品質高圧縮比画像圧縮


一般的にAndroidプロジェクトでは、アルバムから写真を選択してサーバーにアップロードする必要がありますが、fileファイルを直接アップロードすることはできません.画素の高い携帯電話では、1300万台のカメラが最大9-10 mに達するなど、撮影された写真の体積も大きくなります.このようにアップロードする前に圧縮する必要がありますが、雰囲気の画像サイズの圧縮と品質の圧縮を圧縮する必要があります.圧縮中にOOMが発生する可能性が高いので、以下は画像圧縮ツール類で、まず画像幅の高い圧縮を行い、比較的大きな画像を1280*1280の大きさ範囲に圧縮してoomを減らし、その後品質の圧縮を行い、一般的に品質は70-100の間に維持され、肉眼ではほとんど差が見えないが、大きさは明らかに改善することができ、圧縮後の大きさ範囲は100 k-200 kの間で、サーバへのアップロードが容易です.幅の高い圧縮と品質の圧縮はそれぞれ1回実行して、循環圧縮がないので、私はいくつかの循環圧縮の方案が往々にして画像の品質を著しく低下させることを発見して、俗に写真のペーストと呼ばれています.
package com.example.administrator.jnidemo;


import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.os.Build;
import android.util.Log;

import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

/**
 * Created by Administrator on 2016/4/6.
 */
public class AlxBitMapUtils {

    /**
     *     bitmap,            
     * @param bitmap
     * @param widthRatio     ,    1 ,    1 
     * @param heightRatio
     * @return
     */
    public static Bitmap scaleBitmap(Bitmap bitmap, float widthRatio, float heightRatio) {
        Matrix matrix = new Matrix();
        matrix.postScale(widthRatio,heightRatio);
        return Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(),bitmap.getHeight(),matrix,true);
    }

    /**
     *       ,        ,     ,     
     * @param oriFile    
     * @param targetFile     stream     
     * @param ifDel               
     */
    public static void compressImage(File oriFile, File targetFile, OutputStream stream,boolean ifDel) {
        if(oriFile ==null)return;
        Log.i("Alex","    "+oriFile);
        Log.i("Alex","     "+targetFile);
        try {
            BitmapFactory.Options opts = new BitmapFactory.Options();
            opts.inJustDecodeBounds = true; //            ,        ,    
            BitmapFactory.decodeFile(oriFile.getAbsolutePath(), opts);//      ,   Options   
            //  Options         
            int imageHeight = opts.outHeight;
            int imageWidth = opts.outWidth;
            int longEdge = Math.max(imageHeight,imageWidth);//        
            int pixelCount = (imageWidth*imageHeight)>>20;//             
            Log.i("Alex","    "+imageWidth+"    "+imageHeight+"      "+pixelCount+"    ");

            long size = oriFile.length();
            Log.i("Alex","f.length      "+(size)+" B");
            //        ,      bitmap
            Bitmap bitmap = null;
            if(pixelCount > 4){//     4    ,            
                float compressRatio = longEdge /1280f;
                int compressRatioInt = Math.round(compressRatio);
                if(compressRatioInt%2!=0 && compressRatioInt!=1)compressRatioInt++;//       ,      
                Log.i("Alex","      "+compressRatio+"     "+compressRatioInt);
                //    
                BitmapFactory.Options options = new BitmapFactory.Options();
                //       1024*1024 1    ,100k  
                options.inSampleSize = Math.round(compressRatioInt);//  ,       ,            ,        1280*1.5,     ,           
                options.inJustDecodeBounds = false;// decode file   ,         ,         
                options.inPreferredConfig = Bitmap.Config.RGB_565;//       , R=5,G=6,B=5,     ,        5+6+5=16 
                //     bitmap    
                bitmap = BitmapFactory.decodeFile(oriFile.getAbsolutePath(), options);//               bitmap
                //           bitmap  
            }else {//           1920  ,         
                //      bitmap    
                bitmap = BitmapFactory.decodeFile(oriFile.getAbsolutePath());
                //      bitmap        
            }
            if(targetFile!=null)compressMethodAndSave(bitmap, targetFile);
            if(stream!=null)compressBitmapToStream(bitmap,stream);
            if(ifDel) oriFile.delete();//        
            System.gc();
        }catch (Exception e){
            Log.d("Alex",""+e.getMessage().toString());
        }
    }

    /**
     *     bitmap         
     * @param image
     * @return
     */
    private static int getSize(Bitmap image){
        int size=0;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {    //API 19
            size = image.getAllocationByteCount();
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1) {//API 12
            size = image.getByteCount();
        } else {
            size = image.getRowBytes() * image.getHeight();
        }
        return size;
    }

    /**
     *      bitmap            ,           ,     ,     
     * @param image
     * @param targetFile
     */
    public static void compressMethodAndSave(Bitmap image,File targetFile){
        try {
            OutputStream stream = new FileOutputStream(targetFile);
            int size = compressBitmapToStream(image,stream);
            if(size==0)return;
            long afterSize = targetFile.length();
            Log.i("Alex","        "+(afterSize>>10)+"KB    :::"+afterSize*100/size+"%");
        }catch (Exception e){
            Log.i("Alex","        ",e);
        }
    }

    public static int compressBitmapToStream(Bitmap image,OutputStream stream){
        if(image==null || stream==null)return 0;
        try {
            Bitmap.CompressFormat format = Bitmap.CompressFormat.JPEG;
            int size = getSize(image);
            Log.i("Alex","     bitmap   "+(size>>10)+" KB    "+image.getWidth()+"    "+image.getHeight());
            int quality = getQuality(size);//                  
            Log.i("Alex","           "+quality);
            long startTime = System.currentTimeMillis();
            image.compress(format, quality, stream);//        
            if (image != null) {
                image.recycle();//   bitmap      
                image = null;
            }
            Log.i("Alex","           "+(System.currentTimeMillis()-startTime));
            return size;
        }catch (Exception e){
            Log.i("Alex","        ",e);
        }
        return 0;
    }

    /**
     *                   ,       bitmap         ,  1000*1000,               
     * @param size
     * @return
     */
    private static int getQuality(int size){
        int mb=size>>20;//  100 ,   m
        int kb = size>>10;
        Log.i("Alex","              ,   "+kb+"KB,   "+mb);
        if(mb>70){
            return 17;
        }else if(mb>50){
            return 20;
        }else if(mb>40){
            return 25;
        }else if(mb>20){
            return 40;
        }else if(mb>10){
            return 60;
        }else if(mb>3){//       100k,            
            return 60;
        }else if(mb>=2){
            return 60;
        }else if(kb > 1500){
            return 70;
        }else if(kb > 1000){
            return 80;
        }else if(kb>500){
            return 85;
        }else if(kb>100){
            return 90;
        }
        else{
            return 100;
        }
    }

    /**
     *  assets             Bitmap
     * @param fileName
     * @return
     */
    public static Bitmap getDataFromAssets(Context context,String fileName){
        Log.i("Alex","   assets        "+fileName);
        try {
            //      context.getResources().getAssets().open(fileName);    InputStream  BufferedInputStream           
            AssetFileDescriptor descriptor = context.getResources().getAssets().openFd(fileName);//              FileInputStream,    NIO  Channel
            long fileSize = descriptor.getLength();
            Log.i("Alex","          "+fileSize);//              , decodeStream          
            Bitmap bitmap = BitmapFactory.decodeStream(context.getResources().getAssets().open(fileName));
//            Bitmap bitmap = BitmapFactory.decodeFileDescriptor(fileDescriptor);//  ,AssetFileDescriptor           ,      inputStream, FileDescriptor      BitmapFactory.decodeStream    
            if(bitmap==null)Log.i("Alex","decode bitmap  ");
            return bitmap;
        } catch (Exception e) {
            Log.i("Alex","        ",e);
            e.printStackTrace();
        }
        return null;
    }

    public static boolean copyFile(File sourceFile,File targetFile){
        //NIO        :1) FileInputStream   Channel  ;2)    buffer  ;3) Channel     Buffer ;
        FileInputStream fin  = null;
        FileOutputStream fout = null;
        FileChannel fcin = null;
        FileChannel fcout = null;
        try {
            fin = new FileInputStream( sourceFile );
            fout = new FileOutputStream( targetFile );
            fcin = fin.getChannel();
            fcout =fout.getChannel();
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            int r = 0;
            while ((r = fcin.read(buffer))!=-1) {
                buffer.clear();
                buffer.flip();//    ,           
                fcout.write(buffer);
            }
            return true;
        } catch (Exception e){
            Log.i("Alex","        ",e);
        }finally {
            if(fin!=null) try {
                fin.close();
                if(fout!=null)fout.close();
                if(fcin!=null)fcin.close();
                if(fcout!=null)fcout.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return false;
    }




}

呼び出し方法:ここでは、出力ストリームからバイト配列を取得してアップロードの準備をします.
private byte[] getCompressedUploadPhotoBitmapByteArray(String filePath, int inSampleSize, int quality) {
                        byte[] bitmapDataByteArray = {};
                        if (!JDataUtils.isEmpty(filePath)) {
                            
                            File file = new File(filePath);
                            if (file.exists()) {
                                    ByteArrayOutputStream baos = null;
                                    try {
                                        baos = new ByteArrayOutputStream();//      ,     ,           
                                        
                                        AlxBitmapUtils.compressImage(file,null,baos,false);//      ,       
                                        bitmapDataByteArray = baos.toByteArray();
                                        Log.i("Alex","              "+(bitmapDataByteArray.length>>10)+" KB");
                                    } catch (Throwable throwable) {
                                        
                                    } finally {
                                        try {
                                            if (baos != null) {
                                                baos.close();
                                            }
                                        } catch (Throwable throwable) {
                                            
                                        }
                                    }

                            } else {
                                bitmapDataByteArray = null;
                            }
                        } else {
                            bitmapDataByteArray = null;
                        }

                        return bitmapDataByteArray;
                    }