Android Camera(二)

时间:2023-03-09 02:48:31
Android Camera(二)

上次已经写过SurfaceView显示Camera摄像了,代码可以运行,但是里面有问题,这次纠正过来,顺便实现变焦:

代码:

  1. public class CameravedioActivity extends Activity{
  2. private static final String TAG = "CameravedioActivity";
  3. private Camera camera;
  4. private boolean preview  = false ;
  5. private SeekBar mSeekBar;
  6. private SurfaceView surfaceView;
  7. private SurfaceHolder surfaceHolder;
  8. @Override
  9. public void onCreate(Bundle savedInstanceState) {
  10. super.onCreate(savedInstanceState);
  11. /*
  12. *设置窗口属性:一定要在 setContentView(R.layout.main) 之前
  13. */
  14. // 窗口标题,其实可以在manifes文件里面注册
  15. //     requestWindowFeature(Window.FEATURE_NO_TITLE);
  16. // 全屏
  17. getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
  18. setContentView(R.layout.main);
  19. surfaceView =  (SurfaceView) findViewById(R.id.surfaceView);
  20. surfaceHolder = surfaceView.getHolder();
  21. surfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
  22. surfaceView.getHolder().setFixedSize(200, 200);
  23. surfaceView.getHolder().addCallback(new SurfaceViewCallback());
  24. /**
  25. * seekbar 用来实现变焦逻辑
  26. */
  27. mSeekBar = (SeekBar)findViewById(R.id.seekbar);
  28. mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener(){
  29. @Override
  30. public void onProgressChanged(SeekBar seekBar, int progress,
  31. boolean fromUser) {
  32. // TODO Auto-generated method stub
  33. Log.d(TAG, "progress:"+progress);
  34. //          sdk 文档描述 set zoom 之前先check
  35. if(camera.getParameters().isZoomSupported()){
  36. Parameters params = camera.getParameters();
  37. params.setZoom(progress);
  38. camera.setParameters(params);
  39. }
  40. }
  41. @Override
  42. public void onStartTrackingTouch(SeekBar seekBar) {
  43. // TODO Auto-generated method stub
  44. Log.d(TAG, "onStartTrackingTouch");
  45. }
  46. @Override
  47. public void onStopTrackingTouch(SeekBar seekBar) {
  48. // TODO Auto-generated method stub
  49. Log.d(TAG, "onStartTrackingTouch");
  50. }
  51. });
  52. }
  53. @Override
  54. protected void onResume() {
  55. // TODO Auto-generated method stub
  56. super.onResume();
  57. }
  58. public static void setCameraDisplayOrientation(Activity activity,
  59. int cameraId, android.hardware.Camera camera) {
  60. android.hardware.Camera.CameraInfo info =
  61. new android.hardware.Camera.CameraInfo();
  62. android.hardware.Camera.getCameraInfo(cameraId, info);
  63. int rotation = activity.getWindowManager().getDefaultDisplay()
  64. .getRotation();
  65. int degrees = 0;
  66. Log.d(TAG, "rotation:"+rotation);
  67. switch (rotation) {
  68. case Surface.ROTATION_0: degrees = 0; break;
  69. case Surface.ROTATION_90: degrees = 90; break;
  70. case Surface.ROTATION_180: degrees = 180; break;
  71. case Surface.ROTATION_270: degrees = 270; break;
  72. }
  73. int result;
  74. if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
  75. result = (info.orientation + degrees) % 360;
  76. result = (360 - result) % 360;  // compensate the mirror
  77. } else {  // back-facing
  78. result = (info.orientation - degrees + 360) % 360;
  79. }
  80. camera.setDisplayOrientation(result);
  81. }
  82. private final class SurfaceViewCallback implements Callback {
  83. /**
  84. * surfaceView 被创建成功后调用此方法
  85. */
  86. @Override
  87. public void surfaceCreated(SurfaceHolder holder) {
  88. Log.d(TAG,"surfaceCreated");
  89. /*
  90. * 在SurfaceView创建好之后 打开摄像头
  91. * 注意是 android.hardware.Camera
  92. */
  93. //          2.2获取摄像头number physical cameras
  94. //          api 9: Camera.getNumberOfCameras()
  95. Log.d(TAG, "numbers:"+Camera.getNumberOfCameras());
  96. if(Camera.getNumberOfCameras() ==2){
  97. //              前置摄像头
  98. //              api 9 :Camera.CameraInfo
  99. camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);
  100. camera.setDisplayOrientation(90);
  101. }else{
  102. camera = Camera.open();
  103. }
  104. //          camera = Camera.open();
  105. //          setCameraDisplayOrientation(CameravedioActivity.this,Camera.CameraInfo.CAMERA_FACING_FRONT,camera);
  106. Log.d(TAG, "smoothZoom:"+camera.getParameters().isSmoothZoomSupported());
  107. Log.d(TAG, "supportzoom:"+camera.getParameters().isZoomSupported());
  108. Log.d(TAG, "max zoom:"+camera.getParameters().getMaxZoom());
  109. /*
  110. * This method must be called before startPreview(). otherwise surfaceview没有图像
  111. */
  112. try {
  113. camera.setPreviewDisplay(surfaceHolder);
  114. } catch (IOException e) {
  115. // TODO Auto-generated catch block
  116. e.printStackTrace();
  117. }
  118. Camera.Parameters parameters = camera.getParameters();
  119. /* 每秒从摄像头捕获5帧画面, */
  120. parameters.setPreviewFrameRate(5);
  121. /* 设置照片的输出格式:jpg */
  122. parameters.setPictureFormat(PixelFormat.JPEG);
  123. /* 照片质量 */
  124. parameters.set("jpeg-quality", 85);
  125. mSeekBar.setMax(parameters.getMaxZoom());
  126. //          valid parameters:
  127. // 取得相机所支持多少图片大小的个数
  128. List<Size> pszize = parameters.getSupportedPreviewSizes();
  129. //          List<Size> pszize = parameters.getSupportedPictureSizes();
  130. if (null != pszize && 0 < pszize.size()) {
  131. int height[] = new int[pszize.size()];// 声明一个数组
  132. Map<Integer, Integer> map = new HashMap<Integer, Integer>();
  133. for (int i = 0; i < pszize.size(); i++) {
  134. Size size = (Size) pszize.get(i);
  135. int sizeheight = size.height;
  136. int sizewidth = size.width;
  137. height[i] = sizeheight;
  138. map.put(sizeheight, sizewidth);
  139. Log.d(TAG, "size.width:"+sizewidth+"\tsize.height:"+sizeheight);
  140. }
  141. Arrays.sort(height);
  142. // 设置
  143. //                    parameters.setPictureSize(map.get(height[0]),height[0]);
  144. parameters.setPreviewSize(map.get(height[0]),height[0]);
  145. }
  146. /* 将参数对象赋予到 camera 对象上 */
  147. camera.setParameters(parameters);
  148. camera.startPreview();
  149. /**
  150. * Installs a callback to be invoked for every preview frame in addition to displaying them on the screen.
  151. * The callback will be repeatedly called for as long as preview is active. This method can be called at
  152. * any time, even while preview is live. Any other preview callbacks are overridden.
  153. * a callback object that receives a copy of each preview frame, or null to stop receiving
  154. */
  155. camera.setPreviewCallback(new Camera.PreviewCallback(){
  156. @Override
  157. public void onPreviewFrame(byte[] data, Camera camera) {
  158. // TODO Auto-generated method stub
  159. //在视频聊天中,这里传送本地frame数据给remote端
  160. //                  Log.d(TAG, "camera:"+camera);
  161. //                  Log.d(TAG, "byte:"+data);
  162. }
  163. });
  164. preview = true;
  165. }
  166. @Override
  167. public void surfaceChanged(SurfaceHolder holder, int format, int width,
  168. int height) {
  169. Log.d(TAG,"surfaceChanged");
  170. }
  171. /**
  172. * SurfaceView 被销毁时释放掉 摄像头
  173. */
  174. @Override
  175. public void surfaceDestroyed(SurfaceHolder holder) {
  176. if(camera != null) {
  177. /* 若摄像头正在工作,先停止它 */
  178. if(preview) {
  179. camera.stopPreview();
  180. preview = false;
  181. }
  182. //如果注册了此回调,在release之前调用,否则release之后还回调,crash
  183. camera.setPreviewCallback(null);
  184. camera.release();
  185. }
  186. }
  187. }
  188. }

注册文件:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3. package="cn.edu.wtu"
  4. android:versionCode="1"
  5. android:versionName="1.0">
  6. <application android:icon="@drawable/icon" android:label="@string/app_name">
  7. <!-- android:screenOrientation="landscape" 表示横向界面 -->
  8. <activity android:name=".CameravedioActivity" android:label="@string/app_name"  android:screenOrientation="portrait">
  9. <intent-filter>
  10. <action android:name="android.intent.action.MAIN" />
  11. <category android:name="android.intent.category.LAUNCHER" />
  12. </intent-filter>
  13. </activity>
  14. </application>
  15. <uses-sdk android:minSdkVersion="7" />
  16. <!-- 在SDCard中创建与删除文件权限 -->
  17. <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
  18. <!-- 往SDCard写入数据权限 -->
  19. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  20. <!-- 申请使用摄像头的权限 -->
  21. <uses-permission android:name="android.permission.CAMERA"/>
  22. </manifest>

布局文件:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="fill_parent"
  4. android:layout_height="fill_parent"
  5. >
  6. <LinearLayout
  7. android:layout_width="fill_parent"
  8. android:layout_height="fill_parent"
  9. android:orientation="vertical"
  10. >
  11. <SurfaceView
  12. android:id="@+id/surfaceView"
  13. android:layout_width="200dip"
  14. android:layout_height="150dip"
  15. android:layout_gravity="center"
  16. android:visibility="visible"
  17. />
  18. <LinearLayout
  19. android:layout_width="fill_parent"
  20. android:layout_height="wrap_content"
  21. >
  22. <SeekBar
  23. android:id="@+id/seekbar"
  24. android:layout_width="fill_parent"
  25. android:layout_height="wrap_content"
  26. android:layout_marginLeft="40dip"
  27. android:layout_marginRight="40dip"
  28. android:layout_gravity="center"
  29. android:progressDrawable="@android:color/transparent"
  30. android:background="@drawable/progressbar_box"
  31. />
  32. </LinearLayout>
  33. </LinearLayout>
  34. </FrameLayout>

seekbar用来实现调焦的