Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

S3(GT-I9300) Camera preview holder bug

Tags:

android

camera

We created a custom camera based on android.hardware.Camera class. When we press the button "take a photo", the expected behavior is to take the photo and see the still captured photo on a Review Screen. BUT , the camera still works / the viewfinder is showing a 'live' shot (instead of the still Review) when we get to the Review Screen. It looks like the holder doesn't work.

This has been observed on some Samsung Galaxy S3 phones (GT-I9300); but strangely on all other models everything works fine (the still image appears in the Review Screen as it should).

like image 283
GeX Avatar asked Feb 11 '13 22:02

GeX


1 Answers

My solution up to this point is to create a layout where a view takes up the same view as the surfaceview.

Then I get the view bounds for the preview (in my case it's the size of the screen)

//Get our screen size
    Display display = ((WindowManager) getSystemService(Context.WINDOW_SERVICE))
            .getDefaultDisplay();
    DisplayMetrics metrics = getResources().getDisplayMetrics();
    Point size = new Point();
    try {
        display.getSize(size);
        w_width = size.x;
        w_height = size.y;
    } catch (NoSuchMethodError e) {
        w_width = display.getWidth();
        w_height = display.getHeight();
    }

Then I set the callback to be:

callback = new Camera.PictureCallback() {
            @Override
            public void onPictureTaken(byte[] bytes, Camera camera) {
                //Get the view bounds to determine how to manipulate this image
                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inJustDecodeBounds = true;
                BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);

                //If the image is smaller than the screen, don't make the image bigger
                int finalWidth = (w_width < options.outWidth) ? w_width : options.outWidth;
                int finalHeight = (w_height < options.outHeight) ? w_height : options.outHeight;
                int inSampleSize = 1;
                options = new BitmapFactory.Options();
                if (finalHeight > w_height || finalWidth > w_width) {

                    // Calculate ratios of height and width to requested height and width
                    final int heightRatio = Math.round((float) finalHeight / (float) w_height);
                    final int widthRatio = Math.round((float) finalWidth / (float) w_width);

                    // Choose the smallest ratio as inSampleSize value, this will guarantee
                    // a final image with both dimensions larger than or equal to the
                    // requested height and width.
                    inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
                }

                options.inSampleSize = inSampleSize;

                //Decode the smaller image
                Bitmap b = BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);

                //Rotate the image correctly
                Matrix mat = new Matrix();
                mat.postRotate(orientation);
                Bitmap newBitmap = Bitmap.createBitmap(b, 0, 0, options.outWidth, options.outHeight, mat, true);
                imagePreview.setBackgroundDrawable(new BitmapDrawable(newBitmap));
                imagePreview.setVisibility(View.VISIBLE);
            }
        };

So basically the surface view never stops showing the preview, but the imageview hides it so the user can't see it.

Then if the user decides not to keep the image then I just re-hide the view and the surfaceView will keep showing the live preview. Luckily the GS3 does not seem to mind someone calling "camera.startPreview();" even when the preview is already happening.

I really don't like this answer but it's all I have at the moment that works on the galaxy S3. It has worked on older devices (2.3 and up) that I have tried but it is definitely just a work-around.

like image 73
BoredAndroidDeveloper Avatar answered Oct 07 '22 10:10

BoredAndroidDeveloper