【发布时间】:2014-12-20 05:01:10
【问题描述】:
作为确定“图像的基色”的函数,我正在尝试实现以下代码:
typedef unsigned long dword;
typedef unsigned short word;
typedef unsigned char BYTE;
typedef struct
{
BYTE R;
BYTE G;
BYTE B;
} RGB;
RGB
bitfox_get_primecolor_direct
(char *FILE_NAME)
{
RGB primecolor;
BYTE rgb[3];
dword *counts;
dword max_count = 0;
FILE* fp = fopen("sample.bmp", "rb");
counts = calloc(pow(256, 3), sizeof(*counts));
fseek(fp, 54, SEEK_SET);
while (fread (rgb, sizeof(BYTE), 3, fp) == 1)
{
dword idx = (((dword)rgb[0]) << 16) | (((dword)rgb[1]) << 8) | (dword)rgb[2];
if (++counts[idx] > max_count) max_count = idx;
}
primecolor.R = (rgb[max_count] >> 16) & 0xFF;
primecolor.G = (rgb[max_count] >> 8) & 0xFF;
primecolor.B = rgb[max_count] & 0xFF;
free(counts);
fclose(fp);
return primecolor;
}
它应该是一种快速算法(在 RAM 方面不是很节俭)以图像的基色返回 RGB 结构。但是..它返回不正确的颜色。我做错了什么?
【问题讨论】:
-
我停在第一行,但至少:sizeof(*counts)?当然?你在推迟一个未初始化的局部变量吗?
-
几件事。 1) 你确定它是 24 位 bmp 吗?许多位图是 32 位的,因此它们是处理器对齐的。 2)你确定是RGB而不是更常见的BGR?
-
fread()返回成功读取的元素数。由于您阅读了 3 个元素,因此您应该这样做while( fread(..) == 3) -
@Steffen。应该是
while(fread(..) == 1)不同之处在于,不是表示您正在读取三个字节,而是表示您正在读取一个 rgb,这正是您正在做的事情。这也意味着如果 rgb 的定义发生变化,您只需更改一次,此代码将自动获得正确的 rgb 大小。 -
@Lively。那么你应该使用
fread(rgb, sizeof(rgb),1,fp)。