Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to overlay an image or view on top of a camera captured image

What I am doing is drawing an image from the camera on to a canvas, then convert a view containing an image into a bitmap and draw it on top of the canvas. Then the final bitmap gets saved to the external storage.

the problem is the canvas appears to be sizing itself to the preview window size, instead of the saved image size.

Here is the part in my activity class that is merging the captured view on top of the camera image:

        Bitmap myImage = BitmapFactory.decodeByteArray(imageData, 0,
                imageData.length, options);
        Bitmap mutableBitmap = myImage.copy(Bitmap.Config.ARGB_8888, true);

        Paint paint = new Paint();
        Canvas canvas = new Canvas(mutableBitmap);

        view.setDrawingCacheEnabled(true);
        viewCapture = Bitmap.createBitmap(view.getDrawingCache());
        view.setDrawingCacheEnabled(false);
        canvas.drawBitmap(viewCapture, 0, 0, paint);

        fileOutputStream = new FileOutputStream(dir + "/" + imgName + ".jpg");

        BufferedOutputStream bos = new BufferedOutputStream(fileOutputStream);
        mutableBitmap.compress(CompressFormat.JPEG, quality, bos);

This saves the bitmap on top of the captured image, but due to the different sizes, its offset into the top left hand corner.

I'm setting the different sizes by doing the following in my surfaceChanged

  Camera.Parameters p = mCamera.getParameters();
  Camera.Size myBestPreviewSize = getBestPreviewSize(w, h, p);
  p.setPreviewSize(myBestPreviewSize.width, myBestPreviewSize.height);
  Camera.Size myBestPictureSize = getBestPictureSize(w, h, p);
  p.setPictureSize(myBestPictureSize.width, myBestPictureSize.height);

Obviously by doing this, I am getting the best resolution for the preview window, and the best resolution for the captured image. I believe the issue is caused by the two different resolutions, but figuring out why is where I'm stuck.

Hopefully the following images will better describe the issue:

This image shows the preview windows. As you can see the Android is in the dead middle of the image. enter image description here

I capture the image above and it gets saved. I go to view it and this is what it looks like: enter image description here

Notice the Android is no longer in the middle, its in the top left corner.

As another test, I moved the android part way off the screen as shown in the next camera preview enter image description here

I capture the image exactly as shown above, and upon viewing it, the android is cut off exactly how it was in the preview window, but again its in the top left hand corner when it should be full screen enter image description here

like image 707
Badams Avatar asked Mar 07 '13 00:03

Badams


1 Answers

Bitmaps retrieved from the camera are going to be massive (2000+ px wide). Your SurfaceView where you draw the image is only as large as your device resolution (~1000px wide). When you draw the one onto the other, you need to scale it, or it will end up 1/2 the size it should be (as in your screenshots). Here's how I'd modify your code.

view.setDrawingCacheEnabled(true);
viewCapture = Bitmap.createBitmap(view.getDrawingCache());
view.setDrawingCacheEnabled(false);
//Source Rect sized to the surface view.
Rect src = new Rect(0, 0, viewCapture.getWidth(), viewCapture.getHeight());
//Destination RectF sized to the camera picture
RectF dst = new RectF(0, 0, myImage.getWidth(), myImage.getHeight());
canvas.drawBitmap(viewCapture, src, dst, paint);

I know you make some effort to set the camera parameters and size, but either it's not working or you need to take a different approach. I think this should work, though. Your second screenshots, where the Android guy is clipped in both images suggest it's just a simple scaling problem.

Hope that helps!

like image 80
thomas88wp Avatar answered Oct 31 '22 09:10

thomas88wp