Android - предварительный просмотр камеры сбоку - PullRequest
120 голосов
/ 01 октября 2010

Я использую предварительный просмотр, чтобы отобразить то, что камера видит на экране.

Я могу получить все, что работает нормально, создана поверхность, установлена ​​поверхность и отображается поверхность.

Однако этовсегда отображает изображение под неправильным углом 90 градусов в портретном режиме.

Например, на картинке:

alt text

Я знаю, что при использовании следующего кодаустановите изображение прямо:

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

Однако у меня есть предварительный просмотр внутри действия, в котором есть другие элементы, и нет смысла отображать мою активность в альбомном режиме.(По умолчанию он отключен)

Так что мне было интересно, есть ли вообще изменить ориентацию предварительного просмотра?И чтобы оставшаяся часть моей Активности правильно отображалась в Портретном режиме?

Или в любом случае повернуть предварительный просмотр так, чтобы он отображался правильно?

Ответы [ 7 ]

142 голосов
/ 24 февраля 2011

Эта проблема возникла как ошибка на определенном оборудовании см. Здесь , но ее можно устранить с помощью вызова mCamera.setDisplayOrientation (градусы), доступного в API 8. Так вот, как я ее реализую:

public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {            
    if (isPreviewRunning) {
        mCamera.stopPreview();
    }

    Parameters parameters = mCamera.getParameters();
    Display display = ((WindowManager)getSystemService(WINDOW_SERVICE)).getDefaultDisplay();

    if(display.getRotation() == Surface.ROTATION_0) {
        parameters.setPreviewSize(height, width);                           
        mCamera.setDisplayOrientation(90);
    }

    if(display.getRotation() == Surface.ROTATION_90) {
        parameters.setPreviewSize(width, height);                           
    }

    if(display.getRotation() == Surface.ROTATION_180) {
        parameters.setPreviewSize(height, width);               
    }

    if(display.getRotation() == Surface.ROTATION_270) {
        parameters.setPreviewSize(width, height);
        mCamera.setDisplayOrientation(180);
    }

    mCamera.setParameters(parameters);
    previewCamera();                      
}

And the previewCamera method :

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

Это было на HTC Desire, и мне приходилось сначала вводить записи регистрации в каждой из проверок ротации, чтобы сказать, что такое ротация, а затем отлаживать на устройстве и наблюдать вывод logCat, пока яповернул устройство.Для HTC Desire 0 был телефон, как и следовало ожидать (портрет), 90 градусов поворачивал телефон на 90 градусов по часовой стрелке (я предполагал, что это было бы по часовой стрелке).В коде, который вы увидите, мне не нужно было поворачивать дисплей, когда телефон был на 90 или 180 градусов - устройство, похоже, справилось с этим самостоятельно.Только одна точка не работает должным образом: вращение на 270 градусов происходит, когда вы поворачиваете устройство на 90 градусов по часовой стрелке, и вращение дисплея показывает, что все в порядке, но если вы поворачиваете устройство на 270 градусов против часовой стрелки, оно, похоже, не компенсирует его должным образом.

PS Обратите внимание на изменение ширины и высоты в соответствующих оборотах.

16 голосов
/ 30 сентября 2013

попробуйте установить ориентацию дисплея. Это решает мою проблему.

 mCamera.setDisplayOrientation(90);
13 голосов
/ 24 января 2013
 public void surfaceCreated(SurfaceHolder holder) {
     mCamera = Camera.open();
     mCamera.setDisplayOrientation(90);
     try {
         mCamera.setPreviewDisplay(holder);
         mCamera.setPreviewCallback(new PreviewCallback() {

             @Override
             public void onPreviewFrame(byte[] data, Camera camera) {
             }
         });

     } catch (Exception e) {
         e.printStackTrace();
     }
}

попробуйте этот код

4 голосов
/ 22 апреля 2015

У меня была проблема с передней камерой (проблема с перевернутым).Затем я использовал следующий метод, документированный в Документах Android -

public void setCameraDisplayOrientation(Activity activity , int icameraId , Camera camera1s)
    {
        CameraInfo cameraInfo = new CameraInfo();

        Camera.getCameraInfo(icameraId, cameraInfo);

        int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();

        int degrees = 0; // k

        switch (rotation)
        {
        case Surface.ROTATION_0:
            degrees = 0;
            break;
        case Surface.ROTATION_90:
            degrees = 90;
            break;
        case Surface.ROTATION_180:
            degrees = 180;
            break;
        case Surface.ROTATION_270:
            degrees = 270;
            break;

        }

        int result;

        if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT)
        {
            // cameraType=CAMERATYPE.FRONT;

            result = (cameraInfo.orientation + degrees) % 360;
            result = (360 - result) % 360; // compensate the mirror

        }
        else
        { // back-facing

            result = (cameraInfo.orientation - degrees + 360) % 360;

        }
        // displayRotate=result;
        camera.setDisplayOrientation(result);


    }
3 голосов
/ 15 мая 2013

Я сделал это по совету mCamera.setDisplayOrientation (90);но также повернул растровое изображение, потому что по какой-то причине другие подходы не работают для меня в версии 2.3.3.

Для поворота растрового изображения я сделал это:

Matrix matrix = new Matrix();
matrix.postRotate(90);
imageView1 = new ImageView(this);
Bitmap bitmap = BitmapFactory.decodeFile(files[i].getAbsolutePath());
Bitmap rotatedBitmap = Bitmap.createBitmap(bitmap , 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
Bitmap scaledBitmap = Bitmap.createScaledBitmap(rotatedBitmap, 80, 80, true);
imageView1.setImageBitmap(scaledBitmap);
0 голосов
/ 30 ноября 2016
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
    // If your preview can change or rotate, take care of those events here.
    // Make sure to stop the preview before resizing or reformatting it.

    if (mHolder.getSurface() == null) {
        // preview surface does not exist
        return;
    }

    try {
        mCamera.stopPreview();
    } catch (Exception e) {
        e.printStackTrace();
    }

    Camera.Parameters parameters = mCamera.getParameters();
    Display display = ((WindowManager) getContext().getSystemService(WINDOW_SERVICE)).getDefaultDisplay();

    if (display.getRotation() == Surface.ROTATION_0) {
        parameters.setPreviewSize(h, w);
        mCamera.setDisplayOrientation(90);
    }

    if (display.getRotation() == Surface.ROTATION_90) {
        parameters.setPreviewSize(w, h);
        mCamera.setDisplayOrientation(0);
    }

    if (display.getRotation() == Surface.ROTATION_180) {
        parameters.setPreviewSize(h, w);
        mCamera.setDisplayOrientation(270);
    }

    if (display.getRotation() == Surface.ROTATION_270) {
        parameters.setPreviewSize(w, h);
        mCamera.setDisplayOrientation(180);
    }

    previewCamera();
}

public void previewCamera() {
    try {
        mCamera.setPreviewDisplay(mHolder);
        mCamera.startPreview();
    } catch (Exception e) {
        //Log.d(APP_CLASS, "Cannot start preview", e);
        e.printStackTrace();
    }
}
0 голосов
/ 17 марта 2014

Я сравнил свой код с учебным и, наконец, исправил, поместив следующий код в мой AndroidManifext.xml: В теге <activity>:

android:screenOrientation="landscape"
android:configChanges="keyboardHidden|orientation">
...