Android开发使用OpenCv中JavaCameraView预览图左旋90度问题

转自:https://blog.csdn.net/yd_yandong/article/details/52698696

本文参考地址:http://stackoverflow.com/questions/14816166/rotate-camera-preview-to-portrait-android-opencv-camera点击打开链接

至于预览图左旋90的问题不再贴图了

下面说一下解决办法:

我使用的开发工是Android Studio 2.2

如果你导入了OpenCv的SDK,请继续阅读,其他请立即关闭本博客。

首先找到CameraBridgeViewBase这个类:添加全局变量

 
private WindowManager windowManager;

接下来是构造方法中对windowManager初始化:

 
  1. public CameraBridgeViewBase(Context context, int cameraId) {

  2. super(context);

  3. mCameraIndex = cameraId;

  4. getHolder().addCallback(this);

  5. mMaxWidth = MAX_UNSPECIFIED;

  6. mMaxHeight = MAX_UNSPECIFIED;

  7. windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);

  8. }

  9.  
  10. public CameraBridgeViewBase(Context context, AttributeSet attrs) {

  11. super(context, attrs);

  12.  
  13. int count = attrs.getAttributeCount();

  14. Log.d(TAG, "Attr count: " + Integer.valueOf(count));

  15.  
  16. TypedArray styledAttrs = getContext().obtainStyledAttributes(attrs, R.styleable.CameraBridgeViewBase);

  17. if (styledAttrs.getBoolean(R.styleable.CameraBridgeViewBase_show_fps, false))

  18. enableFpsMeter();

  19.  
  20. mCameraIndex = styledAttrs.getInt(R.styleable.CameraBridgeViewBase_camera_id, -1);

  21.  
  22. getHolder().addCallback(this);

  23. mMaxWidth = MAX_UNSPECIFIED;

  24. mMaxHeight = MAX_UNSPECIFIED;

  25. windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);

  26. styledAttrs.recycle();

  27. }


接下来把deliverAndDrawFrame(CvCameraViewFrame frame)方法替换为下面的代码:

 
  1. protected void deliverAndDrawFrame(CvCameraViewFrame frame) {

  2. Mat modified;

  3.  
  4. if (mListener != null) {

  5. modified = mListener.onCameraFrame(frame);

  6. } else {

  7. modified = frame.rgba();

  8. }

  9.  
  10. boolean bmpValid = true;

  11. if (modified != null) {

  12. try {

  13. Utils.matToBitmap(modified, mCacheBitmap);

  14. } catch (Exception e) {

  15. Log.e(TAG, "Mat type: " + modified);

  16. Log.e(TAG, "Bitmap type: " + mCacheBitmap.getWidth() + "*" + mCacheBitmap.getHeight());

  17. Log.e(TAG, "Utils.matToBitmap() throws an exception: " + e.getMessage());

  18. bmpValid = false;

  19. }

  20. }

  21.  
  22. if (bmpValid && mCacheBitmap != null) {

  23. Canvas canvas = getHolder().lockCanvas();

  24. if (canvas != null) {

  25. canvas.drawColor(0, android.graphics.PorterDuff.Mode.CLEAR);

  26. int rotation = windowManager.getDefaultDisplay().getRotation();

  27. int degrees = 0;

  28. // config degrees as you need

  29. switch (rotation) {

  30. case Surface.ROTATION_0:

  31. degrees = 90;

  32. break;

  33. case Surface.ROTATION_90:

  34. degrees = 0;

  35. break;

  36. case Surface.ROTATION_180:

  37. degrees = 270;

  38. break;

  39. case Surface.ROTATION_270:

  40. degrees = 180;

  41. break;

  42. }

  43.  
  44. Matrix matrix = new Matrix();

  45. matrix.postRotate(degrees);

  46. Bitmap outputBitmap = Bitmap.createBitmap(mCacheBitmap, 0, 0, mCacheBitmap.getWidth(), mCacheBitmap.getHeight(), matrix, true);

  47.  
  48. if (outputBitmap.getWidth() <= canvas.getWidth()) {

  49. mScale = getRatio(outputBitmap.getWidth(), outputBitmap.getHeight(), canvas.getWidth(), canvas.getHeight());

  50. } else {

  51. mScale = getRatio(canvas.getWidth(), canvas.getHeight(), outputBitmap.getWidth(), outputBitmap.getHeight());

  52. }

  53.  
  54. if (mScale != 0) {

  55. canvas.scale(mScale, mScale, 0, 0);

  56. }

  57. Log.d(TAG, "mStretch value: " + mScale);

  58.  
  59. canvas.drawBitmap(outputBitmap, 0, 0, null);

  60.  
  61. if (mFpsMeter != null) {

  62. mFpsMeter.measure();

  63. mFpsMeter.draw(canvas, 20, 30);

  64. }

  65. getHolder().unlockCanvasAndPost(canvas);

  66.  
  67. }

  68. }

  69. }

上面还引用了getRatio(int widthSource, int heightSource, int widthTarget, int heightTarget)方法:

 
  1. private float getRatio(int widthSource, int heightSource, int widthTarget, int heightTarget) {

  2. if (widthTarget <= heightTarget) {

  3. return (float) heightTarget / (float) heightSource;

  4. } else {

  5. return (float) widthTarget / (float) widthSource;

  6. }

  7. }


看到这里你也许已经明白了,核心代码是如下这些:

 
 
  1. int rotation = windowManager.getDefaultDisplay().getRotation();

  2. int degrees = 0;

  3. // config degrees as you need

  4. switch (rotation) {

  5. case Surface.ROTATION_0:

  6. degrees = 90;

  7. break;

  8. case Surface.ROTATION_90:

  9. degrees = 0;

  10. break;

  11. case Surface.ROTATION_180:

  12. degrees = 270;

  13. break;

  14. case Surface.ROTATION_270:

  15. degrees = 180;

  16. break;

  17. }

  18.  
  19. Matrix matrix = new Matrix();

  20. matrix.postRotate(degrees);

其实就是更改Rotation参数。
下面看一下效果:

现在可能又出现了一个问题:图像预览界面不能全屏,如图:画红色线条部分为黑色边框。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值