简体   繁体   English

尽管设置了尺寸,但SurfaceView上的相机预览仍被拉伸

[英]Camera preview on SurfaceView is stretched despite setting sizes

I'm trying to make the camera preview correctly show up on a SurfaceView . 我试图使相机预览正确显示在SurfaceView However, despite trying to getSupportedPictureSizes() and setting both pictureSize and previewSize to one of the values from the list, the preview is still very, very stretched. 但是,尽管尝试获取getSupportedPictureSizes()并将pictureSizepreviewSize都设置为列表中的值之一,但预览仍然非常非常拉伸。

I decided I wanted the size to be 1280 by 720 pixels, and I've set this value everywhere (and again, it's on the getSupportedPictureSizes() , as well as getSupportedPreviewSizes() ) 我决定我希望尺寸为1280 x 720像素,并且在所有位置都设置了此值(同样,它在getSupportedPictureSizes()getSupportedPreviewSizes()

I have browsed all of the Stackoverflow posts on the issue, and I can't seem to get it solved. 我已经浏览了有关此问题的所有Stackoverflow帖子,但似乎无法解决。 Any help is appreciated. 任何帮助表示赞赏。

surfaceCreated() for my SurfaceHolder: 我的SurfaceHolder的surfaceCreated():

public void surfaceCreated(SurfaceHolder holder)
{
    Camera.Parameters parameters = camera.getParameters();

    parameters.setPictureSize(1280, 720);
    parameters.setPreviewSize(1280, 720);

    Log.d("SurfaceView", surfaceView.getWidth() + ", " + surfaceView.getHeight());

    camera.setParameters(parameters);
    camera.setDisplayOrientation(90);

    previewCamera();
}

SurfaceView design XML: SurfaceView设计XML:

<SurfaceView
    android:layout_width="1280px"
    android:layout_height="720px"
    android:layout_gravity="center_horizontal"
    android:id="@+id/surfaceViewCamera"
    android:layout_alignParentBottom="true"
    android:layout_centerHorizontal="true"/>

Entire activity class: 整个活动类别:

package org.ownzone.security_droid;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.hardware.Camera;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.WindowManager;
import android.widget.CompoundButton;
import android.widget.Switch;
import android.widget.TextView;

public class AuthenticatedActivity extends ActionBarActivity
{
    private ServerConnection sc = ServerConnection.getServerConnectionInstance();
    private boolean active;

    private Camera camera;
    private SurfaceView surfaceView;
    private SurfaceHolder surfaceHolder;
    private boolean isPreviewRunning;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_authenticated);

        active = false;
        isPreviewRunning = false;

        TextView headline = (TextView) findViewById(R.id.textViewHeadLine);
        headline.setText(getIntent().getStringExtra("cardholder") + " authenticated");

        Switch activeSwitch = (Switch) findViewById(R.id.switchActive);
        activeSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
        {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
            {
                active = isChecked;
            }
        });

        surfaceView = (SurfaceView) findViewById(R.id.surfaceViewCamera);

        camera = Camera.open();

        for (Camera.Size size : camera.getParameters().getSupportedPictureSizes())
        {
            Log.d("Size", size.width + ", " + size.height);
        }

        surfaceHolder = surfaceView.getHolder();
        surfaceHolder.addCallback(surfaceHolderCallback);
        //camera.setPreviewDisplay(surfaceView.getHolder());
        //camera.startPreview();

        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
    }

    private void takePhoto()
    {
        camera.takePicture(shutterCallback, rawPictureCallback, jpegPictureCallback);
    }

    SurfaceHolder.Callback surfaceHolderCallback = new SurfaceHolder.Callback()
    {
        @Override
        public void surfaceCreated(SurfaceHolder holder)
        {
            Camera.Parameters parameters = camera.getParameters();

            parameters.setPictureSize(1280, 720);
            parameters.setPreviewSize(1280, 720);

            Log.d("SurfaceView", surfaceView.getWidth() + ", " + surfaceView.getHeight());

            camera.setParameters(parameters);
            camera.setDisplayOrientation(90);

            previewCamera();
        }

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
        {

        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder)
        {

        }
    };

    public void previewCamera()
    {
        try
        {
            camera.setPreviewDisplay(surfaceHolder);
            camera.startPreview();
            isPreviewRunning = true;
        }
        catch (Exception e)
        {
            Log.d("AuthenticatedActivity", "Cannot start preview", e);
        }
    }


    Camera.ShutterCallback shutterCallback = new Camera.ShutterCallback()
    {
        public void onShutter()
        {

        }
    };

    Camera.PictureCallback rawPictureCallback = new Camera.PictureCallback()
    {
        public void onPictureTaken(byte[] data, Camera camera)
        {

        }
    };

    Camera.PictureCallback jpegPictureCallback = new Camera.PictureCallback()
    {
        public void onPictureTaken(byte[] data, Camera camera)
        {
            Bitmap bitmapPicture = BitmapFactory.decodeByteArray(data, 0, data.length);
            Bitmap correctBmp = Bitmap.createBitmap(bitmapPicture, 0, 0, bitmapPicture.getWidth(), bitmapPicture.getHeight(), null, true);

        }
    };
}

Without a screenshot, this is a bit of a guess, but I'd suspect your call to setDisplayOrientation. 没有屏幕截图,这有点猜测,但是我怀疑您对setDisplayOrientation的调用。

A hardcoded value there may work for a single device or a set of devices, but in general, you need to take into account several factors - see the documentation here: http://developer.android.com/reference/android/hardware/Camera.html#setDisplayOrientation(int) 此处的硬编码值可能适用于单个设备或一组设备,但是通常,您需要考虑多个因素-请参见此处的文档: http : //developer.android.com/reference/android/hardware/ Camera.html#setDisplayOrientation(int)

And in general, on most devices (but not all!), if you have a landscape app on a phone, you'll end up with calling setDisplayOrientation(0), not 90. 通常,在大多数设备上(但不是全部!),如果手机上有风景应用程序,则最终会调用setDisplayOrientation(0)而不是90。

Is your app landscape- or portrait-oriented (or flexible?)? 您的应用是横向还是纵向(还是灵活的?)? And a screenshot would be very helpful in ruling out various issues. 屏幕截图对于排除各种问题非常有帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM