2011-10-17 162 views
0

我在从SurfaceView中获取图像/绘图或位图时遇到了一些麻烦,该图像作为摄像头使用。从SurfaceView获取图像到ImageView?

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


    } 
+0

你能告诉我你是怎么做到的吗? – Erum 2015-02-05 09:46:21

回答

4

它比这复杂得多。 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已经显示的布局与您在问题中所做的一样。它已经显示它。

+0

太好了,谢谢!我已将“PreviewCallback”添加到我的活动和您的代码到其“public void onPreviewFrame(byte [] data,Camera camera){”...但我如何从活动初始化相机?简单地说“Camera camera = Camera.open(); camera.startPreview();”无法连接到相机服务。 :/ – Roger 2011-10-17 14:11:53

+0

你说你已经有相机实施工作。保持这一点。你需要这个。用你的预览对象添加'camera.setPreviewCallback'。 – DeeV 2011-10-17 14:15:28

+0

哦,我应该在哪里把它camera.setPreviewCallback? – Roger 2011-10-17 14:37:35