【问题标题】:Android camera preview in surfaceviewSurfaceview中的Android相机预览
【发布时间】:2012-08-04 10:35:55
【问题描述】:

我设法将相机预览放在表面视图中,效果很好。但是现在我对其他组件的速度有疑问。因为现在真的很慢。

我需要将相机放入新线程吗?如何降低fps或分辨率?因为这是我现在所拥有的不能正常工作。

我的表面观点:

class KameraSurface extends SurfaceView implements SurfaceHolder.Callback {
    private static final String TAG = "Preview";

    SurfaceHolder mHolder;
    public Camera camera;

    KameraSurface(Context context) {
        super(context);

        // Install a SurfaceHolder.Callback so we get notified when the
        // underlying surface is created and destroyed.
        mHolder = getHolder();
        mHolder.addCallback(this);
        mHolder.setFormat(PixelFormat.RGB_332);
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_GPU);
    }

    public void surfaceCreated(SurfaceHolder holder) {
        // The Surface has been created, acquire the camera and tell it where
        // to draw.

         camera = Camera.open();

         Camera.Parameters p = camera.getParameters();
         p.setPictureSize(80, 60);
         p.setColorEffect(android.hardware.Camera.Parameters.EFFECT_NONE);
         p.setJpegQuality(20);
         p.setPreviewFrameRate(1);
         p.setPreviewFpsRange(5, 10);
         p.setPreviewSize(80, 60);
         camera.setParameters(p);



        try {
            camera.setPreviewDisplay(holder);


            camera.setPreviewCallback(new PreviewCallback() {

                public void onPreviewFrame(byte[] data, Camera arg1) {
                    //KameraSurface.this.invalidate();
                }
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        // Surface will be destroyed when we return, so stop the preview.
        // Because the CameraDevice object is not a shared resource, it's very
        // important to release it when the activity is paused.
        camera.stopPreview();
        camera = null;
    }
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        // Now that the size is known, set up the camera parameters and begin
        // the preview.
        Camera.Parameters parameters = camera.getParameters();
        parameters.setPreviewSize(80, 60);
        camera.setParameters(parameters);

        camera.startPreview();
    }

    @Override
    public void draw(Canvas canvas) {
            super.draw(canvas);
            Paint p= new Paint(Color.RED);
            Log.d(TAG,"draw");
            canvas.drawText("PREVIEW", canvas.getWidth()/2, canvas.getHeight()/2, p );
    }
}

我的 xml:

.
.
.
 <TableRow
            android:layout_width="match_parent"
            android:layout_height="fill_parent" >

            <FrameLayout
                android:id="@+id/preview"
                android:layout_width="133dp"
                android:layout_height="100dp"
                android:layout_margin="20dp" >
            </FrameLayout>
.
.
.

以及我如何调用主要活动:

KameraSurface preview = new KameraSurface(getApplicationContext());
                ((FrameLayout) findViewById(R.id.preview)).addView(preview);

【问题讨论】:

标签: android camera surfaceview


【解决方案1】:

我尚未测试您的代码,但有许多因素可能会导致体验缓慢,包括硬件不佳。如果您在 Windows 中使用模拟器,请尝试将进程/应用程序的关联性设置为除 0 以外的任何 CPU 内核。它在单核模式下运行得更快。

我需要将相机放入新线程吗?

没有。正如您可以在此处阅读的https://stackoverflow.com/a/1243448/649979,它已经在独立于 GUI 线程的自己的线程中。

然而,我们通过 cmets 发现硬件加速有助于 &lt;application android:hardwareAccelerated="true" ...&gt; http://developer.android.com/guide/topics/graphics/hardware-accel.html

如何降低 fps 或分辨率?因为这就是我现在所拥有的 不能正常工作。

应该如何工作?您尚未对此进行概述。

【讨论】:

  • 在 goclever a103 平板电脑 (ICS) 上
  • 我觉得现在快了一点……另一半可能是因为便宜的平板电脑。
  • 尝试在 BlueStacks 上运行它,视频播放是唯一不能正常工作的东西,但它会链接到您的网络摄像头来进行摄像头工作。在那里试一下,看看是否更好。 bluestacks.com
【解决方案2】:

您可以选择在不同的线程中启动“startPreview”..

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
    // Now that the size is known, set up the camera parameters and begin
    // the preview.
    Camera.Parameters parameters = camera.getParameters();
    parameters.setPreviewSize(80, 60);
    camera.setParameters(parameters);

    Thread preview_thread = new Thread(new Runnable() {
        @Override
        public void run() {
               camera.startPreview();
           }
        }, "preview_thread");
        preview_thread.start(); 
    }

【讨论】:

  • 为什么您将帧速率设置为 1 .... 任何相机设备的标准帧速率至少为 15 fps ... 尝试相同的..
  • 但是没有必要有15fps。
【解决方案3】:

我遇到了同样的问题,但我通过这种方法获得了这个预览大小,现在我的相机预览工作正常。

private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) {
            final double ASPECT_TOLERANCE = 0.1;
            double targetRatio = (double) h / w;

            if (sizes == null)
                return null;

            Camera.Size optimalSize = null;
            double minDiff = Double.MAX_VALUE;

            int targetHeight = h;

            for (Camera.Size size : sizes) {
                double ratio = (double) size.height / size.width;
                if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)
                    continue;

                if (Math.abs(size.height - targetHeight) < minDiff) {
                    optimalSize = size;
                    minDiff = Math.abs(size.height - targetHeight);
                }
            }

            if (optimalSize == null) {
                minDiff = Double.MAX_VALUE;
                for (Camera.Size size : sizes) {
                    if (Math.abs(size.height - targetHeight) < minDiff) {
                        optimalSize = size;
                        minDiff = Math.abs(size.height - targetHeight);
                    }
                }
            }

            return optimalSize;
        }

    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-16
    相关资源
    最近更新 更多