Ask Your Question

Android: getting largest preview image possible

asked 2013-03-06 10:11:45 -0600

Barry Thomas gravatar image

updated 2013-03-07 03:36:31 -0600

The Nexus 4 has a screen res of 1280x768 (with no title bar etc).

According to getResolutionList() the largest preview image from OpenCV (item 0 in the list) is 1280x720, so in onCameraFrame, why does the image always come through at a maximum of 800x480.

Even when I try to force the size to the maximum using setResolution(mResolutionList.get(0)) it sticks at 800x480.

Can anyone give me some clue as to what I'm doing wrong?

Many thanks


EDIT: ps I'm using 2.4.4 on Android 4.2.

EDIT: To add some explanation about the answer, here's a picture:

image description

The total screen res on the Nexus is 1280x768, but that includes the buttons on the right, so the total screen I have to play with is 1196x768 (the red dotted line). The largest preview image reported by getResolutionList is 1280x720, but that won't fit, so despite being listed as available... it isn't really.

Next job: Work out how to scale up the largest preview which will fit (800x480 - the blue dotted line) to fill the screen without slamming performance.

edit retag flag offensive close merge delete

2 answers

Sort by ยป oldest newest most voted

answered 2013-03-06 11:53:17 -0600

NativeCameraView and JavaCameraView classes base on size of View surface on the screen, where frame will be drawn. In most cases it is smaller then screen. It becomes smaller if some additional elements like panels and headers are included in layout. You can check your application layout and element sizes with hierarchyviewer tool from Android SDK (sdk/tools/hierarchyviewer).

edit flag offensive delete link more


Thanks Alexander, HierarchyViewer was really helpful. So the View caps the size of inputFrame before you even see it. It is a bit confusing that getResolutionList includes a size which can never be set.

What is the recommended technique to scale inputFrame to the size of the View without a big performance hit?

Many thanks


Barry Thomas gravatar imageBarry Thomas ( 2013-03-07 03:17:49 -0600 )edit

You need to make changes in library code. Open CameraBridgeViewBase class source code, find canvas.drawBitmap call and set right destination rectangle. If it is larger then original bitmap, canvas scales it automatically. There is open task on bug tracker: This option will be added to new SDK release.

Alexander Smorkalov gravatar imageAlexander Smorkalov ( 2013-03-07 04:54:19 -0600 )edit

Nice addition, I look forward to seeing that. Thanks. I won't start editing the library code, I use the Manager, I'm happy to wait for the new release.

Barry Thomas gravatar imageBarry Thomas ( 2013-03-07 05:02:50 -0600 )edit

All Java code from OpenCV Library project is added to your application package and build time. So, you can freely modify it and use OpenCV Manager. The only think you cannot change is native functions. Additionally you can set full screen style in manifest.

Alexander Smorkalov gravatar imageAlexander Smorkalov ( 2013-03-07 05:19:34 -0600 )edit

Great news, all working now. I'll post a complete answer when I have updated my app on Play and my website. Thanks for the support.

Barry Thomas gravatar imageBarry Thomas ( 2013-03-07 06:13:53 -0600 )edit

answered 2013-03-14 07:21:06 -0600

Barry Thomas gravatar image

Here's what I did (thanks Alexander):

This code goes into in order to scale the bitmap to the size of the screen. The file is at:

[your path to the sdk]\OpenCV-2.4.4-android-sdk\sdk\java\src\org\opencv\android

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) {

            ////// THIS IS THE CHANGED PART /////////////////////
            int width = mCacheBitmap.getWidth();
            int height = mCacheBitmap.getHeight();
            float scaleWidth = ((float) canvas.getWidth()) / width;
            float scaleHeight = ((float) canvas.getHeight()) / height;
            float fScale = Math.min(scaleHeight,  scaleWidth);
            Matrix matrix = new Matrix();
            // RESIZE THE BITMAP
            matrix.postScale(fScale, fScale);


            Bitmap resizedBitmap = Bitmap.createBitmap(mCacheBitmap, 0, 0, width, height, matrix, false);

            canvas.drawBitmap(resizedBitmap, (canvas.getWidth() - resizedBitmap.getWidth()) / 2, (canvas.getHeight() - resizedBitmap.getHeight()) / 2, null);
            if (mFpsMeter != null) {
                mFpsMeter.draw(canvas, 20, 30);

So I now have an image which looks like this:

image description

Which was what I wanted.

edit flag offensive delete link more


The same functionality already implemented in branch 2.4 and will be published in the next release. See the ticket for more details:

Alexander Smorkalov gravatar imageAlexander Smorkalov ( 2013-03-15 02:34:53 -0600 )edit

That's great, and you'll probably do a neater job than I did! :)

Barry Thomas gravatar imageBarry Thomas ( 2013-03-15 03:52:09 -0600 )edit
Login/Signup to Answer

Question Tools



Asked: 2013-03-06 10:11:45 -0600

Seen: 4,979 times

Last updated: Mar 14 '13