Gdiplus 64位颜色

3

我正在创建一个64位的位图,并使用Graphics对象进行包装以在其上绘制。 问题是Gdiplus Color类仅为32位(每个分量仅为字节,即最大255),因此如何使用gdiplus在64位图像上绘制? 例如。

Bitmap bmp(100, 100, PixelFormat64bppARGB);

Graphics g(&bmp);
//how do I draw a red line now, if i use Color(255,0,0) it comes as almost dark black red

如果我理解正确,64bpp意味着每个组件的宽度为16位。然而,Color类仅支持每个组件8位。一种方法是提取像素并自行设置,如果可能的话。我从未在GDI上工作过,所以无法提供更多帮助 :( - dirkgently
是的,那似乎是唯一的选择,即绘制图像并通过缩放到16位复制图像缓冲区,但这正是我想避免的。 - Anurag Uniyal
不要使用Color类,直接修改缓冲区。 - Ed S.
除非有我不知道的更简单的方法。 - Ed S.
1
如果我需要修改缓冲区,为什么要使用gdiplus?例如,如何在缓冲区中绘制Arial字体大小为12? - Anurag Uniyal
3个回答

2

看起来Gdiplus不支持任何64位操作。一个比较简单的方法是将图像分成两个32位图像并分别进行操作,这样仍然可以使用Gdiplus方法。

您可以将ARGB通道拆分为AARR和GGBB,或者使用具有较低和较高ARGB位的两个32位图像。

这两种变体都需要编写包装函数或将每个调用分成两个部分,如下所示:

// This is what you want to do (ARGB, 16 bit per channel)
// g.DrawLine(new Pen(Color(0, 65535, 1024, 31), 1, 0, 0, 100, 100);

// AARR GGBB variant
gAARR.DrawLine(new Pen(Color(0,0,255,255), 1, 0, 0, 100, 100);
gGGBB.DrawLine(new Pen(Color(4,0,0,31), 1, 0, 0, 100, 100);

// ARGBhigh ARGBlow variant
gHigh.DrawLine(new Pen(Color(0,255,4,0), 1, 0, 0, 100, 100);
gLow.DrawLine(new Pen(Color(0,255,0,31), 1, 0, 0, 100, 100);

请注意,这里我使用了Color(A,R,G,B)的顺序,但我不确定是否正确。根据MSDN文档,应该改为Color(R,G,B,A)。如果您不需要alpha通道,则应优先选择highlow变体,因为您仍然可以使用Color(R,G,B)。

要显示或保存结果,您需要合并这两个缓冲区。


我认为这不会起作用,因为你会搞砸抗锯齿和透明效果。即使你进行“智能”合并(这仍然是一个未定义的概念……),它仍然会对抗锯齿做出错误的选择。 - Jason Cohen
没错,可能会有一些副作用,但我认为这些可以处理(例如关闭抗锯齿)。这仍然似乎是创建64位图像而不需要大量努力的最佳方法之一。 - schnaader
但在这种情况下,我将只绘制到一个32位透明图像上,并将每个像素缩放到64位后再进行复制,这样会更容易。 - Anurag Uniyal

1

根据MSDN - Image Pixel Format Constants,您不能这样做:

备注

PixelFormat48bppRGBPixelFormat64bppARGBPixelFormat64bppPARGB使用每个颜色分量(通道)16位。Microsoft Windows GDI+版本1.0可以读取16位每通道的图像,但是这些图像会被转换为8位每通道的格式进行处理、显示和保存。


0
您可以使用此位图构造函数来设置像素格式:
public:
Bitmap(
    int width, 
    int height, 
    PixelFormat format
)

编辑:您将无法使用Color类(我认为)因为它仅支持32位颜色。但是,您可以在Bitmap上调用LockBits并手动循环遍历它。


这就是我正在做的事情,问题不在于如何使用GDIPlus图形对象绘制64位颜色。 - Anurag Uniyal
我不确定你的意思,如果访问缓冲区,每个组件将是2个字节。 - Ed S.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接