【问题标题】:Camera preview stretched when trying to set in SurfaceView尝试在 SurfaceView 中设置时拉伸相机预览
【发布时间】:2015-01-20 10:34:09
【问题描述】:

我正在尝试在 SurfaceView 中设置相机预览 当我在 Surface 中设置相机时,它看起来像拉伸预览。 我该如何解决?

`public class CamActivity extends Activity implements SurfaceHolder.Callback`
`{`
`Camera camera;`
`SurfaceView surface;`
`SurfaceHolder mholder;`
`Button capture;`
`Bitmap bitmap;`
`public  String  path = Environment.getDataDirectory().getAbsolutePath() + "/storage/emulated/0/Pictures/Cam";`
@Override
`protected void onCreate(Bundle savedInstanceState) `
`{`
 `   super.onCreate(savedInstanceState);`
  `  setContentView(R.layout.activity_cam);`
   ` surface=(SurfaceView)findViewById(R.id.camera_view);`
   ` if(mholder==null)`
    `   mholder=surface.getHolder();`
   ` mholder.addCallback(this);`
    `mholder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);`

    `capture=(Button)findViewById(R.id.camera_capture);`
    `File mFolder = new File(path);`
    `if (!mFolder.exists()) {`
     `   mFolder.mkdir();`
    `}`
    `capture.setOnClickListener(new OnClickListener() {`

    `   @SuppressWarnings("deprecation")`
    `   @Override`
    `   public void onClick(View v) {`
    `        camera.takePicture(null, null, new PictureCallback()` 
    `        {`

                @Override
    `           public void onPictureTaken(byte[] data, Camera camera)`
    `           {`

    `               Random generator = new Random();`
    `               int n = 10000;`
    `               n = generator.nextInt(n);`
    `               String fname = "Image-"+ n +".jpg";`
    `               File pictureFile = new File(Environment.getExternalStoragePublicDirectory(`
    `                         Environment.DIRECTORY_PICTURES)+"/", fname);`
    `                try {`
    `                       FileOutputStream fos = new FileOutputStream(pictureFile);`
    `                       bitmap.compress(Bitmap.CompressFormat.JPEG,90, fos);`
    `                       fos.flush();`
    `                       fos.close();`
    `                   } catch (FileNotFoundException e) {`
                            `Toast.makeText(getApplicationContext(),e.getMessage(),Toast.LENGTH_LONG).show();`
    `                   } catch (IOException e) {`
                            `Toast.makeText(getApplicationContext(),e.getMessage(),Toast.LENGTH_LONG).show();`
    `                   }`

    `           }`
    `       });`
    `   }`
    `});`
`}`

@Override
`public void surfaceCreated(SurfaceHolder holder) `
`{`
`    camera=Camera.open();`
`    try` 
`    {`
`        camera.setPreviewDisplay(holder);`
`        Toast.makeText(getApplicationContext(), path, Toast.LENGTH_LONG).show();`
`    } `
`    catch (IOException exception)` 
`    {`
`         camera.release();`
`         camera = null;`
`    }`
`}`

@Override
`public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) `
`{`
 `   camera.startPreview();`
  `  camera.setDisplayOrientation(90);`
`}`

@Override
`public void surfaceDestroyed(SurfaceHolder holder)` 
`{
`   camera.stopPreview();`
`    camera.release();`
`    camera = null;`        
`}`
`}`

【问题讨论】:

  • 你能把你的代码放上去吗?
  • 您的 Surfaceview 尺寸与视频尺寸不同。要么与宽度成比例地减小高度,要么使用相机按钮使宽度全屏显示,作为其顶部的叠加层。
  • 如何设置相同的尺寸? @Shobhit 普里
  • 检查我的代码#Moradiya Aksh
  • 查看 Grafika 获取一些示例 (github.com/google/grafika)。它展示了使用自定义布局 (AspectFrameLayout) 来设置 SurfaceView 的大小,并使用视图矩阵而不是布局通过 TextureView 完成相同的事情。

标签: android android-layout android-camera surfaceview screen-resolution


【解决方案1】:

您需要监听 Activity 中的方向变化,并为相机设置正确的方向。

将此方法添加到您的相机活动中:

public void setCameraDisplayOrientation(Activity activity) {

    if(null == mCamera){
        return;
     }

       android.hardware.Camera.CameraInfo info = 
           new android.hardware.Camera.CameraInfo();

       android.hardware.Camera.getCameraInfo(cameraId, info);

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

       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;
       }


       if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
           orientation = (info.orientation + degrees) % 360;
           orientation = (360 - orientation) % 360;  // compensate the mirror
       } else {  // back-facing
           orientation = (info.orientation - degrees + 360) % 360;
       }

       if(null != mCamera){
           mCamera.setDisplayOrientation(orientation);
       }
    }

同时添加 OrientationEventListner

    mOrientationEventListener = new OrientationEventListener(mApplication, 
            SensorManager.SENSOR_DELAY_NORMAL) {

        @Override
        public void onOrientationChanged(int orientation) {

            if ((orientation == ORIENTATION_UNKNOWN) || (mCamera == null)) {
                return;
            }

            Camera.Parameters params                = mCamera.getParameters();               
            android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();

            android.hardware.Camera.getCameraInfo(cameraId, info);

            orientation = (orientation + 45) / 90 * 90;

            int rotation = 0;

            if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {
                rotation = (info.orientation - orientation + 360) % 360;
            }
            else {  
                /*
                 * back-facing camera
                 */
                rotation = (info.orientation + orientation) % 360;
            }

            params.setRotation(rotation);

            if(null == mCamera) {
                return;
            }

            mCamera.setParameters(params);
        }

    };

活动开始后启用方向监听器 /* * 启动方向监听器 */
if(mOrientationEventListener.canDetectOrientation()){
mOrientationEventListener.enable(); }

在活动的 onConfigurationChanged 和 onResume 回调中,进行如下调用

setCameraDisplayOrientation(Activity 活动)

希望对你有帮助

问候, 虾肉

编辑更新: 请查看此相机示例代码,您的大部分疑问应该得到解决 https://github.com/shrishmv/CameraTest

【讨论】:

  • 如何获取 cameraId ?
  • 请给我答案
  • 查看github项目
  • 从 github 下载并运行示例应用程序。它不应该给出任何错误。将其用作参考并相应地修改您的代码。你能告诉我你到底想做什么吗?
  • 检查这些东西(使用我的示例应用程序作为参考) 1)设置正确的预览大小和图片大小。 IE。首先查询支持的大小并设置适当的大小2)设置相机preivew的布局参数(高度和宽度),即surfaceview等于预览占用集或相同纵横比的大小3)正确设置方向,每当屏幕旋转时或surfaceview 更改 4)如果您的surfaceview 超出屏幕/活动范围,则将父级的布局参数设置为所需的大小,然后设置surfaceview 布局参数。所有这些都在我的示例应用程序中完成。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-16
  • 2021-06-24
  • 1970-01-01
  • 2019-03-02
  • 1970-01-01
相关资源
最近更新 更多