【问题标题】:Getting image from SurfaceView to ImageView?从 SurfaceView 获取图像到 ImageView?
【发布时间】:2011-10-17 23:00:19
【问题描述】:

我在从用作相机预览的 SurfaceView 获取图像/可绘制对象或位图时遇到了一些麻烦。

    final CameraSurfaceView cameraSurfaceView = new CameraSurfaceView(this);
    LinearLayout ll = (LinearLayout)findViewById(R.id.linearLayout1);
    ll.addView(cameraSurfaceView); // THIS WORKS

    ImageView ivCam = (ImageView) findViewById(R.id.ivCam);
    ivCam.setImageBitmap(cameraSurfaceView.getDrawingCache()); // THIS DOESN'T :(

有什么建议吗?谢谢!

编辑:

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        final CameraSurfaceView cameraSurfaceView = new CameraSurfaceView(this);
        LinearLayout ll = (LinearLayout)findViewById(R.id.LLS);
        ll.addView(cameraSurfaceView); // THIS WORKS


    }

///////////////////////////////////////////////////////////////////////////////////////////////   

    public class CameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback
    {
            private SurfaceHolder holder;
            private Camera camera;

            public CameraSurfaceView(Context context) 
            {
                    super(context);

                    //Initiate the Surface Holder properly
                    this.holder = this.getHolder();
                    this.holder.addCallback(this);
                    this.holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
            }

            @Override
            public void surfaceCreated(SurfaceHolder holder) 
            {
                    try
                    {
                            this.camera = Camera.open();
                            this.camera.setPreviewDisplay(this.holder);

                            this.camera.setPreviewCallback(new PreviewCallback() {

                              public void onPreviewFrame(byte[] _data, Camera _camera) {

                                Camera.Parameters params = _camera.getParameters();
                                   int w = params.getPreviewSize().width;
                                   int h = params.getPreviewSize().height;
                                   int format = params.getPreviewFormat();
                                   YuvImage image = new YuvImage(_data, format, w, h, null);

                                   ByteArrayOutputStream out = new ByteArrayOutputStream();
                                   Rect area = new Rect(0, 0, w, h);
                                   image.compressToJpeg(area, 50, out);
                                   Bitmap bm = BitmapFactory.decodeByteArray(out.toByteArray(), 0, out.size());

                                   ImageView ivCam = (ImageView) findViewById(R.id.imageView1);
                                   ivCam.setImageBitmap(bm);  /// NULL POINT EX HERE!
                              }
                            });

                    }
                    catch(IOException ioe)
                    {
                            ioe.printStackTrace(System.out);
                    }
            }


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

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


            public Camera getCamera()
            {
                    return this.camera;
            }


    }

【问题讨论】:

  • 你能告诉我你是怎么做的吗?

标签: android


【解决方案1】:

比这复杂得多。 SurfaceView 的背景不是相机预览。你必须有一个实现Camera.PreviewCalback 的类。一旦你有了它,你就可以获得一个包含预览发送的图像的字节数组。在某些手机上,您可以将预览设置为 JPEG,在这种情况下,您可以直接使用 BitmapFactory 对其进行解码。在其他不支持该功能的手机上,默认情况下您将获得一张 YUV 4:2:0 图像,您必须将其转换为 JPEG 图像。

在 Android 2.2+ 上,您可以像这样将 YUV 图像转换为 JPEG:

   int w = params.getPreviewSize().width;
   int h = params.getPreviewSize().height;
   int format = params.getPreviewFormat();
   YuvImage image = new YuvImage(data, format, w, h, null);

   ByteArrayOutputStream out = new ByteArrayOutputStream();
   Rect area = new Rect(0, 0, w, h);
   image.compressToJpeg(area, 50, out);
   Bitmap bm = BitmapFactory.decodeByteArray(out.toByteArray(), 0, out.size());
   ivCam.setImageBitmap(bm);

如果您针对的是旧模型,则必须使用此处的转换算法。

http://blog.tomgibara.com/post/132956174/yuv420-to-rgb565-conversion-in-android

一个 SO 来源:

Getting frames from Video Image in Android

编辑: 如果您只想显示相机视图,那么您只需将相机正在使用的SurfaceView 添加到已经显示的布局中,就像您在问题中所做的那样。它已经显示出来了。

【讨论】:

  • 太好了,谢谢!我已将“实现 PreviewCallback”添加到我的活动中,并将您的代码添加到其“public void onPreviewFrame(byte[] data, Camera camera) {”...但是如何从活动中初始化摄像头?只需“相机相机 = Camera.open(); camera.startPreview();”给出无法连接到相机服务。 ://
  • 你说你的相机实现已经在工作了。保持这一点。你需要那个。在您的预览对象中添加camera.setPreviewCallback
  • 哦,我应该把它放在哪里 camera.setPreviewCallback ?
  • 您可以在有权访问相机对象的任何时间调用它。我通常将它放在我的自定义 SurfaceView 类中的一个名为 public void savePreviewCallback(Camera.PreviewCallback callback) 的方法下,它允许我传入我想要的任何回调处理程序。它还将相机对象保留在视图中以进行代码隔离。
  • 谢谢,请参阅上面的编辑,它给出了位图的空点异常。
猜你喜欢
  • 2013-02-11
  • 2012-02-21
  • 1970-01-01
  • 2013-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多