카메라 2 미리보기에서 YUV_420_888 이미지를 비트 맵으로 변환하려고합니다. 그러나 출력 이미지의 색상이 올바르지 않습니다.YUV_420_888을 Android 카메라 2의 비트 맵으로 변환하는 잘못된 이미지
다음은 비트 맵을 생성하기 위해 실행중인 테스트 코드입니다. 테스트 코드 일 뿐이므로 비트 맵을 재활용하거나 RenderScript를 계속 작성하는 것과 같은 관련 요소에 대한 코드 검토를하지 마십시오. 이 코드는 YUV에서 RGB 로의 변환을 테스트하는 것입니다.
다른 요인은, 코드가있는 경우 필요한 경우에만 이전 안드로이드 버전으로 인해 적절한 부족으로 오래된 수동 변환을 사용하지 않고, 따라서 충분해야 RenderScript 특정 ScriptIntrinsicYuvToRGB를 사용하여 위의 API (22)에서 실행하기위한 것입니다 YUV_420_888 지원.
RenderScript는 모든 유형의 YUV 변환을 처리하기위한 전용 ScriptIntrinsicYuvToRGB를 이미 제공하고 있기 때문에 Image 객체에서 YUV 바이트 데이터를 가져 오는 방법에 문제가있을 수 있지만 문제가 어디에 있는지 파악할 수는 없다고 생각합니다. 입니다.
Android Studio에서 출력 비트 맵을 보려면 bitmap.recycle()에 중단 점을 배치하면 재활용되기 전에 "비트 맵보기"옵션을 사용하여 변수 디버그 창에서 볼 수 있습니다.
사람이 변환에 문제가 있는지 발견 할 수 있는지 알려 주시기 바랍니다 :
@Override
public void onImageAvailable(ImageReader reader)
{
RenderScript rs = RenderScript.create(this.mContext);
final Image image = reader.acquireLatestImage();
final Image.Plane[] planes = image.getPlanes();
final ByteBuffer planeY = planes[0].getBuffer();
final ByteBuffer planeU = planes[1].getBuffer();
final ByteBuffer planeV = planes[2].getBuffer();
// Get the YUV planes data
final int Yb = planeY.rewind().remaining();
final int Ub = planeU.rewind().remaining();
final int Vb = planeV.rewind().remaining();
final ByteBuffer yuvData = ByteBuffer.allocateDirect(Yb + Ub + Vb);
planeY.get(yuvData.array(), 0, Yb);
planeU.get(yuvData.array(), Yb, Vb);
planeV.get(yuvData.array(), Yb + Vb, Ub);
// Initialize Renderscript
Type.Builder yuvType = new Type.Builder(rs, Element.YUV(rs))
.setX(image.getWidth())
.setY(image.getHeight())
.setYuvFormat(ImageFormat.YUV_420_888);
final Type.Builder rgbaType = new Type.Builder(rs, Element.RGBA_8888(rs))
.setX(image.getWidth())
.setY(image.getHeight());
Allocation yuvAllocation = Allocation.createTyped(rs, yuvType.create(), Allocation.USAGE_SCRIPT);
Allocation rgbAllocation = Allocation.createTyped(rs, rgbaType.create(), Allocation.USAGE_SCRIPT);
// Convert
yuvAllocation.copyFromUnchecked(yuvData.array());
ScriptIntrinsicYuvToRGB scriptYuvToRgb = ScriptIntrinsicYuvToRGB.create(rs, Element.YUV(rs));
scriptYuvToRgb.setInput(yuvAllocation);
scriptYuvToRgb.forEach(rgbAllocation);
// Get the bitmap
Bitmap bitmap = Bitmap.createBitmap(image.getWidth(), image.getHeight(), Bitmap.Config.ARGB_8888);
rgbAllocation.copyTo(bitmap);
// Release
bitmap.recycle();
yuvAllocation.destroy();
rgbAllocation.destroy();
rs.destroy();
image.close();
}
일반적으로 U 및 V 평면은 겹칩니다. YUV_420_888은 NV21 이미지를 호스팅 할 수있는 래퍼입니다 (예 : NV21 이미지). 이 경우 planeU 및 planeV 버퍼의 길이는 실제 크기의 두 배가됩니다. Renderscript를 사용하여 YUV_420_888을 Bitmap으로 변환하는 코드는 [here] (https://stackoverflow.com/questions/36212904/yuv-420-888-interpretation-on-samsung-galaxy-s7-camera2)에서 찾을 수 있습니다. –
안녕하세요. 힌트를 가져 주셔서 감사합니다. 새로운 YUV 변환 스크립트를 만드는 것을 암시하는 대안을 사용하는 대신 기존 ScriptIntrinsicYuvToRGB를 사용해야한다는 질문을보다 명확하게 지정하도록 업데이트했습니다. 감사합니다. – PerracoLabs
** ScriptIntrinsicYuvToRGB **를 사용하기 위해 귀하의 선호도를 존중하지만, 맞춤형 렌더 스크립트를 사용하는 것이 덜 효율적이지는 않습니다. –