转自:https://blog.youkuaiyun.com/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初始化:
-
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)方法替换为下面的代码:
-
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); -
} -
} -
}
上面还引用了getRatio(int widthSource, int heightSource, int widthTarget, int heightTarget)方法:
-
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; -
} -
}
看到这里你也许已经明白了,核心代码是如下这些:
-
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);
其实就是更改Rotation参数。
下面看一下效果:
现在可能又出现了一个问题:图像预览界面不能全屏,如图:画红色线条部分为黑色边框。
本文详细介绍了如何解决Android设备上使用OpenCV进行相机预览时遇到的旋转问题,通过修改CameraBridgeViewBase类中的代码实现预览画面的正确显示。
3932

被折叠的 条评论
为什么被折叠?



