在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ Android/ 拍照和錄像 with Camera
多分辨率適配常用目錄
Android 開發(fā)環(huán)境(Eclipse+ADT+Android 5.0)
Android 原型設(shè)計工具探索
Makefile 快速入門
Android Studio的NDK開發(fā)
人臉檢測-靜態(tài)
getprop 與 dumpsys 命令
Maven 編譯開源二維碼掃描項目 zxing
畫布 Canvas
組合控件
Linux 下的模擬器硬件加速
讀取 Excel
android.hardware.camera2 使用指南
橫豎屏切換
Ubuntu 下切換 JDK 版本
拍照和錄像 with Camera
文本與布局
按鈕控制 ViewPager 的左右翻頁
用 TableLayout 偽裝表格顯示數(shù)據(jù)
Preference Activity 使用詳解
模擬器如何重啟?試試 Genymotion!
獲得屏幕物理尺寸、密度及分辨率
語音識別
了解 native activity
Android Studio 導(dǎo)入第三方類庫、jar 包和 so 庫
啟動另一個 App/apk 中的 Activity
APK 簽名
兩個開源的圖表/報表控件
android studio 導(dǎo)出 jar 包(Module)并獲得手機(jī)信息
圖片的 Base64 編解碼
混淆與反編譯
Android Studio 和 Gradle
Android 5.1 SDK 下載與配置
persistableMode 與 Activity 的持久化
adb 取出安裝在手機(jī)中的 apk
Android Studio 中的源代碼管理
Handler 使用中可能引發(fā)的內(nèi)存泄漏

拍照和錄像 with Camera

目錄(?)[+]

Developer Guides 中有一篇是專門講 Camera 的,而且講的特別細(xì)。千萬別以為有了這么好的文檔就可以輕松的使用 android.hardware.Camera 這個包去拍照和錄像了,各種坑在前面等著你呢。好了,下面將要講述我們?nèi)绾蜗襁|寧隊在常規(guī)賽中填坑的經(jīng)歷。

一、借助 intent

這就十分 easy 了,發(fā)個 intent 就有人幫你搞定拍照和錄像。 拍照:

    public void onTakePhoto(View view) {
        // create Intent to take a picture and return control to the calling application
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

        fileUri = CameraUtils.getOutputMediaFileUri(CameraUtils.MEDIA_TYPE_IMAGE); // create a file to save the image
        intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file name

        // start the image capture Intent
        startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
    }

錄像:

    public void onTakeVideo(View view) {
        //create new Intent
        Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);

        fileUri = CameraUtils.getOutputMediaFileUri(CameraUtils.MEDIA_TYPE_VIDEO);  // create a file to save the video
        intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);  // set the image file name

        intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1); // set the video image quality to high

        // start the Video Capture Intent
        startActivityForResult(intent, CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE);
    }

對結(jié)果的處理:

    private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100;
    private static final int CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE = 101;
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
            if (resultCode == RESULT_OK) {
                // Image captured and saved to fileUri specified in the Intent
                Toast.makeText(this, "Image saved to:\n" +
                        data.getData(), Toast.LENGTH_LONG).show();
            } else if (resultCode == RESULT_CANCELED) {
                // User cancelled the image capture
            } else {
                // Image capture failed, advise user
            }
        }

        if (requestCode == CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE) {
            if (resultCode == RESULT_OK) {
                // Video captured and saved to fileUri specified in the Intent
                Toast.makeText(this, "Video saved to:\n" +
                        data.getData(), Toast.LENGTH_LONG).show();
            } else if (resultCode == RESULT_CANCELED) {
                // User cancelled the video capture
            } else {
                // Video capture failed, advise user
            }
        }
    }

不用上截圖了,就是這么簡單。

二、使用 Camera 編碼

按照文檔的步驟,最后卻沒有搞定,真心讓我很受傷。經(jīng)過一周的折騰,最后還是借助網(wǎng)友的力量搞定。

需要的權(quán)限

        <uses-permission android:name="android.permission.CAMERA" />
        <uses-feature android:name="android.hardware.camera" />
        <uses-feature android:name="android.hardware.camera.autofocus" />
        <uses-permission
         android:name="android.permission.RECORD_AUDIO">
        </uses-permission>
        <uses-permission
          android:name="android.permission.WRITE_EXTERNAL_STORAGE">
        </uses-permission> 

流程

簡單的流程如下圖:

http://wiki.jikexueyuan.com/project/android-actual-combat-skills/images/31-1.png" alt="fig.1" />

MediaRecorder 狀態(tài)圖:

http://wiki.jikexueyuan.com/project/android-actual-combat-skills/images/31-2.gif" alt="fig.2" />

初始化 SurfaceView 與 SurfaceViewHolder

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

            mSurfaceView = (SurfaceView)findViewById(R.id.surfaceview);
            mSurfaceHolder = mSurfaceView.getHolder();
            mSurfaceHolder.addCallback(new Callback() {
                @Override
                public void surfaceDestroyed(SurfaceHolder holder) {
                    releaseCamera();
                }

                @Override
                public void surfaceCreated(SurfaceHolder holder) {
                    initPreview();
                }

                @Override
                public void surfaceChanged(SurfaceHolder holder, int format, int width,
                        int height) {

                }
            });
    protected void initPreview() {
            mCamera = Camera.open(CameraInfo.CAMERA_FACING_BACK);
            try {
                mCamera.setPreviewDisplay(mSurfaceHolder);
            } catch (IOException e) {
                e.printStackTrace();
            }
            setCameraDisplayOrientation(this,CameraInfo.CAMERA_FACING_BACK,mCamera);
            mCamera.startPreview();
        }

        public static void setCameraDisplayOrientation(Activity activity,
                 int cameraId, android.hardware.Camera camera) {
             android.hardware.Camera.CameraInfo info =
                     new android.hardware.Camera.CameraInfo();
             android.hardware.Camera.getCameraInfo(cameraId, info);
             int rotation = activity.getWindowManager().getDefaultDisplay()
                     .getRotation();
             int degrees = 0;
             switch (rotation) {
                 case Surface.ROTATION_0: degrees = 0; break;
                 case Surface.ROTATION_90: degrees = 90; break;
                 case Surface.ROTATION_180: degrees = 180; break;
                 case Surface.ROTATION_270: degrees = 270;  break;
             }

             int result;
             if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
                 result = (info.orientation + degrees) % 360;
                 result = (360 - result) % 360;  //  compensate the mirror
             } else {  // back-facing
                 result = (info.orientation - degrees + 360) % 360;
             }
             camera.setDisplayOrientation(result);
         }

拍照

拍照還是很簡單的,實現(xiàn) PictureCallback 接口:

        private Camera.PictureCallback mPicture = new Camera.PictureCallback() {

            @Override
            public void onPictureTaken(byte[] data, Camera camera) {
                Log.d(TAG,"onPictureTaken");
                mPhotoFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
                if (mPhotoFile == null){
                    Log.d(TAG, "Error creating media file, check storage permissions: ");
                    return;
                }

                try {
                    FileOutputStream fos = new FileOutputStream(mPhotoFile);
                    fos.write(data);
                    fos.close();
                    Log.d(TAG,"save picture success");
                    //notify
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                        Intent mediaScanIntent = new Intent(
                                Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
                        Uri contentUri = Uri.fromFile(mPhotoFile); //out is your output  file
                        mediaScanIntent.setData(contentUri);
                        MainActivity.this.sendBroadcast (mediaScanIntent);
                    } else {
                        sendBroadcast(new Intent(

                                Intent.ACTION_MEDIA_MOUNTED,
                                Uri.parse("file://"
                                        +     Environment.getExternalStorageDirectory())));
                    }
                    mCamera.reconnect();
                } catch (FileNotFoundException e) {
                    Log.d(TAG, "File not found: " + e.getMessage());
                } catch (IOException e) {
                    Log.d(TAG, "Error accessing file: " + e.getMessage());
                }
            }
        };

調(diào)用 takePitcture 方法:

    public void onPhotoClicked(View view) {
        mCamera.takePicture(null, null, mPicture);
    }

錄像

有了上述的準(zhǔn)備,啟動錄像的功能就相對清晰一些,它分為下面的步驟:

    private void startMediaRecorder() {
        mCamera.unlock();
        mIsRecording = true;
        mMediaRecorder = new MediaRecorder();
        mMediaRecorder.reset();
        mMediaRecorder.setCamera(mCamera);
        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
        mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
        CamcorderProfile mCamcorderProfile = CamcorderProfile.get(CameraInfo.CAMERA_FACING_BACK,
                CamcorderProfile.QUALITY_HIGH);
        mMediaRecorder.setProfile(mCamcorderProfile);
        mMediaRecorder.setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO).toString());
        mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());

        try {
            mMediaRecorder.prepare();
        } catch (Exception e) {
            mIsRecording = false;
            Toast.makeText(this, "fail", Toast.LENGTH_LONG).show();
            e.printStackTrace();
            mCamera.lock();
        }
        mMediaRecorder.start();
    }

圖片與視頻保存的路徑:

    private File getOutputMediaFile(int type) {
        File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
                Environment.DIRECTORY_PICTURES), "Camera App");
        // This location works best if you want the created images to be shared
        // between applications and persist after your app has been uninstalled.

        // Create the storage directory if it does not exist
        if (! mediaStorageDir.exists()){
            if (! mediaStorageDir.mkdirs()){
                Log.d("linc", "failed to create directory");
                return null;
            }
        }

        // Create a media file name
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        File mediaFile;
        if (type == MEDIA_TYPE_IMAGE){
            mediaFile = new File(mediaStorageDir.getPath() + File.separator +
                    "IMG_"+ timeStamp + ".jpg");
        } else if(type == MEDIA_TYPE_VIDEO) {
            mediaFile = new File(mediaStorageDir.getPath() + File.separator +
                    "VID_"+ timeStamp + ".mp4");
        } else {
            return null;
        }

        return mediaFile;
    }

代碼的其余部分:

    public static final int MEDIA_TYPE_IMAGE = 1;
    public static final int MEDIA_TYPE_VIDEO = 2;

    private Camera mCamera;
    private SurfaceView mSurfaceView;
    private SurfaceHolder mSurfaceHolder;
    private Button startButton;
    private boolean mIsRecording = false;
    private MediaRecorder mMediaRecorder;
    private File mPhotoFile;
    protected void releaseCamera() {
        if(mCamera!=null){
            mCamera.stopPreview();
            mCamera.release();
            mCamera = null;
        }
    }
        private void stopMediaRecorder() {
        if(mMediaRecorder !=null){
            if(mIsRecording){
                mMediaRecorder.stop();
                //mCamera.lock();
                mMediaRecorder.reset();
                mMediaRecorder.release();
                mMediaRecorder =null;
                mIsRecording = false;
                try {
                    mCamera.reconnect();
                } catch (IOException e) {
                    Toast.makeText(this, "reconect fail", Toast.LENGTH_LONG).show();
                    e.printStackTrace();
                }
            }
        }
    }

參考:

sdk/docs/guide/topics/media/camera.html#custom-camera

http://blog.csdn.net/shen332401890/article/details/8819564