RGBA 图像格式(由 Scintilla 使用)

Posted

技术标签:

【中文标题】RGBA 图像格式(由 Scintilla 使用)【英文标题】:RGBA Image format (as used by Scintilla) 【发布时间】:2013-03-12 16:10:39 【问题描述】:

我正在使用Scintilla(不是ScintillaNET),我正在尝试设置自动完成列表中使用的图像。 Scintilla 需要 RGBA 格式的字节/像素字符串。

Scintilla 对这种 RGBA 格式的描述: (Quote from documentation)

RGBA 格式允许半透明,每个都有一个 alpha 值 像素。它比 XPM 更简单,功能更强大。

数据是从像素开始的 4 字节像素值序列 对于顶行,最左边的像素首先,然后继续 后续行的像素。线条之间没有间隙 对齐原因。

每个像素依次由​​一个红色字节、一个绿色字节、一个蓝色字节组成 字节和一个 alpha 字节。颜色字节不预乘 阿尔法值。也就是说,一个 25% 不透明的全红色像素将是 [FF, 00, 00, 3F]

我想我误解了上面解释的格式,文档不是很清楚。

我的转换方法:

我写了这个函数来把一个PNG转换成这个字节串:

public static string ConvertFromPNG(Bitmap PNG)

    string rgba = "";

    int pixWidth = PNG.Width;
    int pixHeight = PNG.Height;

    for (var y = 0; y < pixHeight; y++)
    
        for (var x = 0; x < pixWidth; x++)
        
            Color pix = PNG.GetPixel(x, y);

            rgba += pix.R.ToString("X2") + pix.G.ToString("X2") + pix.B.ToString("X2") + pix.A.ToString("X2");
        
    

    return rgba;

生成的图像:

但 Scintilla 只是将图像显示为灰色框:

.

有问题的图像是Microsoft's Babel images:之一的副本。

我知道这组字节是正确的,因为有趣的是,如果我将它们排成行并缩小它们,我可以看到图像的轮廓:

生成的字节数:

00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009F000000EC0000001B00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000815B0000DF9B0000F8000000B40000002F000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001B0000007F4E0000FDC80000FFFF0000FF720000FF1D0000B50000003E00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001613000085350000FFDE0000FFFF0000FFFF0000FFFF0000FF750000FF230000C4000000240000000000000000000000000000000000000000000000000000000000000000000000000000000000000085400000EADB0000FFF90000FFFF0000FFFF0000FFFF0000FFF60000FFA70000F5000000DA00000000000000000000000000000000000000000000000000000000000000000000000000000091810000EACA0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFBB0000FF460000FF000000FF000000000000000000000000000000000000000000000000000000000000000000000000000000FF7E0000FFE80000FFFF0000FFFF0000FFFF0000FFFB0000FFB30000FF460000FF0C0000FF000000FF000000000000000000000000000000000000000000000000000000000000000000000000000000FF000000FF660000FFFF0000FFFF0000FFFF0000FFC70000FF0D0000FF590000FF7A0000FF000000FF000000000000000000000000000000000000000000000000000000000000000000000000000000FF8C0000FF7D0000FF2E0000FFFF0000FFBB0000FF1C0000FF510000FFB40000FF7B0000FF000000FF000000000000000000000000000000000000000000000000000000000000000000000000000000FFE20000FFE40000FF410000FF8B0000FF510000FF350000FFB60000FF8F0000FF3A0000EA00000091000000000000000000000000000000000000000000000000000000000000000000000000000000DA910000F5F30000FFFF0000FF0C0000FF270000FFC10000FF930000FF220000EA0000008500000000000000000000000000000000000000000000000000000000000000000000000000000000000000241D0000C4870000FFFF0000FF270000FF420000FF9E0000FF230000FF090000860000001600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003E2D0000B5610000FF120000FF1C0000FF370000FD0000007F0000001B000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002E000000B4000000F8000000DF00000081000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001B000000EC0000009F0000000000000000000000000000000000000000

【问题讨论】:

【参考方案1】:

您正在将字节格式化为十六进制值并将它们放在一个字符串中。 Scintilla 只想要字节本身。

我怀疑您想创建一个字节数组而不是字符串,并将pix.Rpix.Gpix.Bpix.A 的值直接存储到其中,而不是将它们格式化为字符串。

【讨论】:

谢谢,现在可以使用了。文档说该方法需要一串字节,这让我感到困惑:)【参考方案2】:

在接受 JasonD 的回答后,我更新了我的代码并且它正在工作。如果它对其他人有帮助,这里是工作代码:

public static byte[] ConvertFromPNG(Bitmap PNG)

    byte[] rgbaB = new byte[4 * (PNG.Width * PNG.Height)];

    int i = 0;

    for (var y = 0; y < PNG.Height; y++)
    
        for (var x = 0; x < PNG.Width; x++)
        
            Color pix = PNG.GetPixel(x, y);

            rgbaB[i++] = pix.R;
            rgbaB[i++] = pix.G;
            rgbaB[i++] = pix.B;
            rgbaB[i++] = pix.A;
        
    

    return rgbaB;

【讨论】:

以上是关于RGBA 图像格式(由 Scintilla 使用)的主要内容,如果未能解决你的问题,请参考以下文章

PS 制作RGBA四通道 TGA格式图片

Scintilla 控件中类似于 Visual Studio 的代码格式

如何获取PNG图片某点像素的rgba值

python将RGBA图像保存为BMP文件

python 图像处理

cocos2dx——像素格式