1. 程式人生 > >android呼叫系統照相機拍照,並壓縮儲存在本地

android呼叫系統照相機拍照,並壓縮儲存在本地

1.首先拍照和儲存檔案肯定就需要申請許可權

    <!-- 往SDCard寫入資料許可權 -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <!-- 在SDCard中建立與刪除檔案許可權 -->
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
    <!--照相機許可權-->
    <uses-permission
android:name="android.permission.CAMERA"/>

2.在佈局中新增一個按鈕和一個ImageView用來顯示圖片縮圖,佈局如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width
="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:orientation
="vertical" tools:context="mydemo.wzc.com.mycamera.MainActivity">
<Button android:id="@+id/camera" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="呼叫系統照相機拍照"/> <ImageView android:id="@+id/image" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout>

3.點選button呼叫系統照相機進行拍照,button監聽事件如下:

//呼叫系統相機
                File dir = new File(Environment.getExternalStorageDirectory(), "myimage");//在sd下建立資料夾myimage;Environment.getExternalStorageDirectory()得到SD卡路徑檔案
                if (!dir.exists()) {    //exists()判斷檔案是否存在,不存在則建立檔案
                    dir.mkdirs();
                }
                SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");//設定日期格式在android中,建立檔案時,檔名中不能包含“:”冒號
                String filename = df.format(new Date());
                currentImageFile = new File(dir, filename + ".jpg");
                if (!currentImageFile.exists()) {
                    currentImageFile.createNewFile();
                }
                Intent openCameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                openCameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(currentImageFile));
                startActivityForResult(openCameraIntent, ACTION_TAKE_PHOTO);

4.重寫onActivityResult()方法,在該方法中來處理返回的資料。

if (resultCode == RESULT_OK && requestCode == ACTION_TAKE_PHOTO) {
                String sdStatus = Environment.getExternalStorageState();
                if (!sdStatus.equals(Environment.MEDIA_MOUNTED)) { // 檢測sd是否可用
                    Log.i("TestFile", "SD card is not avaiable/writeable right now.");
                    return;
                }
                //原圖
                String filePath = file.getAbsolutePath();
            Bitmap bitmap = BitmapFactory.decodeFile(filePath);
                //利用Bitmap物件建立縮圖
                Bitmap showbitmap = ThumbnailUtils.extractThumbnail(bitmap, 250, 250);
                iv_imageView.setImageBitmap(showbitmap);

此時我們拍照完成之後,照片會儲存在SD下的myimage資料夾下,但是圖片沒有進行壓縮。圖片大小大約1M多(這和手機有關),並且縮圖並沒有儲存只是顯示而已。
效果如圖:
這裡寫圖片描述

4.對圖片進行壓縮,壓縮方法有按比例大小壓縮按質量壓縮

//取樣率壓縮(根據路徑獲取圖片並壓縮):
    public Bitmap getSmallBitmap(File file, int reqWidth, int reqHeight) {
        try {
            String filePath = file.getAbsolutePath();
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;//開始讀入圖片,此時把options.inJustDecodeBounds 設回true了
            BitmapFactory.decodeFile(filePath, options);//此時返回bm為空
            options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);//設定縮放比例 數值越高,圖片畫素越低
            options.inJustDecodeBounds = false;//重新讀入圖片,注意此時把options.inJustDecodeBounds 設回false了
            Bitmap bitmap = BitmapFactory.decodeFile(filePath, options);
            //壓縮好比例大小後不進行質量壓縮
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(currentImageFile));
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);//質量壓縮方法,這裡100表示不壓縮,把壓縮後的資料存放到bos中
            //壓縮好比例大小後再進行質量壓縮
            //compressImage(bitmap,filePath);
            return bitmap;
        } catch (Exception e) {
            Log.d("wzc", "類:" + this.getClass().getName() + " 方法:" + Thread.currentThread()
                    .getStackTrace()[0].getMethodName() + " 異常 " + e);
            return null;
        }
    }

    /**
     * 計算圖片的縮放值
     *
     * @param options
     * @param reqWidth
     * @param reqHeight
     * @return
     */
    public int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
        try {
            int height = options.outHeight;
            int width = options.outWidth;
            int inSampleSize = 1;  //1表示不縮放
            if (height > reqHeight || width > reqWidth) {
                int heightRatio = Math.round((float) height / (float) reqHeight);
                int widthRatio = Math.round((float) width / (float) reqWidth);
                inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
            }
            return inSampleSize;
        } catch (Exception e) {
            Log.d("wzc", "類:" + this.getClass().getName() + " 方法:" + Thread.currentThread()
                    .getStackTrace()[0].getMethodName() + " 異常 " + e);
            return 1;
        }
    }

    // 質量壓縮法:
    private Bitmap compressImage(Bitmap image, String filepath) {
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            image.compress(Bitmap.CompressFormat.JPEG, 100, baos);//質量壓縮方法,這裡100表示不壓縮,把壓縮後的資料存放到baos中
            int options = 100;
            while (baos.toByteArray().length / 1024 > 100) {    //迴圈判斷如果壓縮後圖片是否大於100kb,大於繼續壓縮
                baos.reset();//重置baos即清空baos
                options -= 10;//每次都減少10
                image.compress(Bitmap.CompressFormat.JPEG, options, baos);//這裡壓縮options%,把壓縮後的資料存放到baos中

            }
            //壓縮好後寫入檔案中
            FileOutputStream fos = new FileOutputStream(filepath);
            fos.write(baos.toByteArray());
            fos.flush();
            fos.close();
            return image;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

下面是我進行壓縮前後的對比:
這裡寫圖片描述

第一張是沒有進行壓縮的圖片,第二張是進行按比例壓縮的圖片,最後一張是按比例壓縮後在進行質量壓縮後的照片。

相關推薦

android呼叫系統照相機拍照壓縮儲存本地

1.首先拍照和儲存檔案肯定就需要申請許可權 <!-- 往SDCard寫入資料許可權 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_

android 呼叫系統照相機拍照儲存系統相簿系統圖庫中能看到

需求:  呼叫系統照相機進行拍照,並且儲存到系統相簿,呼叫系統相簿的時候能看到 系統相簿的路徑:String cameraPath= Environment.getExternalStorageDi

android 呼叫系統相機拍照返回的data為null

最近做專案,需要拍照功能,於是就想簡單的呼叫系統相機來完成這一需求(當然,如果想要個性化一點的,也可以自定義camera去實現,這裡暫時不做)。 if(Environment.getExternalStorageState().equals(Environ

Android呼叫系統相機拍照從相簿中選擇照片呼叫系統攝像機錄影

最近在Android Studio上折騰程式碼,昨天編譯器又很不給面子的報錯了: Error type 3 Error: Activity class {com.example.myapplication/com.example.myapplication

Android 呼叫系統照相機拍照和錄影

專案的佈局相當簡單,只有一個Button: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"

android 呼叫系統照相機拍照後剪裁

private static final int PHOTO_REQUEST_CAMERA = 1;// 拍照 private static final int PHOTO_REQUEST_GALLERY = 2;// 從相簿中選擇 private static fina

Android呼叫系統相機拍照儲存到SD卡的兩種實現方式

1.呼叫照相機時通過putExtra的方式直接指定儲存路徑 String FilePath = "/sdcard/pic/"; File file = new File(FilePath); file.mkdirs();// 建立資料夾 Intent intent

Android 呼叫系統相機拍照並且顯示在相簿中以及中間可能會遇到的一些問題的解決

主要思路是在使用照相機拍照,然後為拍得的照片在SD卡新開一個儲存照片的檔案 程式碼:因為要呼叫照相機和SD卡所以需要新增以下許可權: 在manifests中新增 <uses-permission android:name="android.permission.CAM

Android呼叫系統照相機和攝像機

呼叫系統照相機。 private void callPhone() { //獲得檔案 File _file = new File(StorageUtils.getCacheDirectory

Android呼叫系統裁減圖片出現android.os.TransactionTooLargeException: data parcel size 642356 bytes

1、Android拍照和相簿+系統裁剪功能返回圖片http://blog.csdn.net/why110999784/article/details/52460403 2、裁減圖片時傳遞的return-data設定為true,在onActivityResult的Inten

android呼叫系統相機拍照

獲取縮圖 直接調取相機拍照,無需任何許可權,但是隻能獲取到縮圖 Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); if (takePictureIntent.resolveActivit

Android 呼叫系統相簿選擇圖片顯示

主要程式碼: package wkk.app2; import android.app.Activity; import android.content.Intent; import android.database.Cursor; import android.graphics.Bitmap; imp

android 呼叫系統相機拍照後圖片上顯示文字

 先說說自己的思路(有什麼欠缺的望噴。。。)    1、在xml 檔案寫入Imageview(用來顯示拍照圖片) 和textview (顯示想要顯示的文字)  2、將xml 佈局通過   LayoutInflater.from(context).inflate轉換為view檢

解決Android呼叫系統相機拍照後相片無法在相簿中顯示問題

目前自己使用傳送廣播實現了效果public void photo() { Intent openCameraIntent = new Intent(android.provider.MediaSt

Android 呼叫系統相機拍照的返回結果

  1.開啟相機的Intent Action: MediaStore.ACTION_IMAGE_CAPTURE,下面為它的註釋: /** * Standard Intent action that can be sent to have the camera app

Android 呼叫系統相機拍照 . 選取本地相簿

專案中,基本都有使用者自定義頭像或自定義背景的功能,實現方法一般都是呼叫系統相機–拍照,或者系統相簿–選擇照片,然後進行剪裁,最終設為頭像或背景。 我直接貼上使用的程式碼吧! 這次偷懶了,沒有做效果圖,不過這是我試過的程式碼,可以,只不過不能選取原圖,因為

android呼叫系統圖片剪裁相容小米

public void cropPhoto(Uri uri) { Intent intent = new Intent("com.android.camera.action.CROP"); intent.setDataAndType(uri, "image/*

呼叫系統相機拍照從相簿選取圖片上傳

前不久在專案中再次遇到了這個問題,就是從系統相簿中選取圖片,呼叫系統的相機拍照並上傳的問題。由於之前比較懶沒能在做完之後對寫的程式碼進行整理儲存,以至於再次遇到的時候還是重新去研究了一下造成了開發過程中的時間浪費。 注意的點:1.呼叫系統的相機拍攝並取得原圖,並對角度進行處

Android呼叫系統照相機返回intent為空原因分析

1.在呼叫android系統相簿時,使用的是如下方式:     Intent intent = new Intent(Intent.ACTION_GET_CONTENT);             intent.addCategory(Intent.CATEGORY_OPE

Android呼叫系統相機拍照 獲取原圖

拍照時候在onActivityResult中獲得相機拍照後點擊確定後的照片。 Android中用Intent提取縮圖和原始影象 可以接受照片的縮圖 Bundle bundle =data.ge