我发布了这个问题,因为我在以下帖子中找不到解决问题的答案:
Converting preview frame to bitmap
Android decodeYUV420SP results in green images?
Displaying YUV Image in Android
我从
获取了我的数据和cameraResolution(在选择BestPreviewSize之后) public void onPreviewFrame(byte[] data, Camera camera) {
Point cameraResolution = configManager.getCameraResolution();
Handler thePreviewHandler = previewHandler;
if (cameraResolution != null && thePreviewHandler != null) {
Message message = thePreviewHandler.obtainMessage(previewMessage, cameraResolution.x,
cameraResolution.y, data);
message.sendToTarget();
previewHandler = null;
} else {
Log.d(TAG, "Got preview callback, but no handler or resolution available");
}
}
稍后从转换为RGB,我使用:
int[] pixels=new int[yuvData.length];
// int size = dataWidth*dataHeight;
// int[] pixels=new int[size]; replacing yuvData.length by size is not working too
pixels=decodeYUV420SP(pixels,yuvData, dataWidth, dataHeight);
Bitmap bitmap = Bitmap.createBitmap(dataWidth, dataHeight, Bitmap.Config.RGB_565);
bitmap.setPixels(pixels, 0, dataWidth, 0, 0, dataWidth, dataHeight);
我尝试了两种方法,一种使用RenderScript,另一种使用decodeYUV420SP:
public Bitmap convertYUV420_NV21toRGB8888_RenderScript(byte [] data,int W, int H, CaptureActivityOCR fragment) {
// https://stackoverflow.com/questions/20358803/how-to-use-scriptintrinsicyuvtorgb-converting-byte-yuv-to-byte-rgba
RenderScript rs;
ScriptIntrinsicYuvToRGB yuvToRgbIntrinsic;
rs = RenderScript.create(fragment.getActivity());
yuvToRgbIntrinsic = ScriptIntrinsicYuvToRGB.create(rs, Element.U8_4(rs)); //Create an intrinsic for converting YUV to RGB.
Type.Builder yuvType = new Type.Builder(rs, Element.U8(rs)).setX(data.length);
Allocation in = Allocation.createTyped(rs, yuvType.create(), Allocation.USAGE_SCRIPT); //an Allocation will be populated with empty data when it is first created
Type.Builder rgbaType = new Type.Builder(rs, Element.RGBA_8888(rs)).setX(W).setY(H);
Allocation out = Allocation.createTyped(rs, rgbaType.create(), Allocation.USAGE_SCRIPT); //an Allocation will be populated with empty data when it is first created
in.copyFrom(data);//Populate Allocations with data.
yuvToRgbIntrinsic.setInput(in); //Set the input yuv allocation, must be U8(RenderScript).
yuvToRgbIntrinsic.forEach(out); //Launch the appropriate kernels,Convert the image to RGB.
Bitmap bmpout = Bitmap.createBitmap(W, H, Bitmap.Config.ARGB_8888);
out.copyTo(bmpout); //Copy data out of Allocation objects.
return bmpout;
}
或
int[] decodeYUV420SP(int[] rgb, byte[] yuv420sp, int width, int height) {
Log.e("camera", " decodeYUV420SP ");
// TODO Auto-generated method stub
final int frameSize = width * height;
for (int j = 0, yp = 0; j < height; j++) {
int uvp = frameSize + (j >> 1) * width, u = 0, v = 0;
for (int i = 0; i < width; i++, yp++) {
int y = (0xff & ((int) yuv420sp[yp])) - 16;
if (y < 0) y = 0;
if ((i & 1) == 0) {
v = (0xff & yuv420sp[uvp++]) - 128;
u = (0xff & yuv420sp[uvp++]) - 128;
}
int y1192 = 1192 * y;
int r = (y1192 + 1634 * v);
int g = (y1192 - 833 * v - 400 * u);
int b = (y1192 + 2066 * u);
if (r < 0) r = 0; else if (r > 262143) r = 262143;
if (g < 0) g = 0; else if (g > 262143) g = 262143;
if (b < 0) b = 0; else if (b > 262143) b = 262143;
rgb[yp] = 0xff000000 | ((r << 6) & 0xff0000) | ((g >> 2) & 0xff00) | ((b >> 10) & 0xff);
}
}
return rgb;
}
但我仍然不知道为什么我会得到一些好的形象但是绿色。 (我有另外类似的黑白方法,它正在工作) 除了上面的链接,我尝试了所有与此主题相关的帖子,所以如果有人可以帮助另一个提示,请?我可能会对要申请的尺寸感到困惑吗?
在OnPreviewFrame方法之后和转换为RGB方法之前的某个地方,我使用另一个方法和下面的指令,因为我需要旋转接收到的数据。我想知道这不是问题的根源:
byte[] rotatedData = new byte[data.length];
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++)
rotatedData[x * height + height - y - 1] = data[x + y * width];
}
int tmp = width;
width = height;
height = tmp;
请帮帮我?
答案 0 :(得分:2)
我认为你的轮换例程是错误的。 它适用于Luma(Y),因此您可以获得黑白图像的良好效果,但不能获得色度。如果宽度和高度是图片的尺寸,则根本不会旋转色度值。 因此,您需要为色度添加第二个循环并移动字节对(V和U)。
如果您在没有此旋转的情况下尝试了它并且仍然有绿色图片,则问题可能也在您的decodeYUV420SP功能中。
yuv to rgba转换没有一个通用公式。它必须与对方相匹配 在这里http://www.codeproject.com/Articles/402391/RGB-to-YUV-conversion-with-different-chroma-sampli和http://www.fourcc.org/fccyvrgb.php
这个适用于我
B = 1.164(Y - 16) + 2.018(U - 128)
G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128)
R = 1.164(Y - 16) + 1.596(V - 128)
它似乎与您只使用浮动版本相同,所以您可以尝试其他。
答案 1 :(得分:0)
我建议在RenderScript旋转后旋转位图:
If ( -Not ( Test-Path "Registry::HKEY_CLASSES_ROOT\Directory\shell\NASBackup\command")){New-Item -Path "Registry::HKEY_CLASSES_ROOT\Directory\shell\NASBackup\command" -ItemType RegistryKey -Force}
Set-ItemProperty -path "Registry::HKEY_CLASSES_ROOT\Directory\shell\NASBackup\command" -Name "(Default)" -Type "String" -Value "cmd /c start /b /wait powershell.exe -nologo -WindowStyle Hidden -file C:\Windows\System32\Backup.ps1"
#