inputImage.getByteBuffer() 在将 AndroidX Camera 与 MLKit 一起使用时为 null
inputImage.getByteBuffer() is null when using AndroidX Camera with MLKit
这是我的代码 Activity class:
@Override protected void onCreate(Bundle savedInstanceState)
{
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
_cpf = ProcessCameraProvider.getInstance(this);
_cpf.addListener(new Runnable() {
@Override
public void run() {
try {
ProcessCameraProvider cameraProvider = _cpf.get();
bindImageAnalysis(cameraProvider);
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
}
}
}, ContextCompat.getMainExecutor(this));
}
private void bindImageAnalysis(@NonNull ProcessCameraProvider cameraProvider) {
ImageAnalysis imageAnalysis =
new ImageAnalysis.Builder().setTargetResolution(new Size(640, 360))
.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST).build();
imageAnalysis.setAnalyzer(ContextCompat.getMainExecutor(this), new ImageAnalysis.Analyzer() {
@Override
public void analyze(@NonNull ImageProxy ip) {
processImage(ip.getImage(), ip.getImageInfo().getRotationDegrees());
ip.close();
}
});
CameraSelector cameraSelector = new CameraSelector.Builder().requireLensFacing(CameraSelector.LENS_FACING_BACK).build();
cameraProvider.bindToLifecycle((LifecycleOwner)this, cameraSelector, imageAnalysis);
}
在每个 analyze
回调中,MLKit 指示
InputImage.fromMediaImage(ip.getImage(),ip.getImageInfo().getRotationDegrees()).getByteBuffer()
为空。我应该如何解释这个?这是否总是意味着图像为空?
inputImage.getByteBuffer() 是一种内部方法,并非为 public 用途而设计。只有在使用字节缓冲区或字节数组构造图像时,此方法才会 return 。如果您需要使用 android 媒体图像中的字节缓冲区,则需要自行进行转换。
此外,我们对 Firebase ML Kit 进行了一些更改,以更好地区分设备上的 API 和基于云的 API。 “ML Kit"(without firebase branding) contains all the on-device APIs. Here's 从 firebase mlkit 到 mlkit 的迁移指南。所有进一步的改进和新的 API 将仅与新的 ML Kit 一起发布。
问题在于我过早 .close()
ng。 PoseDetector
处理是异步的,因此在 ip.close()
之后立即调用 processImage
。当调用 ip.close()
时,processImage 仍在工作,所以这就是 Attempt to invoke virtual method 'java.nio.ByteBuffer android.media.Image$Plane.getBuffer()
背后的原因。不要在 analyze
方法中使用 .close()
,而是应该在 OnSuccessListener
或 OnSuccessListener
.
结束时调用它
这是完整的example。
这是我的代码 Activity class:
@Override protected void onCreate(Bundle savedInstanceState)
{
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
_cpf = ProcessCameraProvider.getInstance(this);
_cpf.addListener(new Runnable() {
@Override
public void run() {
try {
ProcessCameraProvider cameraProvider = _cpf.get();
bindImageAnalysis(cameraProvider);
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
}
}
}, ContextCompat.getMainExecutor(this));
}
private void bindImageAnalysis(@NonNull ProcessCameraProvider cameraProvider) {
ImageAnalysis imageAnalysis =
new ImageAnalysis.Builder().setTargetResolution(new Size(640, 360))
.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST).build();
imageAnalysis.setAnalyzer(ContextCompat.getMainExecutor(this), new ImageAnalysis.Analyzer() {
@Override
public void analyze(@NonNull ImageProxy ip) {
processImage(ip.getImage(), ip.getImageInfo().getRotationDegrees());
ip.close();
}
});
CameraSelector cameraSelector = new CameraSelector.Builder().requireLensFacing(CameraSelector.LENS_FACING_BACK).build();
cameraProvider.bindToLifecycle((LifecycleOwner)this, cameraSelector, imageAnalysis);
}
在每个 analyze
回调中,MLKit 指示
InputImage.fromMediaImage(ip.getImage(),ip.getImageInfo().getRotationDegrees()).getByteBuffer()
为空。我应该如何解释这个?这是否总是意味着图像为空?
inputImage.getByteBuffer() 是一种内部方法,并非为 public 用途而设计。只有在使用字节缓冲区或字节数组构造图像时,此方法才会 return 。如果您需要使用 android 媒体图像中的字节缓冲区,则需要自行进行转换。
此外,我们对 Firebase ML Kit 进行了一些更改,以更好地区分设备上的 API 和基于云的 API。 “ML Kit"(without firebase branding) contains all the on-device APIs. Here's 从 firebase mlkit 到 mlkit 的迁移指南。所有进一步的改进和新的 API 将仅与新的 ML Kit 一起发布。
问题在于我过早 .close()
ng。 PoseDetector
处理是异步的,因此在 ip.close()
之后立即调用 processImage
。当调用 ip.close()
时,processImage 仍在工作,所以这就是 Attempt to invoke virtual method 'java.nio.ByteBuffer android.media.Image$Plane.getBuffer()
背后的原因。不要在 analyze
方法中使用 .close()
,而是应该在 OnSuccessListener
或 OnSuccessListener
.
这是完整的example。