打印手机摄像头的支持参数+将预览帧转换为位图+获取最佳预览

举报
ShaderJoy 发表于 2021/12/29 23:56:12 2021/12/29
【摘要】 打印手机摄像头的支持参数+将预览帧转换为位图 public class SecondActivity extends Activity implements SurfaceHolder.Callback, PreviewCallback{ // 定义对象 private SurfaceView mSurfaceview = null...

打印手机摄像头的支持参数+将预览帧转换为位图


  
  1. public class SecondActivity extends Activity implements SurfaceHolder.Callback,
  2. PreviewCallback
  3. {
  4. // 定义对象
  5. private SurfaceView mSurfaceview = null; // SurfaceView对象:(视图组件)视频显示
  6. private SurfaceHolder mSurfaceHolder = null; // SurfaceHolder对象:(抽象接口)SurfaceView支持类
  7. private Camera mCamera = null; // Camera对象,相机预览
  8. private String TAG = "SnapCamera";
  9. private boolean bIfPreview = false;
  10. private int mPreviewWidth;
  11. private int mPreviewHeight;
  12. Bitmap mBitmap = null;
  13. @Override
  14. protected void onCreate(Bundle savedInstanceState)
  15. {
  16. // TODO Auto-generated method stub
  17. super.onCreate(savedInstanceState);
  18. setContentView(R.layout.activity_main);
  19. initSurfaceView();
  20. }
  21. // InitSurfaceView
  22. private void initSurfaceView()
  23. {
  24. mSurfaceview = (SurfaceView) this.findViewById(R.id.CameraView);
  25. mSurfaceHolder = mSurfaceview.getHolder(); // 绑定SurfaceView,取得SurfaceHolder对象
  26. mSurfaceHolder.addCallback(SecondActivity.this); // SurfaceHolder加入回调接口
  27. // mSurfaceHolder.setFixedSize(176, 144); // 预览大小設置
  28. mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);// 设置显示器类型,setType必须设置
  29. }
  30. /* 【2】【相机预览】 */
  31. private void initCamera()// surfaceChanged中调用
  32. {
  33. Log.i(TAG, "going into initCamera");
  34. if (bIfPreview)
  35. {
  36. mCamera.stopPreview();// stopCamera();
  37. }
  38. if (null != mCamera)
  39. {
  40. try
  41. {
  42. /* Camera Service settings */
  43. Camera.Parameters parameters = mCamera.getParameters();
  44. // parameters.setFlashMode("off"); // 无闪光灯
  45. parameters.setPictureFormat(PixelFormat.JPEG); // Sets the image format for picture 设定相片格式为JPEG,默认为NV21
  46. parameters.setPreviewFormat(PixelFormat.YCbCr_420_SP); // Sets the image format for preview picture,默认为NV21
  47. /*
  48. * 【ImageFormat】JPEG/NV16(YCrCb format,used for
  49. * Video)/NV21(YCrCb format,used for Image)/RGB_565/YUY2/YU12
  50. */
  51. // 【调试】获取camera支持的PictrueSize,看看能否设置
  52. List<Size> pictureSizes = mCamera.getParameters()
  53. .getSupportedPictureSizes();
  54. List<Size> previewSizes = mCamera.getParameters()
  55. .getSupportedPreviewSizes();
  56. List<Integer> previewFormats = mCamera.getParameters()
  57. .getSupportedPreviewFormats();
  58. List<Integer> previewFrameRates = mCamera.getParameters()
  59. .getSupportedPreviewFrameRates();
  60. Log.i(TAG + "initCamera", " support parameters is ");
  61. Size psize = null;
  62. for (int i = 0; i < pictureSizes.size(); i++)
  63. {
  64. psize = pictureSizes.get(i);
  65. Log.i(TAG + "initCamera", "PictrueSize,width: "
  66. + psize.width + " height:" + psize.height);
  67. }
  68. for (int i = 0; i < previewSizes.size(); i++)
  69. {
  70. psize = previewSizes.get(i);
  71. Log.i(TAG + "initCamera", "PreviewSize,width: "
  72. + psize.width + " height:" + psize.height);
  73. }
  74. Integer pf = null;
  75. for (int i = 0; i < previewFormats.size(); i++)
  76. {
  77. pf = previewFormats.get(i);
  78. Log.i(TAG + "initCamera", "PreviewFormats:" + pf);
  79. }
  80. Iterator<Integer> it = previewFrameRates.iterator();
  81. while (it.hasNext())
  82. {
  83. Log.i(TAG + "initCamera", "PreviewFrameRates:" + it.next());
  84. }
  85. // 设置拍照和预览图片大小
  86. parameters.setPictureSize(640, 480); // 指定拍照图片的大小
  87. parameters.setPreviewSize(mPreviewWidth, mPreviewHeight); // 指定preview的大小
  88. // 这两个属性 如果这两个属性设置的和真实手机的不一样时,就会报错
  89. // 横竖屏镜头自动调整
  90. if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE)
  91. {
  92. parameters.set("orientation", "portrait"); //
  93. parameters.set("rotation", 90); // 镜头角度转90度(默认摄像头是横拍)
  94. mCamera.setDisplayOrientation(90); // 在2.2以上可以使用
  95. } else
  96. // 如果是横屏
  97. {
  98. parameters.set("orientation", "landscape"); //
  99. mCamera.setDisplayOrientation(0); // 在2.2以上可以使用
  100. }
  101. /* 视频流编码处理 */
  102. // 添加对视频流处理函数
  103. // 设定配置参数并开启预览
  104. mCamera.setParameters(parameters); // 将Camera.Parameters设定予Camera
  105. mCamera.startPreview(); // 打开预览画面
  106. bIfPreview = true;
  107. // 【调试】设置后的图片大小和预览大小以及帧率
  108. Camera.Size csize = mCamera.getParameters().getPreviewSize();
  109. mPreviewHeight = csize.height;
  110. mPreviewWidth = csize.width;
  111. Log.i(TAG + "initCamera", "After setting, PreviewSize:width: "
  112. + csize.width + " height: " + csize.height);
  113. csize = mCamera.getParameters().getPictureSize();
  114. Log.i(TAG + "initCamera", "After setting, PictrueSize:width: "
  115. + csize.width + " height: " + csize.height);
  116. Log.i(TAG + "initCamera", "After setting, PreviewFormat is "
  117. + mCamera.getParameters().getPreviewFormat());
  118. Log.i(TAG + "initCamera", "After setting, PreviewFrameRate is "
  119. + mCamera.getParameters().getPreviewFrameRate());
  120. } catch (Exception e)
  121. {
  122. e.printStackTrace();
  123. }
  124. }
  125. }
  126. /* 【SurfaceHolder.Callback 回调函数】 */
  127. public void surfaceCreated(SurfaceHolder holder)
  128. // SurfaceView启动时/初次实例化,预览界面被创建时,该方法被调用。
  129. {
  130. // TODO Auto-generated method stub
  131. mCamera = Camera.open();// 开启摄像头(2.3版本后支持多摄像头,需传入参数)
  132. try
  133. {
  134. Log.i(TAG, "SurfaceHolder.Callback:surface Created");
  135. mCamera.setPreviewDisplay(mSurfaceHolder);// set the surface to be
  136. // used for live preview
  137. mCamera.setPreviewCallback(SecondActivity.this);
  138. } catch (Exception ex)
  139. {
  140. if (null != mCamera)
  141. {
  142. mCamera.release();
  143. mCamera = null;
  144. }
  145. Log.i(TAG + "initCamera", ex.getMessage());
  146. }
  147. }
  148. public void surfaceChanged(SurfaceHolder holder, int format, int width,
  149. int height)
  150. // 当SurfaceView/预览界面的格式和大小发生改变时,该方法被调用
  151. {
  152. // TODO Auto-generated method stub
  153. Log.i(TAG, "SurfaceHolder.Callback: Surface Changed");
  154. mPreviewHeight = height;
  155. mPreviewWidth = width;
  156. initCamera();
  157. }
  158. public void surfaceDestroyed(SurfaceHolder holder)
  159. // SurfaceView销毁时,该方法被调用
  160. {
  161. // TODO Auto-generated method stub
  162. Log.i(TAG, "SurfaceHolder.Callback:Surface Destroyed");
  163. if (null != mCamera)
  164. {
  165. mCamera.setPreviewCallback(null); // !!这个必须在前,不然退出出错
  166. mCamera.stopPreview();
  167. bIfPreview = false;
  168. mCamera.release();
  169. mCamera = null;
  170. }
  171. }
  172. @Override
  173. public void onPreviewFrame(byte[] data, Camera camera)
  174. {
  175. // TODO Auto-generated method stub
  176. Camera.Parameters parameters = camera.getParameters();
  177. int format = parameters.getPreviewFormat();
  178. if (mBitmap != null)
  179. {
  180. mBitmap.recycle();
  181. mBitmap = null;
  182. }
  183. // YUV formats require more conversion
  184. if (format == PixelFormat.YCbCr_420_SP
  185. || format == PixelFormat.YCbCr_422_I)
  186. {
  187. int w = 100/* parameters.getPreviewSize().width */;
  188. int h = 100/* parameters.getPreviewSize().height */;
  189. // Get the YuV image 由于此方法适用于android 2.2版本,所以此处不能用。
  190. // YuvImage yuv_image = new YuvImage(data, format, w, h, null);
  191. // // Convert YuV to Jpeg
  192. // Rect rect = new Rect(0, 0, w, h);
  193. // ByteArrayOutputStream output_stream = new
  194. // ByteArrayOutputStream();
  195. // yuv_image.compressToJpeg(rect, 100, output_stream);
  196. // // Convert from Jpeg to Bitmap
  197. // bitmap2 = BitmapFactory.decodeByteArray(output_stream
  198. // .toByteArray(), 0, output_stream.size());
  199. int[] i = new int[data.length];
  200. decodeYUV420SP(i, data, w, h);
  201. mBitmap = Bitmap.createBitmap(i, w, h, Bitmap.Config.RGB_565);
  202. // mBitmap = renderCroppedGreyscaleBitmap(data, w, h);
  203. // Log.e(TAG, "Image format is YUV:" + format);
  204. }
  205. // Jpeg and RGB565 are supported by BitmapFactory.decodeByteArray
  206. else if (format == PixelFormat.JPEG || format == PixelFormat.RGB_565)
  207. {
  208. // Log.e(TAG, "Image format is JPEG/RGB:" + format);
  209. mBitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
  210. }
  211. }
  212. private void decodeYUV420SP(int[] rgb, byte[] yuv420sp, int width,
  213. int height)
  214. {
  215. // TODO Auto-generated method stub
  216. final int frameSize = width * height;
  217. for (int j = 0, yp = 0; j < height; j++)
  218. {
  219. int uvp = frameSize + (j >> 1) * width, u = 0, v = 0;
  220. for (int i = 0; i < width; i++, yp++)
  221. {
  222. int y = (0xff & ((int) yuv420sp[yp])) - 16;
  223. if (y < 0)
  224. y = 0;
  225. if ((i & 1) == 0)
  226. {
  227. v = (0xff & yuv420sp[uvp++]) - 128;
  228. u = (0xff & yuv420sp[uvp++]) - 128;
  229. }
  230. int y1192 = 1192 * y;
  231. int r = (y1192 + 1634 * v);
  232. int g = (y1192 - 833 * v - 400 * u);
  233. int b = (y1192 + 2066 * u);
  234. if (r < 0)
  235. r = 0;
  236. else if (r > 262143)
  237. r = 262143;
  238. if (g < 0)
  239. g = 0;
  240. else if (g > 262143)
  241. g = 262143;
  242. if (b < 0)
  243. b = 0;
  244. else if (b > 262143)
  245. b = 262143;
  246. rgb[yp] = 0xff000000 | ((r << 6) & 0xff0000)
  247. | ((g >> 2) & 0xff00) | ((b >> 10) & 0xff);
  248. }
  249. }
  250. }
  251. }

在给定最大范围的条件下获取最佳预览的方法:


  
  1. private void getBestPreviewSize(Camera camera, Parameters parameters, SurfaceView cameraView)
  2. {
  3. int bestWidth=0;
  4. int bestHeight=0;
  5. List<Size> previewSizes=parameters.getSupportedPreviewSizes();
  6. if(previewSizes.size()>1)
  7. {
  8. Iterator<Size> cei=previewSizes.iterator();
  9. while(cei.hasNext())
  10. {
  11. Size aSize=cei.next();
  12. Log.v("snap shot","Checking "+aSize.width+"*"+aSize.height);
  13. if(aSize.width>bestWidth && aSize.width<=LARGETST_WIDTH
  14. && aSize.height >bestHeight
  15. && aSize.height<=LARGETST_HEIGHT)
  16. {
  17. bestWidth=aSize.width;
  18. bestHeight=aSize.height;
  19. }
  20. }
  21. if(bestHeight!=0 && bestWidth!=0)
  22. {
  23. Log.v("snap shot","Using "+bestWidth+"*"+ bestHeight);
  24. parameters.setPreviewSize(bestWidth,bestHeight);
  25. cameraView.setLayoutParams(new LinearLayout.LayoutParams(bestWidth,bestHeight));
  26. }
  27. }
  28. camera.setParameters(parameters);
  29. }


文章来源: panda1234lee.blog.csdn.net,作者:panda1234lee,版权归原作者所有,如需转载,请联系作者。

原文链接:panda1234lee.blog.csdn.net/article/details/8711095

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。