changqing132 2024-02-17 21:03 采纳率: 0%
浏览 4
已结题

glsurfaceview的yuv数据转bitmap画面黑白

拿到一个yuv格式的数据

public Bitmap rawByteArray2RGBABitmap2(byte[] data, int width, int height) {
        int frameSize = width * height;

        int[] rgba = new int[frameSize];
        for (int i = 0; i < height; i++)
            for (int j = 0; j < width; j++) {
                int y = (0xff & ((int) data[i * width + j]));
                int u = (0xff & ((int) data[frameSize + (i >> 1) * width + (j & ~1) + 0]));
                int v = (0xff & ((int) data[frameSize + (i >> 1) * width + (j & ~1) + 1]));
                y = y < 16 ? 16 : y;
                y = y > 235 ? 235: y;
                int r = Math.round(1.164f * (y - 16) + 1.596f * (v - 128));
                int g = Math.round(1.164f * (y - 16) - 0.813f * (v - 128) - 0.391f * (u - 128));
                int b = Math.round(1.164f * (y - 16) + 2.018f * (u - 128));
                r = r < 0 ? 0 : (r > 255 ? 255 : r);
                g = g < 0 ? 0 : (g > 255 ? 255 : g);
                b = b < 0 ? 0 : (b > 255 ? 255 : b);
                rgba[i * width + j] = 0xff000000 + (b << 16) + (g << 8) + r;
            }
        Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        bmp.setPixels(rgba, 0 , width, 0, 0, width, height);
        return bmp;
    }


用这个去转换成bitmap,结果是

img

基本还是黑白,然后上面会有一些色斑

  • 写回答

25条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-02-17 21:05
    关注
    获得0.45元问题酬金

    引自免费微信小程序:皆我百晓生

    根据您提供的代码,这段Java函数确实将YUV数据转换为了RGB格式,并进一步封装为一个Bitmap对象。然而,您提到输出的图像整体是黑白且带有色斑,这可能由以下几个原因导致:

    1. 色彩空间转换错误:在将YUV转换为RGB的过程中,计算公式可能存在误差或者不符合您的原始YUV数据的实际色彩空间标准(例如YUV420SP、YUV420P等)。在上述代码中,使用的转换公式适用于NV21格式(YUV420SP),如果您输入的数据不是这种格式,可能会导致色彩失真。

    2. 黑白效果:尽管代码中实现了从YUV到RGB的转换,但并没有实现将彩色图像转为黑白的功能。若需要黑白效果,可以简单地将R、G、B三个分量设为相同值来模拟灰度图像:

      int gray = (r + g + b) / 3;
      rgba[i * width + j] = 0xff000000 | (gray << 16) | (gray << 8) | gray;
      
    3. 色斑问题:色斑可能是由于内存访问越界或者其他与YUV数据读取和像素赋值相关的错误导致的。请确保data数组中的Y、U、V分量的索引计算正确,尤其是在处理奇偶行时对于U、V采样的调整。

    4. 数据源问题:如果原始YUV数据本身就有问题,比如压缩损失严重、噪声较大或编码异常,那么转换后的图像也会出现不正常的现象。

    要解决这个问题,请首先确认您的YUV数据格式是否符合当前转换函数所假设的标准,并根据实际需求添加或修改代码以生成黑白图像。以下是将彩色转为黑白并修正可能的越界问题的示例代码:

    public Bitmap rawByteArray2GrayscaleBitmap(byte[] data, int width, int height) {
        int frameSize = width * height;
    
        // 检查数据是否为NV21格式
        if ((frameSize * 3 / 2) != data.length) {
            throw new IllegalArgumentException("Data length does not match NV21 format for the given dimensions.");
        }
    
        int[] gray = new int[frameSize];
        for (int i = 0; i < height; i++) {
            for (int j = 0; j < width; j++) {
                int yIndex = i * width + j;
                int y = (0xff & ((int) data[yIndex]));
    
                // 对于非第一行,处理UV分量的偏移量
                if (i % 2 == 1 && j % 2 == 1) {
                    continue; // Skip the UV values which are not needed for grayscale conversion
                }
    
                // Calculate grayscale value from Y only
                gray[yIndex] = 0xff000000 | (y << 16) | (y << 8) | y;
            }
            // 跳过奇数行UV部分(如果是NV21)
            if (i % 2 != 0) {
                yIndex += width / 2;
            }
        }
    
        Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        bmp.setPixels(gray, 0 , width, 0, 0, width, height);
        return bmp;
    }
    

    请注意,此代码仅针对NV21格式进行了优化,如需支持其他YUV格式,请相应地调整UV分量的提取逻辑。同时,为了生成黑白图像,已直接使用Y分量代表灰度值。

    评论 编辑记录

报告相同问题?

问题事件

  • 系统已结题 2月25日
  • 赞助了问题酬金15元 2月17日
  • 创建了问题 2月17日

悬赏问题

  • ¥15 编辑cmake lists 明明写了project项目名,但是还是报错怎么回事
  • ¥15 关于#计算机视觉#的问题:求一份高质量桥梁多病害数据集
  • ¥15 特定网页无法访问,已排除网页问题
  • ¥50 如何将脑的图像投影到颅骨上
  • ¥15 提问一个关于vscode相关的环境配置问题,就是输入中文但是显示不出来,代码在idea可以显示中文,但在vscode不行,不知道怎么配置环境
  • ¥15 netcore使用PuppeteerSharp截图
  • ¥20 这张图页头,页脚具体代码该怎么写?
  • ¥15 关于#sql#的问题,请各位专家解答!
  • ¥20 WPF MVVM模式 handycontrol 框架, hc:SearchBar 控件 Text="{Binding NavMenusKeyWords}" 绑定取不到值
  • ¥15 需要手写数字信号处理Dsp三个简单题 不用太复杂