사용자 지정 카메라(1)
25846 단어 사용자 정의
5.0 이전 릴리즈에서 카메라를 사용자화하는 절차는 다음과 같습니다.
하나, 사용자 정의 카메라를 만드는 절차
1. 카메라 찾기 및 사용 권한 얻기
카메라의 존재를 감지하고 권한을 얻습니다
카메라 장치 코드 확인
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
//
return true;
} else {
//
return false;
}
카메라 사용 가능한 코드 확인
Camera c = null;
try {
c = Camera.open(); //
}
catch (Exception e){
//
}
2. 미리 보기 보기 클래스 만들기
클래스는 SurfaceView의 하위 클래스여야 합니다.
사용자 정의 보기 클래스로
그 주요 업무는 서로 다른 이벤트 내에서 전송된 Camera 실례를 통해 미리 보기 보기(Preview)를 제어하는 것이다.
구체적인 API 데모 코드는 다음과 같습니다.
/** A basic Camera preview class */
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
public CameraPreview(Context context, Camera camera) {
super(context);
mCamera = camera;
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = getHolder();
mHolder.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, now tell the camera where to draw the preview.
try {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
} catch (IOException e) {
Log.d(TAG, "Error setting camera preview: " + e.getMessage());
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// empty. Take care of releasing the Camera preview in your activity.
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// ,
// Make sure to stop the preview before resizing or reformatting it.
if (mHolder.getSurface() == null){
// preview surface does not exist
return;
}
// stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e){
// ignore: tried to stop a non-existent preview
}
// set preview size and make any resize, rotate or
// reformatting changes here
// start preview with new settings
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e){
Log.d(TAG, "Error starting camera preview: " + e.getMessage());
}
}
}
3. 미리 보기 레이아웃 만들기
비교적 간단한 레이아웃으로 나중에 카메라 미리보기를 표시하는 SurfaceView는 코드를 통해 FrameLayout에 추가됩니다.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<FrameLayout
android:id="@+id/camera_preview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
/>
<Button
android:id="@+id/button_capture"
android:text="Capture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
/>
</LinearLayout>
이에 대응하는 Activity의 주요 코드는 다음과 같습니다.
public class CameraActivity extends Activity {
private Camera mCamera;
private CameraPreview mPreview;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Camera
mCamera = Camera.open();
// Activity Preview SurfaceView
mPreview = new CameraPreview(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(mPreview);
}
}
4. 촬영 동작을 감청
버튼이 동작을 감청하고 초점을 맞추기 시작한다
구체적인 코드 구현은 일반 감청과 마찬가지로 초점을 맞추면camera를 사용할 수 있다.autoFocus(autoFocusCallBack);
autoFocusCallBack은 AutoFocusCallback의 실례로 초점 맞추기가 끝난 후의 조작을 되돌리는 데 주로 사용된다.
예를 들어 Camera를 통해서.takePicture(shutter, PictureCallback, PictureCallback) 캡처 이미지
5. 사진 캡처 및 저장
Camera를 통해takePicture(shutter, PictureCallback, PictureCallback) 이미지를 캡처한 후 저장해야 합니다.
private PictureCallback mPicture = new PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
if (pictureFile == null){
Log.d(TAG, "Error creating media file, check storage permissions: " +
e.getMessage());
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
}
}
};
이상은 공식 API의 데모로 onPictureTaken 방법을 통해 포획된 이미지 데이터를 획득하여 참고할 수 있습니다.
6. 카메라 리소스 여유 확보
이전의surfaceDestroyed에서camera를 통과할 수 있습니다.release는 다른 응용 프로그램의 사용에 영향을 주지 않도록 카메라 자원을 방출합니다
다음은 자신이 쓴 데모입니다. 그림이 간단하고 많이 절약되었고 구조도 어지럽습니다. 그러나 기본적인 사진 기능은 이미 실현되었습니다.
package com.rw.demo;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
import android.hardware.Camera;
import android.hardware.Camera.AutoFocusCallback;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.ShutterCallback;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
public class CameraDemo extends Activity {
private SurfaceView cameraSurface;
private SurfaceHolder myHolder;
private boolean isPreview=false;
Camera camera;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.camera_layout);
getView();
//
myHolder=cameraSurface.getHolder();
myHolder.addCallback(new Callback() {
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
CameraDemo.this.initCamera(holder);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
});
}
/**
*
* @param holder
* @throws IOException
*/
@SuppressWarnings("deprecation")
protected void initCamera(SurfaceHolder holder) throws IOException {
if(!isPreview)
camera=Camera.open(1);
camera.setDisplayOrientation(90);
if(camera!=null && !isPreview){
camera.setPreviewDisplay(holder);
camera.startPreview();
isPreview=true;
}
}
/**
*
*/
private void getView() {
cameraSurface=(SurfaceView) findViewById(R.id.camera_surface_id);
}
/**
*
* @param v
*/
public void takePhoto(View v){
if(camera!=null){
Log.i("CameraDemo"," !");
camera.autoFocus(autoFocusCallBack);
}
}
//
AutoFocusCallback autoFocusCallBack =new AutoFocusCallback() {
@Override
public void onAutoFocus(boolean success, Camera camera) {
if(success){
camera.takePicture(new ShutterCallback() {
@Override
public void onShutter() {
}
}, new PictureCallback(){
@Override
public void onPictureTaken(byte[] data, Camera camera) {
}
}, jpeg);
}
}
};
//
PictureCallback jpeg=new PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
//
final Bitmap bm=BitmapFactory.decodeByteArray(data,0, data.length);
File file=new File(Environment.getExternalStorageDirectory(),"testPicture.jpg");
FileOutputStream outStream =null;
try {
outStream=new FileOutputStream(file);
bm.compress(CompressFormat.JPEG, 100, outStream);
outStream.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
camera.stopPreview();
camera.startPreview();
isPreview=true;
}
};
//
@Override
protected void onDestroy() {
super.onDestroy();
if(camera!=null){
camera.release();
}
}
@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
}
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Vue 어셈블리에서 여러 번 사용자 정의 매개변수 작업 재사용추가 정보: VUE 구성 요소(슬롯 slot 및 재사용 가능 구성 요소) 하위 구성 요소의 일부 내용이 부모 구성 요소를 통해 DOM을 전달할 때 부모 구성 요소props 전가의 비교적 좌절된 문법을 사용하지 않아도...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.