2016-08-01 42 views
1

我想實現從一個Android設備到另一個視頻流。爲了做到這一點,我想從相機獲取幀,通過套接字發送並在另一部手機上顯示ImageView。問題是我必須使用特定格式的ImageReader - YUV_420_888。當我嘗試根據此圖像中的字節創建位圖時,我只能得到ALPHA_8(其他格式會導致Exceptions說緩衝區對於像素來說不夠大),這是黑白+錯誤定向的。我想知道是否有一種方法可以直接獲取正確的版本或以某種方式轉換它,以便我可以在ImageView上顯示適當的位圖。下面是一些代碼:如何正確接收來自onImageAvailable的相機圖像?

public class MainActivity extends AppCompatActivity 
{ 
    private ImageReader mImageReader; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     this.imageView = (ImageView) findViewById(R.id.image); 

     this.handler = new Handler(){ 
      @Override 
      public void handleMessage(Message msg) 
      { 
       if(msg.what == Worker.PROCESSED_IMAGE) 
       { 
        imageView.setImageBitmap((Bitmap) msg.obj); 
       } 
      } 
     }; 
    } 

    private void openCamera() 
    { 
     CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE); 

     try 
     { 
      String cameraId = manager.getCameraIdList()[0]; 
      CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId); 
      StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP); 
      mPreviewSize = map.getOutputSizes(SurfaceTexture.class)[0]; 
      mImageReader = ImageReader.newInstance(mPreviewSize.getWidth(), mPreviewSize.getHeight(), ImageFormat.YUV_420_888, 50); 
      mImageReader.setOnImageAvailableListener(new Worker(this, this.handler, mPreviewSize.getWidth(), mPreviewSize.getHeight()), new Handler()); 

      manager.openCamera(cameraId, mStateCallback, null); 
     } 
     catch(CameraAccessException e) 
     { 
      e.printStackTrace(); 
     } 

    } 

} 


public class Worker implements ImageReader.OnImageAvailableListener 
{ 
    @Override 
    public void onImageAvailable(ImageReader imageReader) 
    { 
     Image image = imageReader.acquireLatestImage(); 

     Image.Plane plane = image.getPlanes()[0]; 
     ByteBuffer buffer = plane.getBuffer(); 
     Bitmap bm = Bitmap.createBitmap(width, heigth, Bitmap.Config.ALPHA_8); 
     bm.copyPixelsFromBuffer(buffer); 
     image.close(); 
     handler.obtainMessage(PROCESSED_IMAGE, bm).sendToTarget(); 

} 

回答

2

幾乎是正確的,嘗試改爲使用此代碼:

@Override 
public void onImageAvailable(ImageReader reader) { 
    Image image = null; 
    try { 
     image = reader.acquireLatestImage(); 
//  Log.d(TAG, String.format(Locale.getDefault(), "image w = %d; h = %d", image.getWidth(), image.getHeight())); 
     Image.Plane[] planes = image.getPlanes(); 
     ByteBuffer buffer = planes[0].getBuffer(); 
     buffer.rewind(); 
     byte[] data = new byte[buffer.capacity()]; 
     buffer.get(data); 
     Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length); 
//use your bitmap 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    if (image != null) { 
     image.close(); 
    } 
} 
+0

位圖是不是與此代碼適當的大小。它不填滿屏幕。 – Donato

+0

@ Donato「它不填滿屏幕」 - 這與當前的問題/答案不符。也許你把錯誤的大小設置爲[ImageReader](https://developer.android.com/reference/android/media/ImageReader.html#newInstance(int,%20int,%20int,%20int)),或者這只是UI問題。 –

相關問題