Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android拍照調用系統相冊仿微信封裝總結,治療各種崩潰,圖片橫豎問題壓縮等問題。

Android拍照調用系統相冊仿微信封裝總結,治療各種崩潰,圖片橫豎問題壓縮等問題。

編輯:關於Android編程

項目下載地址:https://github.com/Aiushtha/android-PictureSelector

最早使用android調用系統拍照然後遇到很多空指針等問題以及各種android 不同版本Intent取data有時候會空指針之類的api兼容問題,像使用紅米note在開了很多應用後,再啟動拍照系統,會發生拍照崩潰圖片丟失等問題,用微信控件有時拍照有極小概率拍照無效等等奇怪的問題,其原因是因為Activity被回收了,變量變成null,

還有三星手機可能會遇到變量空針

需要在AndroidManifest.xml的Activity裡加入

android:configChanges="mcc|mnc|keyboard|keyboardHidden|navigation|orientation|screenSize|fontScale"

 

如何在Fragment上調用拍照,圖片如何壓縮

經過一段時間優化,修復了一些坑。我覺得目前的代碼比較可靠,總結一下封裝後分享出來。

\

\

 

\

\

 

package com.cn.demo.takephoto;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import java.io.File;
import java.text.DecimalFormat;
import java.util.List;

import me.lxz.photopicker.camera.PhotoPickManger;
import me.lxz.photopicker.tools.SimpleImageLoader;

public class SimpleDemoActivity extends AppCompatActivity {

    PhotoPickManger pickManger;
    private View btn;
    private ImageView img;
    private TextView tv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        /**圖片加載器*/
        SimpleImageLoader.init(this.getApplicationContext());


        btn = findViewById(R.id.btn);
        img = (ImageView) findViewById(R.id.img);
        tv=(TextView)findViewById(R.id.tv);

        pickManger = new PhotoPickManger("pick",this, savedInstanceState,new PhotoPickManger.OnPhotoPickFinsh() {
            @Override
            public void onPhotoPick(List list) {
                tv.setText("");
                Toast.makeText(getApplicationContext(), "path:" + list.get(0).getPath() + " length:" + list.get(0).length(), Toast.LENGTH_SHORT).show();
                tv.append("path:" + list.get(0).getPath());
                tv.append("\nlength:" + new DecimalFormat("#.##").format((1.0d*list.get(0).length()/1024/1024))+"MB");
                /**是否圖片壓縮*/
                processImg();

            }
        });
        /**是否在*/
        pickManger.setCut(false);
        pickManger.flushBundle();

        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                pickManger.clearCache();
                pickManger.start(PhotoPickManger.Mode.SYSTEM_CAMERA);
            }
        });


    }
    /**圖片壓縮*/
    private void processImg() {
        pickManger.doProcessedPhotos(new PhotoPickManger.OnProcessedPhotos() {
            @Override
            public void onProcessed(List list) {
                SimpleImageLoader.displayImage(list.get(0), img);
                tv.append("\nprogress length:" + new DecimalFormat("#.##").format((1.0d*list.get(0).length()/1024/1024))+"MB");
           }
        });
    }



    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        pickManger.onActivityResult(requestCode, resultCode, data);
    }

    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
        super.onSaveInstanceState(savedInstanceState);
        pickManger.onSaveInstanceState(savedInstanceState);
    }
}

核心代碼:

 

 

package me.lxz.photopicker.camera;

import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.provider.MediaStore;
import android.util.Log;
import android.widget.Toast;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import me.iwf.photopicker.PhotoPickerActivity;
import me.iwf.photopicker.utils.PhotoPickerIntent;
import me.lxz.photopicker.tools.PictureUtil;


/**
 * 圖片選擇器
 */
public final class PhotoPickManger {

    public interface OnProcessedPhotos {
        void onProcessed(List list);
    }

    public interface OnPhotoPickFinsh {
        public void onPhotoPick(List list);
    }


    /**
     * 模式
     */
    public enum Mode {
        /**
         * 系統相機
         */SYSTEM_CAMERA,
        /**
         * 系統圖庫
         */SYSTEM_IMGCAPTRUE,
        /**
         * 類似微信圖庫
         */AS_WEIXIN_IMGCAPTRUE
    }


    /**
     * 用於區別哪一個圖片選擇器
     */
    private static String currentPickMangerName;

    /**
     * 測試用
     */
    private boolean isDebugToast = true;

    /**
     * 用於區別其他圖片選擇器
     */
    private String name;


    public final String SAVE_STATIC_NAME = "save_currentPickMangerName";

    /**
     * 字段保存所已選擇的圖片
     */
    public final String SAVE_SELECTED_PHOTOS = "save_selected_photos";

    /**
     * 字段保存所拍照已選擇的圖片
     */
    public final String SAVE_CACHE_CAMERA = "save_cache_camera";

    /**
     * 字段保存所拍照是否選擇裁剪
     */
    public final String SAVE_CACHE_IS_CUT = "save_cache_is_cut";


    /**
     * 字段保存待處理圖片
     */
    public final String SAVE_CACHE_CUT_QUEUE = "save_cache_cut_queue";


    /**
     * 是否裁剪 只對系統相機和系統相冊有效
     */
    private boolean isCut = false;
    /**
     * 是否縮略
     */
    private boolean isOptimize = false;

    /**
     * 設置返回最大圖片數 對系統相機和相冊調用無效
     * 默認1
     */
    private int returnFileCount = 1;


    private OnPhotoPickFinsh onPhotoPickFinsh;

    private File tempFile;

    private Handler handler = new Handler();

    /**
     * 已經選擇的拍照圖片
     */
    public ArrayList selectsPhotos = new ArrayList<>();


    private Activity activity;

    /**
     * 用於緩存
     */
    public Bundle bundle;
    /**
     * 系統拍照標示code
     */
    private final int PHOTO_REQUEST_TAKEPHOTO = 1;// 拍照
    /**
     * 系統相冊標示code
     */
    private final int PHOTO_REQUEST_GALLERY = 2;// 從相冊中選擇
    /**
     * 系統照片返回標示code
     */
    private final int PHOTO_REQUEST_CUT = 3;// 結果
    /**
     * 仿微信相冊返回code
     */
    public final static int AS_WEIXIN_REQUEST_CODE = 4;

    /**
     * 如果多圖待剪切則保存到該隊列裡
     */
    public ArrayList willCutOfFileQueue = new ArrayList<>();


    /**
     * 圖片緩存地址
     */
    public String cacheFilePath = "/img/";

    /**
     * 默認裁剪大小
     */
    public int defaultCutSize = 150;

    /**
     * 至少大於多少的圖片進行處理
     */
    public int needProcessFileLength = (int) 0.5 * 1024 * 1024;

    /***
     * 構造方法
     *
     * @param name             為圖片選擇器默認一個別名 用來區別那一個選擇器被選擇了
     * @param activity
     * @param bundle           當系統內存不足時,重建時取出變量
     * @param onPhotoPickFinsh 圖片選擇成功時回調
     */
    public PhotoPickManger(String name, Activity activity, Bundle bundle, OnPhotoPickFinsh onPhotoPickFinsh) {
        this.onPhotoPickFinsh = onPhotoPickFinsh;
        this.name = name;
        this.activity = activity;
        this.bundle = bundle;

        if (bundle != null) {
            isCut = bundle.getBoolean(SAVE_CACHE_IS_CUT + "_" + name);
            currentPickMangerName = bundle.getString(SAVE_STATIC_NAME);
            willCutOfFileQueue = (ArrayList) bundle.getSerializable(SAVE_CACHE_CUT_QUEUE + "name");
        }
    }

    /**
     * 處理掉重建時的緩存
     */
    public void flushBundle() {
        if (bundle != null) {
            if (isDebugToast) {
                Toast.makeText(activity, "bundle is refresh", Toast.LENGTH_LONG).show();
            }
            selectsPhotos = (ArrayList) bundle.getSerializable(SAVE_SELECTED_PHOTOS + "_" + name);
            if (selectsPhotos == null) {
                selectsPhotos = new ArrayList<>();
            }
            tempFile = (File) bundle.getSerializable(SAVE_CACHE_CAMERA + "_" + name);
            if (tempFile != null) {
                if (tempFile.exists()) {
                    if (tempFile.length() > 0) {
                        if (!isCut) {
                            selectsPhotos.add(tempFile);
                        } else {
                            startPhotoZoom(Uri.fromFile(tempFile), defaultCutSize);
                        }
                        tempFile = null;
                    } else {
                        tempFile.delete();
                        tempFile = null;
                    }

                }
            }
            bundle.remove(SAVE_CACHE_CAMERA + "_" + name);
            if (!selectsPhotos.isEmpty()) {
                if (onPhotoPickFinsh != null) onPhotoPickFinsh.onPhotoPick(selectsPhotos);
            }

        }
    }

    /**
     * 保存變量
     */
    public void onSaveInstanceState(Bundle savedInstanceState) {
        this.bundle = savedInstanceState;
        if (selectsPhotos != null && !selectsPhotos.isEmpty()) {
            savedInstanceState.putSerializable(SAVE_SELECTED_PHOTOS + "_" + name, selectsPhotos);
        }
        if (tempFile != null) {
            savedInstanceState.putSerializable(SAVE_CACHE_CAMERA + "_" + name, tempFile);
        }
        savedInstanceState.putBoolean(SAVE_CACHE_IS_CUT + "_" + name, isCut);
        savedInstanceState.putSerializable(SAVE_CACHE_CUT_QUEUE + "_" + name, willCutOfFileQueue);
        savedInstanceState.putSerializable(SAVE_STATIC_NAME, currentPickMangerName);
    }

    /**
     * 如果是單一拍照,在拍照前應該清理緩存
     */
    public void clearCache() {
        getSelectsPhotos().clear();
        tempFile = null;
        if (bundle != null) {
            bundle.remove(SAVE_SELECTED_PHOTOS + "_" + name);
            bundle.remove(SAVE_CACHE_CAMERA + "_" + name);
        }


    }

    /**
     * 生成一個臨時的緩存文件
     */
    private File getFile() {
        File dir = new File(Environment.getExternalStorageDirectory().getPath()
                + cacheFilePath);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        File file = new File(Environment.getExternalStorageDirectory()
                .getPath() + cacheFilePath, getPhotoFileName());
        return file;
    }

    // 使用系統當前日期加以調整作為照片的名稱
    private String getPhotoFileName() {
        Date date = new Date(System.currentTimeMillis());
        SimpleDateFormat dateFormat = new SimpleDateFormat(
                "'IMG'_yyyyMMdd_HHmmss");
        return dateFormat.format(date) + ".jpg";
    }

    /**
     * // 調用系統的拍照功能
     */
    private void startCamearPicCut() {
        tempFile = getFile();
        Log.d("test", "start:" + tempFile.exists() + " " + tempFile.length());
        // this.isCutOut = b;
        // 調用系統的拍照功能
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        intent.putExtra("camerasensortype", 2);// 調用前置攝像頭
        intent.putExtra("autofocus", true);// 自動對焦
        intent.putExtra("fullScreen", false);// 全屏
        intent.putExtra("showActionIcons", false);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(tempFile));
        activity.startActivityForResult(intent, PHOTO_REQUEST_TAKEPHOTO);
    }

    /**
     * 調用系統的相冊
     */
    private void startImageCaptrue() {
        tempFile = getFile();
        Intent intent = new Intent(Intent.ACTION_PICK, null);
        intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                "image/*");
        activity.startActivityForResult(intent, PHOTO_REQUEST_GALLERY);
    }


    /**
     * 調用仿微信圖庫
     */

    private void startAsWeixinImageCaptrue() {
        PhotoPickerIntent intent = new PhotoPickerIntent(activity);
        intent.setPhotoCount(returnFileCount);
        activity.startActivityForResult(intent, AS_WEIXIN_REQUEST_CODE);
    }

    /**
     * 啟動
     */

    public void start(Mode mode) {
        currentPickMangerName = this.name;
        switch (mode) {
            case SYSTEM_CAMERA:
                startCamearPicCut();
                break;
            case SYSTEM_IMGCAPTRUE:
                startImageCaptrue();
                break;
            case AS_WEIXIN_IMGCAPTRUE:
                startAsWeixinImageCaptrue();
                break;
        }
    }


    /**
     * 回調onActivityResult事件
     */
    @SuppressWarnings("unused")
    public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
        if (currentPickMangerName == null) {
            if (bundle != null) {
                currentPickMangerName = bundle.getString(SAVE_STATIC_NAME);
                if (!currentPickMangerName.equals(name)) return;
            }
        } else {
            if (!currentPickMangerName.equals(name)) return;
        }
        try {
            switch (requestCode) {
                case PHOTO_REQUEST_TAKEPHOTO:
                    if (isCut) {
                        startPhotoZoom(Uri.fromFile(tempFile), defaultCutSize); // 裁剪
                    } else {
                        if (tempFile.length() == 0) {
                            tempFile.delete();
                        } else {
                            finish(tempFile);
                        }
                    }
                    return;
                case PHOTO_REQUEST_GALLERY:
                    if (isCut) {
                        if (data != null) {
                            startPhotoZoom(data.getData(), defaultCutSize);
                        }
                    } else {

                        File file = null;
                        try {
                            String path = getRealPathFromURI(data.getData());
                            file = new File(path);

                            if (file == null) return;
                            if (file.length() == 0) {
                                file.delete();
                                return;
                            }
                            finish(file);
                        } catch (Exception e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }

                    }
                    return;

                case PHOTO_REQUEST_CUT:
                    if (data != null) {
                        setCutPicToView(data);
                    } else {
                        flushCutPhotos();
                    }
                    return;
                case AS_WEIXIN_REQUEST_CODE:
                    List photos = null;
                    try {
                        if (requestCode == AS_WEIXIN_REQUEST_CODE) {
                            if (data != null) {
                                photos = data.getStringArrayListExtra(PhotoPickerActivity.KEY_SELECTED_PHOTOS);
                                if (!isCut) {

                                    List list = new ArrayList();
                                    if (photos != null && !photos.isEmpty()) {
                                        for (String str : photos) {
                                            list.add(new File(str));
                                        }
                                    } else {
                                        return;
                                    }
                                    finish(list);
                                } else {
                                    if (photos != null && !photos.isEmpty()) {
                                        /**如果只有一張照片可以直接裁剪 否則*/
                                        if (photos.size() == 1) {
                                            for (String str : photos) {
                                                tempFile = getFile();
                                                copyFile(str, tempFile.getAbsolutePath());
                                                startPhotoZoom(Uri.fromFile(tempFile), defaultCutSize); // 裁剪
                                            }
                                        } else {
                                            for (String str : photos) {
                                                willCutOfFileQueue.add(new File(str));
                                            }
                                            tempFile = getFile();
                                            copyFile(willCutOfFileQueue.get(0).getAbsolutePath(), tempFile.getAbsolutePath());
                                            startPhotoZoom(Uri.fromFile(tempFile), defaultCutSize); // 裁剪
                                            willCutOfFileQueue.remove(0);
                                        }
                                    }

                                }
                            }

                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                    return;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 如果多圖處理裁剪隊列
     */
    private void flushCutPhotos() {
        if (willCutOfFileQueue != null && !willCutOfFileQueue.isEmpty()) {
            tempFile = getFile();
            copyFile(willCutOfFileQueue.get(0).getAbsolutePath(), tempFile.getAbsolutePath());
            willCutOfFileQueue.remove(0);
            startPhotoZoom(Uri.fromFile(tempFile), defaultCutSize); // 裁剪
        }
    }

    /**
     * 文件復制
     */
    private void copyFile(String oldPath, String newPath) {
        try {
            int bytesum = 0;
            int byteread = 0;
            File oldfile = new File(oldPath);
            if (oldfile.exists()) {                  //文件存在時
                InputStream inStream = new FileInputStream(oldPath);      //讀入原文件
                FileOutputStream fs = new FileOutputStream(newPath);
                byte[] buffer = new byte[1444];
                int length;
                while ((byteread = inStream.read(buffer)) != -1) {
                    bytesum += byteread;            //字節數 文件大小
                    System.out.println(bytesum);
                    fs.write(buffer, 0, byteread);
                }
                inStream.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 對當前已選圖片進行壓縮
     */
    public void doProcessedPhotos(final OnProcessedPhotos on) {

        if (getSelectsPhotos() != null && !getSelectsPhotos().isEmpty()) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    for (Iterator it = getSelectsPhotos().iterator(); it.hasNext(); ) {
                        try {
                            File file = it.next();
                            if (file.length() > needProcessFileLength) {
                                final Bitmap bm = PictureUtil.getSmallBitmap(file.getAbsolutePath(), 720, 1200);
                                try {
                                    FileOutputStream fos = new FileOutputStream(file);
                                    bm.compress(Bitmap.CompressFormat.JPEG, 95, fos);
                                } catch (FileNotFoundException e) {
                                    e.printStackTrace();
                                }
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            on.onProcessed(getSelectsPhotos());
                        }
                    });


                }
            }).start();

        }
    }

    /**
     * 圖片選擇完成並回調
     */
    private void finish(final File file) {
        finish(createFiles(file));
    }

    /**
     * 圖片選擇完成並回調
     */
    private void finish(final List files) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (Iterator it = files.iterator(); it.hasNext(); ) {
                    File file = it.next();
                    if (!file.exists() || file.length() == 0) {
                        it.remove();
                    } else {
                        changFile(file.getPath());
                    }
                }
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        selectsPhotos.addAll(files);
                        if (!files.isEmpty()) {
                            if (onPhotoPickFinsh != null) onPhotoPickFinsh.onPhotoPick(files);
                        }
                        tempFile = null;
                        flushCutPhotos();
                    }
                });
            }
        }).start();


    }

    /**
     * 三星手機將橫向圖片轉換為豎向
     */
    public void changFile(String file) {
        BitmapFactory.Options options = new BitmapFactory.Options();

        /**
         * 最關鍵在此,把options.inJustDecodeBounds = true;
         * 這裡再decodeFile(),返回的bitmap為空,但此時調用options.outHeight時,已經包含了圖片的高了
         */
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(file, options);
        int width = options.outWidth;
        int height = options.outHeight;
        if (width > height) {

            Bitmap bit = bitmapFromFile(file, width, height);
            bit = adjustPhotoRotation(bit, 1);
            try {
                bit.compress(Bitmap.CompressFormat.PNG,100,new FileOutputStream(file));
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 旋轉圖片
     */
    public Bitmap adjustPhotoRotation(Bitmap bm, int count) {
        int orientationDegree = 90;
        Matrix m = new Matrix();
        for (int i = 0; i < count; i++) {
            m.setRotate(orientationDegree, bm.getWidth(),
                    bm.getHeight());
            float targetX, targetY;
            if (orientationDegree == 90) {
                targetX = bm.getHeight();
                targetY = 0;
            } else {
                targetX = bm.getHeight();
                targetY = bm.getWidth();
            }

            final float[] values = new float[9];
            m.getValues(values);

            float x1 = values[Matrix.MTRANS_X];
            float y1 = values[Matrix.MTRANS_Y];

            m.postTranslate(targetX - x1, targetY - y1);
        }

        Bitmap bm1 = Bitmap.createBitmap(bm.getHeight(), bm.getWidth(),
                Bitmap.Config.ARGB_8888);
        Paint paint = new Paint();
        Canvas canvas = new Canvas(bm1);
        canvas.drawBitmap(bm, m, paint);

        // ?????bitmap????
        bm.recycle();

        return bm1;
    }

    private List createFiles(File file) {
        List list = new ArrayList<>();
        list.add(file);
        return list;
    }

    /**
     * 根據Uri獲得File文件路徑
     */
    public String getRealPathFromURI(Uri contentUri) {
        String res = null;
        String[] proj = {MediaStore.Images.Media.DATA};
        Cursor cursor = activity.getContentResolver().query(contentUri, proj,
                null, null, null);
        if (cursor.moveToFirst()) {
            ;
            int column_index = cursor
                    .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
            res = cursor.getString(column_index);
        }
        cursor.close();
        return res;
    }

    /**
     * 啟動裁剪
     */
    private void startPhotoZoom(Uri uri, int size) {
        Log.d("test", uri.toString());
        Intent intent = new Intent("com.android.camera.action.CROP");
        intent.setDataAndType(uri, "image/*");
        // crop為true是設置在開啟的intent中設置顯示的view可以剪裁
        intent.putExtra("crop", "true");

        // aspectX aspectY 是寬高的比例
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1);

        // outputX,outputY 是剪裁圖片的寬高
        intent.putExtra("outputX", size);
        intent.putExtra("outputY", size);

        intent.putExtra("return-data", true);
        intent.putExtra("noFaceDetection", true);
        activity.startActivityForResult(intent, PHOTO_REQUEST_CUT);
    }

    // 將進行剪裁後的圖片顯示到UI界面上
    private void setCutPicToView(Intent picdata) {
        Bundle bundle = picdata.getExtras();
        if (bundle != null) {
            Bitmap photo = bundle.getParcelable("data");
            if (photo != null) {
                FileOutputStream fOut = null;
                try {
                    fOut = new FileOutputStream(tempFile);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
                photo.compress(Bitmap.CompressFormat.JPEG, 100, fOut);
            }
            finish(tempFile);

        }
    }


    /**
     * 獲取一個指定大小的bitmap
     *
     * @param reqWidth  目標寬度
     * @param reqHeight 目標高度
     */
    public Bitmap bitmapFromFile(String pathName, int reqWidth,
                                 int reqHeight) {
        if (reqHeight == 0 || reqWidth == 0) {
            return BitmapFactory.decodeFile(pathName);
        } else {
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            BitmapFactory.decodeFile(pathName, options);

            options = calculateInSampleSize(options, reqWidth,
                    reqHeight);
            return BitmapFactory.decodeFile(pathName, options);
        }
    }

    /**
     * 圖片壓縮處理(使用Options的方法)
     *

* * 說明 使用方法: * 首先你要將Options的inJustDecodeBounds屬性設置為true,BitmapFactory.decode一次圖片 。 * 然後將Options連同期望的寬度和高度一起傳遞到到本方法中。 * 之後再使用本方法的返回值做參數調用BitmapFactory.decode創建圖片。 *

* * 說明 BitmapFactory創建bitmap會嘗試為已經構建的bitmap分配內存 * ,這時就會很容易導致OOM出現。為此每一種創建方法都提供了一個可選的Options參數 * ,將這個參數的inJustDecodeBounds屬性設置為true就可以讓解析方法禁止為bitmap分配內存 * ,返回值也不再是一個Bitmap對象, 而是null。雖然Bitmap是null了,但是Options的outWidth、 * outHeight和outMimeType屬性都會被賦值。 * * @param reqWidth 目標寬度,這裡的寬高只是閥值,實際顯示的圖片將小於等於這個值 * @param reqHeight 目標高度,這裡的寬高只是閥值,實際顯示的圖片將小於等於這個值 */ public BitmapFactory.Options calculateInSampleSize( final BitmapFactory.Options options, final int reqWidth, final int reqHeight) { // 源圖片的高度和寬度 final int height = options.outHeight; final int width = options.outWidth; int inSampleSize = 1; if (height > reqHeight || width > reqWidth) { // 計算出實際寬高和目標寬高的比率 final int heightRatio = Math.round((float) height / (float) reqHeight); final int widthRatio = Math.round((float) width / (float) reqWidth); // 選擇寬和高中最小的比率作為inSampleSize的值,這樣可以保證最終圖片的寬和高 // 一定都會大於等於目標的寬和高。 inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio; } // 設置壓縮比例 options.inSampleSize = inSampleSize; options.inJustDecodeBounds = false; return options; } public Activity getActivity() { return activity; } public PhotoPickManger setActivity(Activity activity) { this.activity = activity; return this; } public boolean isCut() { return isCut; } public PhotoPickManger setIsCut(boolean isCut) { this.isCut = isCut; return this; } public boolean isOptimize() { return isOptimize; } public PhotoPickManger setIsOptimize(boolean isOptimize) { this.isOptimize = isOptimize; return this; } public int getReturnFileCount() { return returnFileCount; } public PhotoPickManger setReturnFileCount(int returnFileCount) { this.returnFileCount = returnFileCount; return this; } public OnPhotoPickFinsh getOnPhotoPickFinsh() { return onPhotoPickFinsh; } public PhotoPickManger setOnPhotoPickFinsh(OnPhotoPickFinsh onPhotoPickFinsh) { this.onPhotoPickFinsh = onPhotoPickFinsh; return this; } public boolean isDebugToast() { return isDebugToast; } public PhotoPickManger setDebugToast(boolean isDebugToast) { this.isDebugToast = isDebugToast; return this; } public void setCut(boolean isCut) { this.isCut = isCut; } public Bundle getBundle() { return bundle; } public PhotoPickManger setBundle(Bundle bundle) { this.bundle = bundle; return this; } public File getTempFile() { return tempFile; } public ArrayList getSelectsPhotos() { return selectsPhotos; } public int getNeedProcessFileLength() { return needProcessFileLength; } public PhotoPickManger setNeedProcessFileLength(int needProcessFileLength) { this.needProcessFileLength = needProcessFileLength; return this; } public static String getCurrentPickMangerName() { return currentPickMangerName; } public static void setCurrentPickMangerName(String currentPickMangerName) { PhotoPickManger.currentPickMangerName = currentPickMangerName; } public String getCacheFilePath() { return cacheFilePath; } public PhotoPickManger setCacheFilePath(String cacheFilePath) { this.cacheFilePath = cacheFilePath; return this; } public String getName() { return name; } public PhotoPickManger setName(String name) { this.name = name; return this; } public PhotoPickManger setTempFile(File tempFile) { this.tempFile = tempFile; return this; } }

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved