本文参考地址:http://stackoverflow.com/questions/14816166/rotate-camera-preview-to-portrait-android-opencv-camera点击打开链接
至于预览图左旋90的问题不再贴图了
下面说一下解决办法:
我使用的开发工是Android Studio 2.2
如果你导入了OpenCv的SDK,请继续阅读,其他请立即关闭本博客。
首先找到CameraBridgeViewBase这个类:添加全局变量
接下来是构造方法中对windowManager初始化:private WindowManager windowManager;
public CameraBridgeViewBase(Context context, int cameraId) { super(context); mCameraIndex = cameraId; getHolder().addCallback(this); mMaxWidth = MAX_UNSPECIFIED; mMaxHeight = MAX_UNSPECIFIED; windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); } public CameraBridgeViewBase(Context context, AttributeSet attrs) { super(context, attrs); int count = attrs.getAttributeCount(); Log.d(TAG, "Attr count: " + Integer.valueOf(count)); TypedArray styledAttrs = getContext().obtainStyledAttributes(attrs, R.styleable.CameraBridgeViewBase); if (styledAttrs.getBoolean(R.styleable.CameraBridgeViewBase_show_fps, false)) enableFpsMeter(); mCameraIndex = styledAttrs.getInt(R.styleable.CameraBridgeViewBase_camera_id, -1); getHolder().addCallback(this); mMaxWidth = MAX_UNSPECIFIED; mMaxHeight = MAX_UNSPECIFIED; windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); styledAttrs.recycle(); }
接下来把deliverAndDrawFrame(CvCameraViewFrame frame)方法替换为下面的代码:上面还引用了getRatio(int widthSource, int heightSource, int widthTarget, int heightTarget)方法:protected void deliverAndDrawFrame(CvCameraViewFrame frame) { Mat modified; if (mListener != null) { modified = mListener.onCameraFrame(frame); } else { modified = frame.rgba(); } boolean bmpValid = true; if (modified != null) { try { Utils.matToBitmap(modified, mCacheBitmap); } catch (Exception e) { Log.e(TAG, "Mat type: " + modified); Log.e(TAG, "Bitmap type: " + mCacheBitmap.getWidth() + "*" + mCacheBitmap.getHeight()); Log.e(TAG, "Utils.matToBitmap() throws an exception: " + e.getMessage()); bmpValid = false; } } if (bmpValid && mCacheBitmap != null) { Canvas canvas = getHolder().lockCanvas(); if (canvas != null) { canvas.drawColor(0, android.graphics.PorterDuff.Mode.CLEAR); int rotation = windowManager.getDefaultDisplay().getRotation(); int degrees = 0; // config degrees as you need switch (rotation) { case Surface.ROTATION_0: degrees = 90; break; case Surface.ROTATION_90: degrees = 0; break; case Surface.ROTATION_180: degrees = 270; break; case Surface.ROTATION_270: degrees = 180; break; } Matrix matrix = new Matrix(); matrix.postRotate(degrees); Bitmap outputBitmap = Bitmap.createBitmap(mCacheBitmap, 0, 0, mCacheBitmap.getWidth(), mCacheBitmap.getHeight(), matrix, true); if (outputBitmap.getWidth() <= canvas.getWidth()) { mScale = getRatio(outputBitmap.getWidth(), outputBitmap.getHeight(), canvas.getWidth(), canvas.getHeight()); } else { mScale = getRatio(canvas.getWidth(), canvas.getHeight(), outputBitmap.getWidth(), outputBitmap.getHeight()); } if (mScale != 0) { canvas.scale(mScale, mScale, 0, 0); } Log.d(TAG, "mStretch value: " + mScale); canvas.drawBitmap(outputBitmap, 0, 0, null); if (mFpsMeter != null) { mFpsMeter.measure(); mFpsMeter.draw(canvas, 20, 30); } getHolder().unlockCanvasAndPost(canvas); } } }
private float getRatio(int widthSource, int heightSource, int widthTarget, int heightTarget) { if (widthTarget <= heightTarget) { return (float) heightTarget / (float) heightSource; } else { return (float) widthTarget / (float) widthSource; } }
看到这里你也许已经明白了,核心代码是如下这些:其实就是更改Rotation参数。int rotation = windowManager.getDefaultDisplay().getRotation(); int degrees = 0; // config degrees as you need switch (rotation) { case Surface.ROTATION_0: degrees = 90; break; case Surface.ROTATION_90: degrees = 0; break; case Surface.ROTATION_180: degrees = 270; break; case Surface.ROTATION_270: degrees = 180; break; } Matrix matrix = new Matrix(); matrix.postRotate(degrees);
下面看一下效果:
现在可能又出现了一个问题:图像预览界面不能全屏,如图:画红色线条部分为黑色边框。