上次已經編寫了一個非常簡單的相機程式(Simple Camera Program),當然相機除了預覽(Preview)外,還可以做出不同的功能,拍照是其中不可缺少的功能,拍照後還可以作後期的處理,如測距、人面檢測、文字辨測或 QR 掃描等等,所以是很實用程式,需要研究怎樣編寫相機拍照程式(Camera Take Photo Program)。
Android Studio - 相機拍照程式(Camera Take Photo Program)(七十): |
- 操作系統:Windows 7 64-bit 版本
- 開發環境:Android Studio 4.0.1 版本
- 原程式:C:\Development\Development_Android\Android_Project\DIY-Android-091-11b Camera Takephoto
- 程式:C:\Development\Development_Android\Android_Project\DIY-Android-091-11b Camera Takephoto
- 測試環境:Vivo(維沃)X5Max Android 4.4.4(KitKat)版本
簡單相機程式(Simple Camera Program)編程步驟:
- 設定 Camera 許可權限後 - AndroidManifest.xml
- 設定 SurfaceView 參數 - init_View()
- 啟動 SurfaceView Callback - mSurfaceHolder.addCallback(this);
- 打開 Camera - Camera.open()
- 設置 Camera 參數 - setParameters()
- StartPreview Camera 顯示 - setPreviewDisplay(surfaceHolder) → startPreview()
- 設置 Button Takephoto 參數
- 截取 Camera 圖像 - takePhotoViaCamera()
- 儲存相片 - SaveImage()
AndroidManifest.xml 獲取 Camera 許可權:
<uses-feature android:name="android.hardware.camera" /> <uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> |
activity_camera_takephoto.xml:
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent">
<SurfaceView android:id="@+id/activity_camera_surface" android:layout_width="match_parent" android:layout_height="match_parent" />
<Button android:id="@+id/btn_camera_photo" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="200dp" android:text="Take Photo" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout> |
CameraTakePhoto.java:
package bugworkshop.blogspot.com.camera;
import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle;
// Camera import android.hardware.Camera;
// SurfaceView import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.widget.Button;
// Takephoto import android.graphics.Bitmap; import android.graphics.BitmapFactory; import java.io.ByteArrayOutputStream; import android.graphics.Matrix; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException;
public class CameraTakePhoto extends AppCompatActivity implements SurfaceHolder.Callback{
private Button mbtn_camera_photo;
// Camera private Camera mCamera;
// SurfaceView private SurfaceView mSurfaceView; private SurfaceHolder mSurfaceHolder;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_camera_takephoto);
mbtn_camera_photo = (Button)findViewById(R.id.btn_camera_photo);
mbtn_camera_photo.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { takePhotoViaCamera(); } });
init_View(); }
public void init_View() { mSurfaceView = (SurfaceView)findViewById(R.id.activity_camera_surface); mSurfaceHolder = mSurfaceView.getHolder(); mSurfaceHolder.addCallback(this); mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); }
@Override public void surfaceCreated(@NonNull SurfaceHolder surfaceHolder) { mCamera = Camera.open(); if (mCamera != null) { Camera.Parameters p = mCamera.getParameters(); p.setPreviewSize(640, 480); p.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); mCamera.setParameters(p); }
try { mCamera.setPreviewDisplay(surfaceHolder); mCamera.startPreview(); } catch (IOException e) { e.printStackTrace(); } }
@Override public void surfaceChanged(@NonNull SurfaceHolder surfaceHolder, int i, int i1, int i2) { }
@Override public void surfaceDestroyed(@NonNull SurfaceHolder surfaceHolder) { }
// Take Photo public void takePhotoViaCamera() { if (mCamera != null) { mCamera.takePicture(new Camera.ShutterCallback() { @Override public void onShutter() { } }, new Camera.PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { } }, new Camera.PictureCallback() { @Override public void onPictureTaken(final byte[] data, Camera camera) { saveImage(data); mCamera.startPreview(); } }); } }
public void saveImage(byte[] data) { BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 6; options.inDither = false; options.inPurgeable = true; options.inInputShareable = true; options.inTempStorage = new byte[32 * 1024]; options.inPreferredConfig = Bitmap.Config.RGB_565; Bitmap bMap = BitmapFactory.decodeByteArray(data, 0, data.length, options);
int orientation; if (bMap.getHeight() < bMap.getWidth()) { orientation = 90; } else { orientation = 0; }
Bitmap bMapRotate; if (orientation != 0) { Matrix matrix = new Matrix(); matrix.postRotate(orientation); bMapRotate = Bitmap.createBitmap(bMap, 0, 0, bMap.getWidth(), bMap.getHeight(), matrix, true); } else { bMapRotate = Bitmap.createScaledBitmap(bMap, bMap.getWidth(), bMap.getHeight(), true); } FileOutputStream out; try { out = new FileOutputStream("/sdcard/PictPreview.png"); ByteArrayOutputStream stream = new ByteArrayOutputStream(); bMapRotate.compress(Bitmap.CompressFormat.PNG, 100, stream); out.write(stream.toByteArray()); out.flush(); if (bMapRotate != null) { bMapRotate.recycle(); bMapRotate = null; } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } |
沒有留言:
張貼留言