2011-10-17 63 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