2016-08-01 3 views
1

한 Android 장치에서 다른 장치로 비디오 스트리밍을 구현하려고합니다. 이 작업을 수행하려면 카메라에서 프레임을 가져 와서 소켓을 통해 보내고 다른 휴대 전화의 ImageView에 표시하고 싶습니다. 문제는 특정 형식 (YUV_420_888)으로 ImageReader를 사용해야한다는 것입니다. 이 이미지의 바이트를 기반으로 비트 맵을 만들려고 할 때 흑백 및 잘못된 방향이 ALPHA_8 (다른 형식의 경우 버퍼가 픽셀만큼 크지 않다는 예외를 발생시킬 수 있음) 만 얻을 수 있습니다. 올바른 버전을 직접 얻는 방법이 있는지 또는 어떻게 변환하여 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 문제 일 수 있습니다. . –

관련 문제