J'utilise l'API Camera2 d'Android et j'aimerais effectuer un traitement d'image sur les cadres de prévisualisation de la caméra, puis afficher les changements sur l'aperçu (TextureView). À partir de l'exemple courant de camera2video, j'ai installé un ImageReader dans mon openCamera().Android Video Processing - comment connecter la Surface ImageReader à l'aperçu?
mImageReader = ImageReader.newInstance(mVideoSize.getWidth(),
mVideoSize.getHeight(), ImageFormat.YUV_420_888, mMaxBufferedImages);
mImageReader.setOnImageAvailableListener(mImageAvailable, mBackgroundHandler);
Dans mon startPreview(), je les ai installé surfaces pour recevoir des trames du CaptureRequest.
SurfaceTexture texture = mTextureView.getSurfaceTexture();
assert texture != null;
texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
List<Surface> surfaces = new ArrayList<>();
// Here is where we connect the mPreviewSurface to the mTextureView.
mPreviewSurface = new Surface(texture);
surfaces.add(mPreviewSurface);
mPreviewBuilder.addTarget(mPreviewSurface);
// Connect our Image Reader to the Camera to get the preview frames.
Surface readerSurface = mImageReader.getSurface();
surfaces.add(readerSurface);
mPreviewBuilder.addTarget(readerSurface);
Ensuite, je vais modifier les données d'image dans le rappel OnImageAvailableListener(). 2 instances de surface
ImageReader.OnImageAvailableListener mImageAvailable = new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader) {
try {
Image image = reader.acquireLatestImage();
if (image == null)
return;
final Image.Plane[] planes = image.getPlanes();
// Do something to the pixels.
// Black out part of the image.
ByteBuffer y_data_buffer = planes[0].getBuffer();
byte[] y_data = new byte[y_data_buffer.remaining()];
y_data_buffer.get(y_data);
byte y_value;
for (int row = 0; row < image.getHeight()/2; row++) {
for (int col = 0; col < image.getWidth()/2; col++) {
y_value = y_data[row * image.getWidth() + col];
y_value = 0;
y_data[row * image.getWidth() + col] = y_value;
}
}
image.close();
} catch (IllegalStateException e) {
Log.d(TAG, "mImageAvailable() Too many images acquired");
}
}
};
Comme je le comprends maintenant j'envoie des images, une pour mTextureView et l'autre pour mon ImageReader.
Comment faire pour que mTextureView utilise la même Surface que le ImageReader, ou devrais-je manipuler les données d'image directement depuis la Surface de mTextureView?
Merci
Donc, si j'utilise l'itinéraire ANEDWindow NDK, la raison de YUV-> RGB est parce que TextureView nécessite le format RVB? – jimbo
Eh bien, il est plus que le NDK expose actuellement que les formats d'image RVB pour sélectionner: https://developer.android.com/ndk/reference/hardware__buffer_8h.html#a06fc87d81c62e9abb8790b6e5713c55ba521c192d1f9b5e85aa68b86ead204fbe –