【发布时间】:2021-02-24 05:59:57
【问题描述】:
我只在 windows (AutoHotkey) 上编程,主要使用它的 win32 api。 我想将 GDI 位图(32 位 DIB)转换为灰度。 我使用GetObject() 获取BITMAP 结构并将bmBITS 及其大小传递给以下函数
int ToGrayscale(unsigned char * s, int n)
{
float b, g, r, y;
for (int i=0; i<n; i+=4)
{
b = (float) s[i+0];
g = (float) s[i+1];
r = (float) s[i+2];
y = (0.299 * r) + (0.587 * g) + (0.114 * b);
s[i+0] = s[i+1] = s[i+2] = (unsigned char)y;
}
return 1;
}
以上是完整的代码。我使用 Pelles C 将其编译为 .obj,从 .obj 中提取机器代码 并从 AutoHotkey 语言调用/使用该机器代码。
调用时的机器代码给了我访问冲突错误。
s[i+0] = s[i+1] = s[i+2] = 0;
工作正常并将图像填充为黑色,但我想用灰度值 y 转换像素。 这样做的正确方法是什么?
我不确定我是否提供了足够的信息。请询问/建议,我会更新它。
编辑 1: 我在 c 文件中又添加了一个工作函数 ToBlack()。
int ToBlack(unsigned char * s, int n)
{
for (int i=0; i<n; i+=4)
{
s[i+0] = s[i+1] = s[i+2] = 0;
}
return 1;
}
int ToGrayscale(unsigned char * s, int n)
{
float b, g, r, y;
for (int i=0; i<n; i+=4)
{
b = (float) s[i+0];
g = (float) s[i+1];
r = (float) s[i+2];
y = (0.299 * r) + (0.587 * g) + (0.114 * b);
s[i+0] = s[i+1] = s[i+2] = (unsigned char)y;
}
return 1;
}
源位图是具有单一 ARGB 颜色 FFAABBCC 的 2x2 32 位不透明位图 bmBITS 大小为 16 字节,数据的十六进制表示为 CCBBAAFFCCBBAAFFCCBBAAFFCCBBAAFF
ToBlack() 工作正常,当我在运行机器代码后检查 bmBITS 时, 我得到以下结果 - 正确。
ToBlack(bmBITS, 16) 结果:000000FF000000FF000000FF000000FF
ToBlack(bmBITS, 12) 结果:000000FF000000FF000000FFCCBBAAFF
ToBlack(bmBITS, 8) 结果:000000FF000000FFCCBBAAFFCCBBAAFF
ToBlack(bmBITS, 4) 结果:000000FFCCBBAAFFCCBBAAFFCCBBAAFF
ToGrayscale(bmBITS, 16) 数据不变。 我猜是在分配 y 时发生崩溃。
【问题讨论】:
-
我假设
n是像素数,而i迭代每个颜色字节。那么应该是i<(n/4) -
感谢您的回复。 n 是 bmBITS 的字节大小。我在 .c 文件中又添加了一个函数来说明我的问题。请阅读编辑后的帖子。
-
bmBits定义为 "指向位图位值位置的指针。bmBits 成员必须是指向字符(1 字节)值数组的长指针。 " 该对象的大小为bmHeight * bmWidthBytes字节。那就是n。
标签: c casting char autohotkey grayscale