Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Renders openCV's camera in portrait mode on android - to be placed in `CameraBridgeViewBase.java`
private final Matrix mMatrix = new Matrix();
private void updateMatrix() {
float mw = this.getWidth();
float mh = this.getHeight();
float hw = this.getWidth() / 2.0f;
float hh = this.getHeight() / 2.0f;
float cw = (float)Resources.getSystem().getDisplayMetrics().widthPixels; //Make sure to import Resources package
float ch = (float)Resources.getSystem().getDisplayMetrics().heightPixels;
float scale = cw / (float)mh;
float scale2 = ch / (float)mw;
if(scale2 > scale){
scale = scale2;
}
boolean isFrontCamera = mCameraIndex == CAMERA_ID_FRONT;
mMatrix.reset();
if (isFrontCamera) {
mMatrix.preScale(-1, 1, hw, hh); //MH - this will mirror the camera
}
mMatrix.preTranslate(hw, hh);
if (isFrontCamera){
mMatrix.preRotate(270);
} else {
mMatrix.preRotate(90);
}
mMatrix.preTranslate(-hw, -hh);
mMatrix.preScale(scale,scale,hw,hh);
}
@Override
public void layout(int l, int t, int r, int b) {
super.layout(l, t, r, b);
updateMatrix();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
updateMatrix();
}
/**
* This method shall be called by the subclasses when they have valid
* object and want it to be delivered to external client (via callback) and
* then displayed on the screen.
* @param frame - the current frame to be delivered
*/
protected void deliverAndDrawFrame(CvCameraViewFrame frame) { //replaces existing deliverAndDrawFrame
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 saveCount = canvas.save();
canvas.setMatrix(mMatrix);
if (mScale != 0) {
canvas.drawBitmap(mCacheBitmap, new Rect(0,0,mCacheBitmap.getWidth(), mCacheBitmap.getHeight()),
new Rect((int)((canvas.getWidth() - mScale*mCacheBitmap.getWidth()) / 2),
(int)((canvas.getHeight() - mScale*mCacheBitmap.getHeight()) / 2),
(int)((canvas.getWidth() - mScale*mCacheBitmap.getWidth()) / 2 + mScale*mCacheBitmap.getWidth()),
(int)((canvas.getHeight() - mScale*mCacheBitmap.getHeight()) / 2 + mScale*mCacheBitmap.getHeight())), null);
} else {
canvas.drawBitmap(mCacheBitmap, new Rect(0,0,mCacheBitmap.getWidth(), mCacheBitmap.getHeight()),
new Rect((canvas.getWidth() - mCacheBitmap.getWidth()) / 2,
(canvas.getHeight() - mCacheBitmap.getHeight()) / 2,
(canvas.getWidth() - mCacheBitmap.getWidth()) / 2 + mCacheBitmap.getWidth(),
(canvas.getHeight() - mCacheBitmap.getHeight()) / 2 + mCacheBitmap.getHeight()), null);
}
//Restore canvas after draw bitmap
canvas.restoreToCount(saveCount);
if (mFpsMeter != null) {
mFpsMeter.measure();
mFpsMeter.draw(canvas, 20, 30);
}
getHolder().unlockCanvasAndPost(canvas);
}
}
}
@sontqq

This comment has been minimized.

Copy link

@sontqq sontqq commented Aug 7, 2019

Works fine. Thank you!

@topherbuckley

This comment has been minimized.

Copy link

@topherbuckley topherbuckley commented Sep 12, 2019

@heaversm Have you submitted a pull request for any of this in the opencv repo? It would be nice to have this functionality built in rather than directly modifying their library files.

@topherbuckley

This comment has been minimized.

Copy link

@topherbuckley topherbuckley commented Sep 12, 2019

Also, it appears there is some ambiguity to the Matrix package. android.graphics and android.opengl both have a Matrix class. It appears the reset() and preScae() methods are from android.graphics.Matrix. Maybe include a comment on this? Side note: is there any reason you can't use the native Mat type in openCV?

@homandiy

This comment has been minimized.

Copy link

@homandiy homandiy commented Apr 7, 2020

It works! Let's clap for Mike. Here is my record: https://www.linkedin.com/pulse/android-opencv-349-part-2-cameraview-homan-huang/?published=t
I have 17fps.

@oppicool

This comment has been minimized.

Copy link

@oppicool oppicool commented May 18, 2020

thanks a lot!

@winterwindwang

This comment has been minimized.

Copy link

@winterwindwang winterwindwang commented Aug 7, 2020

thank a lot!

@kishandonga

This comment has been minimized.

Copy link

@kishandonga kishandonga commented Aug 20, 2020

thanks it's working

@SpookyMask

This comment has been minimized.

Copy link

@SpookyMask SpookyMask commented Oct 16, 2020

Thank you! I just can't translate a point backward from the screen to the mat, any idea how to do that?

@jusjinuk

This comment has been minimized.

Copy link

@jusjinuk jusjinuk commented Jan 14, 2021

thx! Helped a lot.

@MohammadAzimi

This comment has been minimized.

Copy link

@MohammadAzimi MohammadAzimi commented Jun 21, 2021

awsome!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment