转自: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初始化:
-
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参数。
下面看一下效果:
现在可能又出现了一个问题:图像预览界面不能全屏,如图:画红色线条部分为黑色边框。