1

我正在尝试从运行相机视图的表面视图中获取图片,

我已经实现了 onPreviewFrame,它被正确调用,因为调试显示我。

我现在面临的问题,因为我在方法中收到的 byte[] 数据是 YUV 空间颜色(NV21),我正在尝试将其转换为灰度以生成位图,然后将其存储到文件中.

我正在遵循的转换过程是:

 public Bitmap convertYuvGrayScaleRGB(byte[] yuv, int width, int height) {

    int[] pixels = new int[width * height];

    for (int i = 0; i < height*width; i++) {
        int grey = yuv[i] & 0xff;
        pixels[i] = 0xFF000000 | (grey * 0x00010101);
    }

    return Bitmap.createBitmap(pixels, width, height, Bitmap.Config.ARGB_8888);

  }

将其存储到文件的导入过程是:

Bitmap bitmap = convertYuvGrayScaleRGB(data,widht,heigth);

    ByteArrayOutputStream bytes = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.PNG, 50, bytes);

        File f = new File(Environment.getExternalStorageDirectory()
                                    + File.separator + "test.jpg");

    Log.d("Camera", "File: " + f.getAbsolutePath());
    try {
        f.createNewFile();
        FileOutputStream fo = new FileOutputStream(f);
        fo.write(bytes.toByteArray());
        fo.close();
        bitmap.recycle();
        bitmap = null;
         } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();

尽管如此,我得到的结果如下:

结果

4

4 回答 4

0

我做的:

int frameSize = width * height;
for (int i = 0; i < height; i++) {
    for (int j = 0; j < width; j++) {
        ret[frameSize + (i >> 1) * width + (j & ~1) + 1] = 127; //U
        ret[frameSize + (i >> 1) * width + (j & ~1) + 0] = 127; //V
    }
}

如此简单,但它真的很好而且很快;)

于 2013-12-16T11:17:36.267 回答
0

我在您的代码中找不到任何明显的错误,但我之前已经遇到过这种倾斜的图像。当这发生在我身上时,这是由于:

  • 在代码中的某个点,图像的宽度和高度被交换,
  • 或者您尝试转换的原始图像具有填充,在这种情况下,您将需要stride添加宽度和高度。

希望这可以帮助!

于 2013-05-24T15:44:03.450 回答
0

您正在转换的图像的宽度可能不均匀。在这种情况下,它会被填充到内存中。

让我看看文档...

它似乎比这更复杂。如果你想让你的代码像现在这样工作,你必须让宽度为 16 的倍数。

来自文档:

公共静态最终 int YV12

在 API 级别 9 Android YUV 格式中添加。

这种格式暴露给软件解码器和应用程序。

YV12 是 4:2:0 YCrCb 平面格式,由 WxH Y 平面后跟 (W/2) x (H/2) Cr 和 Cb 平面组成。

这种格式假设

偶数宽度 偶数高度 水平步幅 16 像素的倍数 垂直步幅等于高度 y_size = stride * height c_stride = ALIGN(stride/2, 16) c_size = c_stride * height/2 size = y_size + c_size * 2 cr_offset = y_size cb_offset = y_size + c_size

于 2013-05-26T18:13:35.320 回答
0

我刚刚在S3上遇到了这个问题。我的问题是我为预览使用了错误的尺寸。我假设相机是 16:9,而实际上是 4:3。

使用 Camera.getParameters().getPreviewSize() 查看输出的内容。

于 2013-06-02T05:01:19.873 回答