下面列出了怎么用android.media.ImageReader的API类实例代码及写法,或者点击链接到github查看源代码。
@Override
public void onImageAvailable(ImageReader reader) {
synchronized (mLock) {
if (borrowedImage == null) {
Image i = reader.acquireNextImage();
borrowedImage = i;
if (bDebug) {
Log.d(TAG, "==== OnImageReady ====");
Log.d(TAG, "Size:" + i.getWidth() + "x" + i.getHeight());
Log.d(TAG, "Format:" + i.getFormat());
Log.d(TAG, "#Planes:" + i.getPlanes().length);
Log.d(TAG, "Y-Plane Pixel Stride:" + i.getPlanes()[0].getPixelStride());
Log.d(TAG, "Y-Planes Row Stride" + i.getPlanes()[0].getRowStride());
Log.d(TAG, "Y(i[0]) Start Address:" + NativeRender.getPointerFromByteBuffer(i.getPlanes()[0].getBuffer(), 0));
Log.d(TAG, "U(i[0]) Start Address:" + NativeRender.getPointerFromByteBuffer(i.getPlanes()[1].getBuffer(), 0));
Log.d(TAG, "V(i[0]) Start Address:" + NativeRender.getPointerFromByteBuffer(i.getPlanes()[2].getBuffer(), 0));
Log.d(TAG, "======================");
}
if (mCallback != null) mCallback.onFrameReady();
}
}
}
/**
*
*/
void initImageRead(MediaProjection mediaProjection) {
if (mediaProjection == null) {
LogHelper.e(TAG, "mediaProjection == null");
return;
}
int width = UIUtils.getWidthPixels();
int height = UIUtils.getRealHeightPixels();
int dpi = UIUtils.getDensityDpi();
mImageReader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, 2);
/**
* 获取getSurface
*/
mediaProjection.createVirtualDisplay("ScreenCapture",
width, height, dpi,
DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
mImageReader.getSurface(), null, null);
}
@Override
public void onImageAvailable(ImageReader reader) {
Image image = reader.acquireLatestImage();
if (image == null) {
Log.d(TAG, "onImageAvailable: image is null");
return;
}
final Image.Plane[] planes = image.getPlanes();
final Buffer buffer = planes[0].getBuffer().rewind();
int pixelStride = planes[0].getPixelStride();
int rowStride = planes[0].getRowStride();
int rowPadding = rowStride - pixelStride * width;
Bitmap bitmap = Bitmap.createBitmap(width + rowPadding / pixelStride, height, Bitmap.Config.ARGB_8888);
bitmap.copyPixelsFromBuffer(buffer);
tearDown();
image.close();
cb.onScreenshot(bitmap);
}
/**
* 静止画の撮影を行います.
*
* @param listener 静止画の撮影結果を通知するリスナー
*/
private void takePhotoInternal(final @NonNull OnPhotoEventListener listener) {
try {
ImageReader stillImageReader = mCameraWrapper.createStillImageReader(ImageFormat.JPEG);
stillImageReader.setOnImageAvailableListener((reader) -> {
Image photo = reader.acquireNextImage();
if (photo == null) {
listener.onFailedTakePhoto("Failed to acquire image.");
return;
}
storePhoto(photo, listener);
photo.close();
}, mPhotoHandler);
mCameraWrapper.takeStillImage(stillImageReader.getSurface());
} catch (CameraWrapperException e) {
if (DEBUG) {
Log.e(TAG, "Failed to take photo.", e);
}
listener.onFailedTakePhoto("Failed to take photo.");
}
}
/**
* カメラデバイスのプレビューを開始します.
* <p>
* {@link #setTextureView(AutoFitTextureView)} もしくは、{@link #setTextureView(AutoFitTextureView)}
* のどちらに設定してから呼び出してください。
* </p>
*
* @return プレビューの開始に成功した場合はtrue、それ以外はfalse
*/
public boolean startPreview(final ImageReader.OnImageAvailableListener previewListener) {
if (mState == null) {
mPreviewListener = previewListener;
((OpenCameraState) mOpenCameraState).mOpenCallback = () -> nextState(mCreateSessionState);
if (mTextureView != null) {
nextState(mInitSurfaceState);
return true;
} else if (mSurfaceTexture != null) {
nextState(mOpenCameraState);
return true;
}
} else if (mState == mOpenCameraState) {
mPreviewListener = previewListener;
nextState(mCreateSessionState);
return true;
}
return false;
}
@Override
public void onImageAvailable(final ImageReader reader) {
Image image = reader.acquireLatestImage();
if (image == null) {
return;
}
if (!shouldSample.get()) {
image.close();
return;
}
if (!isComputing.compareAndSet(false, true)) {
image.close();
return;
}
visionImage = FritzVisionImage.fromMediaImage(image, orientation);
image.close();
runInBackground(() -> {
objectResult = predictor.predict(visionImage);
requestRender();
});
}
/**
* Starts an ImageReader as a do-nothing Surface. The virtual display will not get fully
* initialized within surface flinger unless it has a valid Surface associated with it. We use
* the ImageReader as the default valid Surface.
*/
private void startImageReader() {
if (mImageReader == null) {
mImageReader = ImageReader.newInstance(mVirtualDisplayWidth, mVirtualDisplayHeight,
PixelFormat.RGBA_8888, 2 /* maxImages */);
Log.i(TAG, "VD startImageReader: res = " + mVirtualDisplayWidth + "X" +
mVirtualDisplayHeight + ", dpi = " + mVirtualDisplayDpi);
}
synchronized (mVdLock) {
setSurfaceLocked(mImageReader.getSurface());
}
}
/**
* Create a ImageMetadataSynchronizer for the List of ImageReaders. 'imageReaders' should not
* contain any duplicates. Each reader's OnImageAvailableListener is set to an internal
* ImageReader.OnImageAvailableListener of the synchronizer and it is an error to change it
* externally. We take ownership of each ImageReader and will close them when this
* ImageMetadataSynchronizer is closed.
*
* <p>imageHandler can be set to an arbitrary non-null Handler and is shared across all
* ImageReader instances.
*
* <p>Callback.onDataAvailable() is called with Image's in the same order as imageReaders.
*/
@SuppressWarnings("JdkObsolete")
public ImageMetadataSynchronizer(List<ImageReader> imageReaders, Handler imageHandler) {
closed = false;
createCaptureCallback();
this.imageReaders.addAll(imageReaders);
// Create a queue and a listener per ImageReader.
int nReaders = imageReaders.size();
for (int i = 0; i < nReaders; ++i) {
final int readerIndex = i;
ImageReader reader = imageReaders.get(readerIndex);
pendingImageQueues.add(new LinkedList<>());
imagesAcquired.add(0);
ImageReader.OnImageAvailableListener listener =
reader1 -> {
synchronized (ImageMetadataSynchronizer.this) {
if (closed) {
return;
}
int nImagesAcquired = imagesAcquired.get(readerIndex);
if (nImagesAcquired < reader1.getMaxImages()) {
Image image = reader1.acquireNextImage();
imagesAcquired.set(readerIndex, nImagesAcquired + 1);
handleImageLocked(readerIndex, image);
}
}
};
reader.setOnImageAvailableListener(listener, imageHandler);
}
}
public List<Surface> getOutputSurfaces() {
List<Surface> surfaces = new ArrayList<>();
for (ImageReader reader : imageReaders) {
surfaces.add(reader.getSurface());
}
return surfaces;
}
@Override
public void onImageAvailable(ImageReader reader) {
try (Image image = reader.acquireNextImage()) {
Image.Plane[] planes = image.getPlanes();
if (planes.length > 0) {
ByteBuffer buffer = planes[0].getBuffer();
byte[] data = new byte[buffer.remaining()];
buffer.get(data);
mCallback.onPictureTaken(data);
}
}
}
private void prepareImageReader() {
if (mImageReader != null) {
mImageReader.close();
}
Size largest = mPictureSizes.sizes(mAspectRatio).last();
mImageReader = ImageReader.newInstance(largest.getWidth(), largest.getHeight(),
ImageFormat.JPEG, /* maxImages */ 2);
mImageReader.setOnImageAvailableListener(mOnImageAvailableListener, null);
}
@Override
public void onImageAvailable(ImageReader reader) {
Image image = reader.acquireLatestImage();
// get image bytes
ByteBuffer imageBuf = image.getPlanes()[0].getBuffer();
final byte[] imageBytes = new byte[imageBuf.remaining()];
imageBuf.get(imageBytes);
image.close();
onPictureTaken(imageBytes);
}
@Override
public void onImageAvailable(ImageReader reader) {
Image mImage = reader.acquireNextImage();
if (mImage == null) {
return;
}
mFrameProcessor.setNextFrame(convertYUV420888ToNV21(mImage));
mImage.close();
}
public boolean startRecord() {
if (mediaProjection == null || running) {
return false;
}
executorService = Executors.newFixedThreadPool(threadCount);
imageReader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, 2);
createVirtualDisplayForImageReader();
running = true;
if (recordServiceListener != null) {
recordServiceListener.onRecorderStatusChanged(running);
}
return true;
}
/**
* 写真撮影を行います.
*
* @param l 撮影した写真を通知するリスナー
*/
public void takePicture(ImageReader.OnImageAvailableListener l) {
if (mCamera2 == null) {
if (DEBUG) {
Log.w(TAG, "Camera2 is null.");
}
return;
}
mCamera2.takePicture(l);
}
@Override
public void onImageAvailable(ImageReader reader) {
try (Image image = reader.acquireNextImage()) {
Image.Plane[] planes = image.getPlanes();
if (planes.length > 0) {
ByteBuffer buffer = planes[0].getBuffer();
byte[] data = new byte[buffer.remaining()];
buffer.get(data);
mCallback.onPictureTaken(data);
}
}
}
private void prepareImageReader() {
if (mImageReader != null) {
mImageReader.close();
}
Size largest = mPictureSizes.sizes(mAspectRatio).last();
mImageReader = ImageReader.newInstance(largest.getWidth(), largest.getHeight(),
ImageFormat.JPEG, /* maxImages */ 2);
mImageReader.setOnImageAvailableListener(mOnImageAvailableListener, null);
}
/**
* Takes the screenshot of whatever currently is on the default display.
* @param resultCode The result code returned by the request for accessing MediaProjection permission
* @param data The intent returned by the same request
*/
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public Screenshotter takeScreenshot(Context context, int resultCode, Intent data, final ScreenshotCallback cb) {
this.context = context;
this.cb = cb;
this.resultCode = resultCode;
this.data = data;
WindowManager windowManager = (WindowManager) MyApplication.getApplication().getSystemService(Context.WINDOW_SERVICE);
width = windowManager.getDefaultDisplay().getWidth();
height = windowManager.getDefaultDisplay().getHeight();
DisplayMetrics metrics = new DisplayMetrics();
windowManager.getDefaultDisplay().getMetrics(metrics);
mScreenDensity = metrics.densityDpi;
mImageReader = ImageReader.newInstance(width, height, 0x1,2);
MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) context
.getSystemService(Context.MEDIA_PROJECTION_SERVICE);
mMediaProjection = mediaProjectionManager.getMediaProjection(resultCode, data);
try {
virtualDisplay = mMediaProjection.createVirtualDisplay("Screenshotter",
width, height, mScreenDensity,
DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
mImageReader.getSurface(), null, null);
mImageReader.setOnImageAvailableListener(Screenshotter.this, null);
} catch (Exception e) {
e.printStackTrace();
}
return this;
}
/**
* カメラデバイスの写真撮影を行います.
* <p>
* 写真撮影を行う場合には、{@link #startPreview()} を行い状態を {@link #STATE_PREVIEW} にしておく必要があります。
* </p>
* <p>
* プレビューサイズ、写真サイズを切り替える場合には、プレビューを停止してから、プレビューを開始する必要があります。
* </p>
* @param listener 写真撮影した結果を通知するリスナー
* @return 撮影開始に成功したらtrue、それ以外はfalse
*/
public boolean takePicture(final ImageReader.OnImageAvailableListener listener) {
if (mState != mPreviewState) {
if (DEBUG) {
Log.w(TAG, "It is invalid state to take a picture. state=" + mState);
}
return false;
}
mTakePictureListener = listener;
nextState(mAutoFocusState);
return true;
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT_WATCH)
private void setImageReader() {
if (DEBUG) Log.d(TAG, "Setting image reader " + String.valueOf(isCapturing()));
mImageReader = ImageReader.newInstance(getGrabberWidth(), getGrabberHeight(),
PixelFormat.RGBA_8888, MAX_IMAGE_READER_IMAGES);
mImageReader.setOnImageAvailableListener(imageAvailableListener, mHandler);
mVirtualDisplay.setSurface(mImageReader.getSurface());
setCapturing(true);
}
@Override
public void onImageAvailable(ImageReader reader) {
try {
final Image image = reader.acquireLatestImage();
if (image != null) {
mCameraFrameCallback.onFrameData(image, image::close);
}
} catch (OutOfMemoryError | IllegalStateException e) {
CameraCompat.onError(CameraCompat.ERR_UNKNOWN);
}
}
@Override
public void onImageAvailable(ImageReader reader) {
Log.e(TAG, "onImageAvailable: " + count++);
Image img = null;
img = reader.acquireLatestImage();
Result rawResult = null;
try {
if (img == null) throw new NullPointerException("cannot be null");
ByteBuffer buffer = img.getPlanes()[0].getBuffer();
byte[] data = new byte[buffer.remaining()];
buffer.get(data);
int width = img.getWidth();
int height = img.getHeight();
PlanarYUVLuminanceSource source = new PlanarYUVLuminanceSource(data, width, height);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
rawResult = mQrReader.decode(bitmap);
onQRCodeRead(rawResult.getText());
} catch (ReaderException ignored) {
Log.e(TAG, "Reader shows an exception! ", ignored);
/* Ignored */
} catch (NullPointerException ex) {
ex.printStackTrace();
} finally {
mQrReader.reset();
Log.e(TAG, "in the finally! ------------");
if (img != null)
img.close();
}
if (rawResult != null) {
Log.e(TAG, "Decoding successful!");
} else {
Log.d(TAG, "No QR code found…");
}
}
@Override
public void onImageAvailable(final ImageReader reader) {
Image image = reader.acquireLatestImage();
if (image == null) {
return;
}
if (!computing.compareAndSet(false, true)) {
image.close();
return;
}
setupImageForPrediction(image);
image.close();
runInBackground(
new Runnable() {
@Override
public void run() {
runInference();
// Fire callback to change the OverlayView
requestRender();
computing.set(false);
}
});
}
public void setImageAvailableListener(ImageReader.OnImageAvailableListener onImageAvailableListener) {
if (mImageReader == null) {
Log.w(TAG, "setImageAvailableListener: mImageReader is null");
return;
}
mImageReader.setOnImageAvailableListener(onImageAvailableListener, null);
}
private static Bitmap renderHevcImageWithFormat(ByteBuffer bitstream, ImageInfo info, int imageFormat) throws FormatFallbackException {
try (ImageReader reader = ImageReader.newInstance(info.size.getWidth(), info.size.getHeight(), imageFormat, 1)) {
renderHevcImage(bitstream, info, reader.getSurface());
Image image = null;
try {
try {
image = reader.acquireNextImage();
} catch (UnsupportedOperationException ex) {
throw new FormatFallbackException(ex);
}
switch (image.getFormat()) {
case ImageFormat.YUV_420_888:
case ImageFormat.YV12:
return convertYuv420ToBitmap(image);
case ImageFormat.RGB_565:
return convertRgb565ToBitmap(image);
default:
throw new RuntimeException("unsupported image format(" + image.getFormat() + ")");
}
} finally {
if (image != null) {
image.close();
}
}
}
}
@Override
public void onImageAvailable(final ImageReader reader) {
Timber.d("Picture is available.");
new Thread(new Runnable() {
@Override
public void run() {
File root = ImageSaver.getRoot(CameraOperator.ROBOCAR_FOLDER);
new ImageSaver(reader.acquireLatestImage(), root, PHOTO_FILENAME).run();
processPhoto(root, PHOTO_FILENAME);
}
}).start();
}
/**
* Initialize the camera device
*/
@SuppressLint("MissingPermission")
public void initializeCamera(Context context, int previewWidth, int previewHeight,
Handler backgroundHandler,
ImageReader.OnImageAvailableListener imageAvailableListener) {
if (initialized) {
throw new IllegalStateException(
"CameraHandler is already initialized or is initializing");
}
initialized = true;
// Discover the camera instance
CameraManager manager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
String[] camIds = null;
try {
camIds = manager.getCameraIdList();
} catch (CameraAccessException e) {
Log.w(TAG, "Cannot get the list of available cameras", e);
}
if (camIds == null || camIds.length < 1) {
Log.d(TAG, "No cameras found");
return;
}
Log.d(TAG, "Using camera id " + camIds[0]);
// Initialize the image processor
mImageReader = ImageReader.newInstance(previewWidth, previewHeight, ImageFormat.JPEG,
MAX_IMAGES);
mImageReader.setOnImageAvailableListener(imageAvailableListener, backgroundHandler);
// Open the camera resource
try {
manager.openCamera(camIds[0], mStateCallback, backgroundHandler);
} catch (CameraAccessException cae) {
Log.d(TAG, "Camera access exception", cae);
}
}
/**
* Initialize the camera device
*/
@SuppressLint("MissingPermission")
public void initializeCamera(Context context, int previewWidth, int previewHeight,
Handler backgroundHandler,
ImageReader.OnImageAvailableListener imageAvailableListener) {
if (initialized) {
throw new IllegalStateException(
"CameraHandler is already initialized or is initializing");
}
initialized = true;
// Discover the camera instance
CameraManager manager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
String[] camIds = null;
try {
camIds = manager.getCameraIdList();
} catch (CameraAccessException e) {
Log.w(TAG, "Cannot get the list of available cameras", e);
}
if (camIds == null || camIds.length < 1) {
Log.d(TAG, "No cameras found");
return;
}
Log.d(TAG, "Using camera id " + camIds[0]);
// Initialize the image processor
mImageReader = ImageReader.newInstance(previewWidth, previewHeight, ImageFormat.JPEG,
MAX_IMAGES);
mImageReader.setOnImageAvailableListener(imageAvailableListener, backgroundHandler);
// Open the camera resource
try {
manager.openCamera(camIds[0], mStateCallback, backgroundHandler);
} catch (CameraAccessException cae) {
Log.d(TAG, "Camera access exception", cae);
}
}
/**
* Initialize the camera that will be used to capture images.
*/
private void initCamera() {
mImagePreprocessor = new ImagePreprocessor(PREVIEW_IMAGE_WIDTH, PREVIEW_IMAGE_HEIGHT,
TF_INPUT_IMAGE_WIDTH, TF_INPUT_IMAGE_HEIGHT);
mCameraHandler = CameraHandler.getInstance();
mCameraHandler.initializeCamera(this,
PREVIEW_IMAGE_WIDTH, PREVIEW_IMAGE_HEIGHT, null,
new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader imageReader) {
Bitmap bitmap = mImagePreprocessor.preprocessImage(imageReader.acquireNextImage());
onPhotoReady(bitmap);
}
});
}
ImageScreenCast(final Context context,
final MediaProjection mediaProjection,
final ImageReader imageReader,
int width, int height) {
super(context, mediaProjection, width, height);
mImageReader = imageReader;
}