Android 直接控制摄像头并解决照片旋转90度的问题
2015-09-16 15:30
666 查看
问题背景:
大家好,我在安卓机拍照的过程中发现,使用原生相机拍照时,屏幕显示的画面范围比最后生成的照片要小。
下面给出具体的情况,请大家帮忙分析:
拍照时屏幕显示的画面:
实际照片内容:
可以看到,屏幕上呈现的画面只是照片的一部分,如示意图所示:
原生的拍照程序会有以上问题,需要通过camera API直接控制摄像头。
上面的问题只需要将surfaceView旋转90度就能解决,在代码中为: camera.setDisplayOrientation(90);
下面是源码:(参考《Android4高级编程》)
之前遇到一个bug:
当我使用下面代码时:
将代码改为下面所示则没有bug。可能是因为camera.release()的时间问题,若放在onPause()中,销毁之后还会用到camera。有时间可以仔细分析。
大家好,我在安卓机拍照的过程中发现,使用原生相机拍照时,屏幕显示的画面范围比最后生成的照片要小。
下面给出具体的情况,请大家帮忙分析:
拍照时屏幕显示的画面:
实际照片内容:
可以看到,屏幕上呈现的画面只是照片的一部分,如示意图所示:
原生的拍照程序会有以上问题,需要通过camera API直接控制摄像头。
上面的问题只需要将surfaceView旋转90度就能解决,在代码中为: camera.setDisplayOrientation(90);
下面是源码:(参考《Android4高级编程》)
package com.example.haveimgfun; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import android.annotation.SuppressLint; import android.app.Activity; import android.os.Bundle; import android.os.Environment; import android.util.Log; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.hardware.Camera; import android.hardware.Camera.AutoFocusCallback; import android.hardware.Camera.PictureCallback; import android.hardware.Camera.ShutterCallback; @SuppressLint("NewApi") public class CameraActivity extends Activity implements SurfaceHolder.Callback{ private Camera camera; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_camera); SurfaceView surface = (SurfaceView)findViewById(R.id.surfaceView); SurfaceHolder holder = surface.getHolder(); holder.addCallback(this); holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); holder.setFixedSize(400, 300); //Button to take picture Button snap = (Button)findViewById(R.id.buttonTakePicture); snap.setOnClickListener(new OnClickListener() { public void onClick(View v) { takePicture(); } }); //Button to auto focus Button autofocus = (Button)findViewById(R.id.buttonAutofocus); autofocus.setOnClickListener(new OnClickListener(){ public void onClick(View v){ doAutoFocus(); } }); } @Override public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) { // TODO Auto-generated method stub camera.cancelAutoFocus(); //release auto fucus 2如果要实现连续的自动对焦,这一句必须加上 } @Override public void surfaceCreated(SurfaceHolder holder) { // TODO Auto-generated method stub try { camera.setPreviewDisplay(holder); camera.startPreview(); camera.setDisplayOrientation(90); //by me rotate 90 //camera.startFaceDetection(); // TODO Draw over the preview if required. } catch (IOException e) { Log.d("TAG", e.getMessage()); } } @Override public void surfaceDestroyed(SurfaceHolder arg0) { // TODO Auto-generated method stub camera.setPreviewCallback(null) ; //debug camera.stopPreview(); camera.release(); camera=null; } @Override protected void onPause() { super.onPause(); //camera.release(); } @Override protected void onResume() { super.onResume(); camera = Camera.open(); //get focus area number } //define shutterCallback ShutterCallback shutterCallback = new ShutterCallback() { public void onShutter() { // TODO Do something when the shutter closes. } }; PictureCallback rawCallback = new PictureCallback() { public void onPictureTaken(byte[] data, Camera camera) { // TODO Do something with the image RAW data. } }; //stroe the picture in format jpeg PictureCallback jpegCallback = new PictureCallback() { public void onPictureTaken(byte[] data, Camera camera) { // Save the image JPEG data to the SD card FileOutputStream outStream = null; try { String path = Environment.getExternalStorageDirectory() + "/test.jpg"; outStream = new FileOutputStream(path); outStream.write(data); outStream.close(); finish(); //finish current activity } catch (FileNotFoundException e) { Log.e("TAG", "File Note Found", e); } catch (IOException e) { Log.e("TAG", "IO Exception", e); } } }; //handle button snap private void takePicture() { camera.takePicture(shutterCallback, rawCallback, jpegCallback); } //handle button auto focus private void doAutoFocus(){ Camera.Parameters parameters = camera.getParameters(); if(parameters.getSupportedFocusModes().contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)){ parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); camera.autoFocus(new AutoFocusCallback(){ public void onAutoFocus(boolean success, Camera camera){ Log.i("TAG","AutoFocus:"+(success?"Succeeded":"Failed")); } }); } } }
</pre><pre>xml:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent"> <LinearLayout android:layout_alignParentTop="true" android:id="@+id/linearLayout1" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <Button android:id="@+id/buttonAutofocus" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Autofocus" /> <Button android:id="@+id/buttonFaces" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Faces" /> <Button android:id="@+id/buttonFocusDistances" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Distances" /> <Button android:id="@+id/buttonTakePicture" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Snap" /> <Button android:id="@+id/buttonExif" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Exif" /> </LinearLayout> <SurfaceView android:layout_below="@id/linearLayout1" android:id="@+id/surfaceView" android:layout_width="match_parent" android:layout_height="match_parent" /> </RelativeLayout>
之前遇到一个bug:
当我使用下面代码时:
public void surfaceDestroyed(SurfaceHolder holder) { //camera.stopFaceDetection(); camera.stopPreview(); } @Override protected void onPause() { super.onPause(); camera.release(); }会报Method called after release()的bug
将代码改为下面所示则没有bug。可能是因为camera.release()的时间问题,若放在onPause()中,销毁之后还会用到camera。有时间可以仔细分析。
@Override public void surfaceDestroyed(SurfaceHolder arg0) { // TODO Auto-generated method stub camera.setPreviewCallback( null) ; //debug camera.stopPreview(); camera.release(); camera= null; } @Override protected void onPause() { super.onPause(); //camera.release(); }
相关文章推荐
- Android开发之Android 5.0新特性
- Android Preference技巧 持久化
- Android OnLowMemory和OnTrimMemory
- 在Android Studio中打开File Explorer
- android sqlite
- Android Studio 快捷键
- ListView中android:entries属性只能设置为string-array对象
- Android Studio 中文乱码
- Android 中关于 【Cursor】 类的介绍
- android四大组件之BroadcastReceiver广播篇
- Android 中的 Service 全面总结
- 15_09_16 Android 开发 新手如何实现 Activity 的跳转
- Android存储基础及相关源码
- Android 多渠道打包
- Android整机性能监控:多核CPU相关数据的获取(使用率、主频)
- (整理篇三)Android知识图谱
- Android studio 快捷键
- Android提高篇之自定义dialog实现processDialog“正在加载”效果、使用Animation实现图片旋转
- 值得开发者(安卓)必备的十八大Android开发资源
- Android社交类APP动态详情代码实现通用模板