问题描述
问题有点奇怪。 (我看到黑色的预览纹理)我带有自己的解决方案,不显示预览,而是将预览缓冲区刷新到Byte [](但是将显示预览,但是显示在opengl纹理上(本机)) 无论如何,使camera2 api正常工作后,我实际上从ImageReader获取图像时遇到问题。
首先,我想澄清一下:为了不显示任何预览(未处理),我仅将ImageReaders表面传递给CaptureRequestBuilder。
List<Surface> surfaces =new ArrayList<>();
Surface frameCaptureSurface = mImageReader.getSurface();
surfaces.add(frameCaptureSurface);
mCaptureRequestbuilder.addTarget(frameCaptureSurface);
OnImageAvailable()触发,但是数据似乎已损坏,如果我将其保存到文件中,irfanview会告诉我标头已损坏等。不知何故,字节已填充,但在此肯定有问题。
这是我目前正在做的代码
Activity shared_activity;
boolean initialized;
CameraDevice mCameraDevice;
Size mSize;
byte[] mFrame;
ImageReader mImageReader;
HandlerThread mCamSessionThread;
Handler mCamSessionHandler;
CaptureRequest.Builder mCaptureRequestbuilder;
CaptureRequest mCaptureRequest;
CameraCaptureSession mCameraCaptureSession;
public PCPHOnesHAREView(Context context,Activity sa,ClipboardManager clp)
{
super(context);
shared_activity = sa;
clipBoard = clp;
initialized = false;
init(false,0);
setKeepScreenOn(true);
}
boolean invoke_cam_upload = false;
final ImageReader.OnImageAvailableListener mOnImageAvailableListener = new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader imageReader) {
LOGE("New frame avil");
if (update_cam_tex) return;
if (invoke_cam_upload) return;
invoke_cam_upload = true;
LOGE("copy new frame to global buffer");
Image image = imageReader.acquireNextimage();
//Now i cant remember exactly where it throws an error (first below or second one)
//E/ion: ioctl c0044901 Failed with code -1: Invalid argument
Image.Plane[] planes = image.getPlanes();
ByteBuffer buffer = planes[0].getBuffer();
buffer.rewind();
mFrame = new byte[buffer.capacity()];
buffer.get(mFrame);
image.close();
update_cam_tex = true;
invoke_cam_upload = false;
}
};
final public CameraCaptureSession.StateCallback mCaptureStateCallback = new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured( CameraCaptureSession cameraCaptureSession) {
try {
mCaptureRequest= mCaptureRequestbuilder.build();
mCameraCaptureSession = cameraCaptureSession;
mCameraCaptureSession.setRepeatingRequest(mCaptureRequest,null,mCamSessionHandler);
CameraOpenedAndPreviewAvil(mSize.getWidth(),mSize.getHeight());
if (mCameraDevice == null) LOGE("CAM NULL");
LOGE("CAP SESSION IS CONfigURED");
} catch (Throwable t) {
LOGE("CAM SESSION ERROR");
}
}
@Override
public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) {
LOGE("CONfig Failed");
}
};
final public CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {
@Override
public void onopened( CameraDevice cameraDevice) {
mCameraDevice = cameraDevice;
createCameraPreviewSession();
LOGE("CREATE PREV SESSION");
}
@Override
public void ondisconnected( CameraDevice cameraDevice) {
mCameraDevice = null;
LOGE("CAM disC");
}
@Override
public void onError( CameraDevice cameraDevice,int i) {
mCameraDevice = null;
LOGE("CAM ERROR");
}
};
private void createCameraPreviewSession() {
try {
LOGE("CONfigURING BUILDER");
mCaptureRequestbuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
mCaptureRequestbuilder.set(CaptureRequest.CONTROL_AF_MODE,CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
List<Surface> surfaces =new ArrayList<>();
Surface frameCaptureSurface = mImageReader.getSurface();
surfaces.add(frameCaptureSurface);
mCaptureRequestbuilder.addTarget(frameCaptureSurface);
mCameraDevice.createCaptureSession(surfaces,mCaptureStateCallback,mCamSessionHandler);
} catch (Throwable t) {
LOGE("CREATE PREV SESSION ERROR "+t.getMessage());
}
}
public void openCameraT() {
//cam_tex.addCallback(this);
CameraManager cameraManager = (CameraManager) shared_activity.getSystemService(Context.CAMERA_SERVICE);
try {
String cameraId = cameraManager.getCameraIdList()[0];
Cameracharacteristics characteristics
= cameraManager.getCameracharacteristics(cameraId);
StreamConfigurationMap map = characteristics.get(
Cameracharacteristics.SCALER_STREAM_CONfigURATION_MAP);
mSize = map.getoutputSizes(SurfaceTexture.class)[map.getoutputSizes(SurfaceTexture.class).length-2];
mCamSessionThread = new HandlerThread("Camera2");
mCamSessionThread.start();
mCamSessionHandler = new Handler(mCamSessionThread.getLooper());
mImageReader = ImageReader.newInstance(mSize.getWidth(),mSize.getHeight(),ImageFormat.YUV_420_888,1);
mImageReader.setonImageAvailableListener(mOnImageAvailableListener,mCamSessionHandler);
LOGE("opening CAMERA");
cameraManager.openCamera(cameraId,mStateCallback,mCamSessionHandler);
} catch (Throwable t) {
LOGE(t.getMessage());
}
}
private void closeCamera() {
try {
if (null != mCameraDevice)
mCameraDevice.close();
} catch (Throwable t) {
}
}
----
On gl thread
public void onDrawFrame(GL10 gl) {
if (!initialized)
{
init(scrw,scrh);
initialized = true;
} else
{
if (update_cam_tex)
{
LOGE("update_cam_tex");
throwing_cam_buff = true;
SetCamTex(mFrame); //native call to pass imageReader byte buffer as bytes[] convert it to rgb and save as texture
update_cam_tex = false;
throwing_cam_buff = false;
}
step();
}
}
这是logcat的输出:
AGAIN INITIALIZE
SW 2255 SH: 1080
QR CODE
Scan
opening CAMERA
CONfigURING BUILDER
CREATE PREV SESSION
CAM C++ DATA READY: w: 208 h: 144
CAP SESSION IS CONfigURED
New frame avil
copy new frame to global buffer
E/ion: ioctl c0044901 Failed with code -1: Invalid argument
update_cam_tex
SETTING CAM TEX,len = 6
PDATA !
New frame avil
copy new frame to global buffer
update_cam_tex
SETTING CAM TEX
PDATA !
New frame avil
copy new frame to global buffer
update_cam_tex
SETTING CAM TEX
PDATA !
New frame avil
copy new frame to global buffer
update_cam_tex
SETTING CAM TEX
PDATA #
SETTING CAM TEX
PDATA#//这显示了mFrame [400]中的字符
无论如何,尝试访问ImageReader缓冲区时出现奇怪的错误 E / ion:ioctl c0044901失败,代码为-1:参数无效
我知道我应该使用两个纹理上载mFrame的功能,但是现在我需要正确处理ImageReader图像转换为未签名的字符*
欢呼
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)