android camera stretched in landscape mode
Asked Answered
M

2

23

The app I'm writing requires camera functionality. So to learn about how to operate the camera, I followed this script:

http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/graphics/CameraPreview.html

I have put the activity in my manifest, set the screen orientation for it on landscape mode.

The problem I'm having is, when the camera is held sideways (so I hold my Galaxy Tab P1000 in landscape position) the view is stretched out.

To be more specific about my script, I used an exact copy of code that Google made. It can be found in the android-sdk\samples\android-8\ApiDemos\src\com\example\android\apis\graphics\

The file itself is called CameraPreview.

I really have no clue why the screen looks so stretched. Of course, the format is weird and not square, but still, when using the default camera app installed on the device, it doesn't deform at all. This camera deforms the image when I hold it sideways and move the camera even a little.

enter image description here

enter image description here

What I did was: I held my galaxy tab to take a picture of an object (laptop in this case) then took a picture with my phone of my Galaxy. On the Galaxy I have the camera screen open in the app i'm making. This counts for both images. One I hold sideways and one I hold in portrait view. The pics are a bit unclear but you can see that in the landscape picture, the camera has become massively wide.

Minimus answered 28/9, 2011 at 9:12 Comment(3)
T_T So am I the only one in the world having this problem? <:Minimus
I am experiencing this issue too...Factorage
This question is a hidden gem! I had a hard time searching for this. Having used all keywords in google. This question saved my life.Sulfatize
E
22

I faced the same problem yesterday. After a researching "Camera" sources I found a reason for camera preview being stretched.

The reason is: SurfaceView aspect ratio (width/height) MUST be same as Camera.Size aspect ratio used in preview parameters. And if aspect ratio is not the same, you've got stretched image.

So, the fastest workaround is to set SurfaceView to size like 320px x 240px - smallest supported size from Parameters.getSupportedPreviewSizes().

Also, you can look at Camera standard application sources, it uses the custom layout for controlling the SurfaceView size (see PreviewFrameLayout.java, onMeasure() function).

Use

git clone https://android.googlesource.com/platform/packages/apps/Camera.git

to get Camera sources.

Evanish answered 3/3, 2012 at 11:27 Comment(3)
+1 for describing the actual problem. You can find the height and width of the SurfaceView in surfaceChanged, then use getSupportedPreviewSizes on the Camera parameters object to find the closest match and set the SurfaceView to the needed acceptable size.Troytroyer
am doing like this,but doesnt work. private Camera.Size getBestPreviewSize(int width, int height, Camera.Parameters parameters) { Camera.Size result = null; for (Camera.Size size : parameters.getSupportedPreviewSizes()) { if (size.width <= width && size.height <= height) { if (result == null) { result = size; } else { int resultArea = result.width * result.height; int newArea = size.width * size.height; if (newArea > resultArea) { result = size; } } } } return (result); }Eupatrid
Your code is just searching for biggest preview size that fits in initial width and height. Of course you having problems with stretched screen, because biggest doesnt mean "best aspect ratio". You need to fit your preview View size to that "biggest" size, by adjusting its width or height so, that ratio=width/height will be the same for initial values (width, height) and for final values (result.width, result.height)Evanish
I
8
public void surfaceCreated(SurfaceHolder holder) {
        // TODO Auto-generated method stub

        try {
            camera = Camera.open();

            camera.setDisplayOrientation(90);
            camera.setPreviewDisplay(holder);
            Camera.Parameters parameters = camera.getParameters();
            List<Size> sizes = parameters.getSupportedPictureSizes();
            parameters.setPictureSize(sizes.get(0).width, sizes.get(0).height); // mac dinh solution 0
            parameters.set("orientation","portrait");
            //parameters.setPreviewSize(viewWidth, viewHeight);
            List<Size> size = parameters.getSupportedPreviewSizes();
            parameters.setPreviewSize(size.get(0).width, size.get(0).height);
            camera.setParameters(parameters);
            camera.startPreview();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

You need only getSupportedPreviewSizes() and save it to a List:

List<Size> size = parameters.getSupportedPreviewSizes();
            parameters.setPreviewSize(size.get(0).width, size.get(0).height);
            camera.setParameters(parameters); 



camera.startPreview(); 

I hope this helps you.

Innoxious answered 6/10, 2012 at 4:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.