3131import android .media .Image ;
3232import android .media .ImageReader ;
3333import android .support .annotation .NonNull ;
34+ import android .support .annotation .Nullable ;
3435import android .util .Log ;
3536import android .util .SparseIntArray ;
3637import android .view .Surface ;
@@ -156,19 +157,26 @@ public void onReady() {
156157
157158 @ Override
158159 public void onImageAvailable (ImageReader reader ) {
159- try (Image image = reader .acquireNextImage ()) {
160- Image .Plane [] planes = image .getPlanes ();
161- if (planes .length > 0 ) {
162- ByteBuffer buffer = planes [0 ].getBuffer ();
163- byte [] data = new byte [buffer .remaining ()];
164- buffer .get (data );
165- mCallback .onPictureTaken (data );
166- }
160+ byte [] data = getByteDataFromImageReader (reader );
161+ if (data != null ) {
162+ mCallback .onPictureTaken (data );
167163 }
168164 }
169-
170165 };
171166
167+ private final ImageReader .OnImageAvailableListener mOnPreviewImageAvailableListener
168+ = new ImageReader .OnImageAvailableListener () {
169+
170+ @ Override
171+ public void onImageAvailable (ImageReader reader ) {
172+ byte [] data = getByteDataFromImageReader (reader );
173+ if (data != null ) {
174+ mCallback .onPreviewFrame (data , reader .getImageFormat (),
175+ reader .getWidth (),
176+ reader .getHeight ());
177+ }
178+ }
179+ };
172180
173181 private String mCameraId ;
174182
@@ -182,6 +190,8 @@ public void onImageAvailable(ImageReader reader) {
182190
183191 private ImageReader mImageReader ;
184192
193+ private ImageReader mCallbackImageDataReader ;
194+
185195 private final SizeMap mPreviewSizes = new SizeMap ();
186196
187197 private final SizeMap mPictureSizes = new SizeMap ();
@@ -232,6 +242,11 @@ void stop() {
232242 mImageReader .close ();
233243 mImageReader = null ;
234244 }
245+
246+ if (mCallbackImageDataReader != null ) {
247+ mCallbackImageDataReader .close ();
248+ mCallbackImageDataReader = null ;
249+ }
235250 }
236251
237252 @ Override
@@ -435,11 +450,49 @@ protected void collectPictureSizes(SizeMap sizes, StreamConfigurationMap map) {
435450
436451 private void prepareImageReader () {
437452 Size largest = mPictureSizes .sizes (mAspectRatio ).last ();
438- mImageReader = ImageReader .newInstance (largest .getWidth (), largest .getHeight (),
453+ initImageReader (largest .getWidth (), largest .getHeight ());
454+
455+ Size size = chooseOptimalSize ();
456+ initCallbackImageDataReader (size .getWidth (), size .getHeight ());
457+ }
458+
459+ private void initImageReader (int width , int height ){
460+ mImageReader = ImageReader .newInstance (width , height ,
439461 ImageFormat .JPEG , /* maxImages */ 2 );
440462 mImageReader .setOnImageAvailableListener (mOnImageAvailableListener , null );
441463 }
442464
465+ private void initCallbackImageDataReader (int width , int height ) {
466+
467+ if (mCallbackImageDataReader != null ) {
468+ mCallbackImageDataReader .close ();
469+ }
470+
471+ mCallbackImageDataReader = ImageReader .newInstance (width , height ,
472+ ImageFormat .NV21 , /* maxImages */ 1 );
473+ mCallbackImageDataReader .setOnImageAvailableListener (mOnPreviewImageAvailableListener , null );
474+ }
475+
476+ /**
477+ * Extract the byte data from the ImageReader
478+ * @param reader
479+ * @return byte array or null if failed
480+ */
481+ @ Nullable
482+ private byte [] getByteDataFromImageReader (@ NonNull ImageReader reader ) {
483+ byte [] data = null ;
484+ try (Image image = reader .acquireNextImage ()) {
485+ Image .Plane [] planes = image .getPlanes ();
486+ if (planes .length > 0 ) {
487+ ByteBuffer buffer = planes [0 ].getBuffer ();
488+ data = new byte [buffer .remaining ()];
489+ buffer .get (data );
490+ }
491+ }
492+ return data ;
493+ }
494+
495+
443496 /**
444497 * <p>Starts opening a camera device.</p>
445498 * <p>The result will be processed in {@link #mCameraDeviceCallback}.</p>
@@ -463,11 +516,14 @@ void startCaptureSession() {
463516 }
464517 Size previewSize = chooseOptimalSize ();
465518 mPreview .setBufferSize (previewSize .getWidth (), previewSize .getHeight ());
519+
466520 Surface surface = mPreview .getSurface ();
467521 try {
468522 mPreviewRequestBuilder = mCamera .createCaptureRequest (CameraDevice .TEMPLATE_PREVIEW );
469523 mPreviewRequestBuilder .addTarget (surface );
470- mCamera .createCaptureSession (Arrays .asList (surface , mImageReader .getSurface ()),
524+ mPreviewRequestBuilder .addTarget (mCallbackImageDataReader .getSurface ());
525+ mCamera .createCaptureSession (Arrays .asList (surface , mImageReader .getSurface (),
526+ mCallbackImageDataReader .getSurface ()),
471527 mSessionCallback , null );
472528 } catch (CameraAccessException e ) {
473529 throw new RuntimeException ("Failed to start camera session" );
0 commit comments