c++ - 我正在从 BMP 文件中读取像素的 RGB 值,但没有得到正确的值
问题描述
我按照此链接中的代码读取 bmp 文件中的像素值,以便能够读取像素的 RGB 值,并且当我将整个图像作为一种颜色并读取随机像素的值时,它们是正确的。在此之后,我尝试制作它,因此该功能也将尝试找出有多少种独特的颜色,因此我在图像中添加了一个具有不同颜色的框,但该功能仍然只能找到一种颜色。我想知道我是否以某种方式没有查看 BMP 中包含的所有字节,但我不确定那会是怎样的,因为我是尝试这些东西的新手。
为了确保代码没有找到不同颜色的像素但未能将它们添加到唯一像素列表中,我尝试在找到与始终找到但没有输出的颜色不同时打印输出。
struct Color {
int R = -1;
int G = -1;
int B = -1;
};
unsigned char* readBMP(char* filename) {
int i;
FILE* f = fopen(filename, "rb");
unsigned char info[54];
fread(info, sizeof(unsigned char), 54, f);
int width = *(int*)&info[18]; //the reason *(int*) is used here because there's an integer stored at 18 in the array that indicates how wide the BMP is
int height = *(int*)&info[22]; // same reasoning for *(int*)
int size = 3 * width * height;
unsigned char* data = new unsigned char[size];
fread(data, sizeof(unsigned char), size, f);
fclose(f);
// windows has BMP saved as BGR tuples and this switches it to RGB
for(i = 0; i < size; i += 3){
unsigned char tmp = data[i];
data[i] = data[i+2];
data[i+2] = tmp;
}
i = 0; // i is the x value of the pixel that is having its RGB values checked
int j = 0; // j is the y value of the pixel that is having its RGB values checked
unsigned char R = data[3 * (i * width + j)]; // value of R of the pixel at (i,j)
unsigned char G = data[3 * (i * width + j) + 1]; // value of G of the pixel at (i,j)
unsigned char B = data[3 * (i * width + j) + 2]; // value of B of the pixel at (i,j)
std::cout << "value of R is " << int(R);
std::cout << " value of G is " << int(G);
std::cout << " value of B is " << int(B);
Color num_colors[5];
int count;
int z;
int flag;
int iterator;
int sum;
for(count = 0; count < size; count += 1){
unsigned char R = data[3 * (i * width + j)];
unsigned char G = data[3 * (i * width + j) + 1];
unsigned char B = data[3 * (i * width + j) + 2];
sum = int(R) + int(G) + int(B);
if(sum != 301) {// 301 is the sum of the RGB values of the color that the program does manage to find
std::cout << sum;
}
flag = 0;
for(z = 0; z < 5; z += 1){
if(num_colors[z].R == R && num_colors[z].G == G && num_colors[z].B == B){
flag = 1;
}
}
if(flag == 1){
continue;
}
iterator = 0;
while(num_colors[iterator].R != -1){
iterator += 1;
}
num_colors[iterator].R = R;
num_colors[iterator].G = G;
num_colors[iterator].B = B;
}
int number = 0;
for(int r = 0; r < 5; r += 1){
std::cout << "\nValue of R here: " << num_colors[r].R;
if(num_colors[r].R != -1){
number += 1;
}
}
std::cout << "\nNumber of colors in image: " << number;
return data;
}
https://imgur.com/a/dXllIWL 这是我正在使用的图片,所以应该找到两种颜色,但代码只找到红色像素。
解决方案
您的问题是您总是检查 (0,0) 处的 RGB 值
i = 0; // i is the x value of the pixel that is having its RGB values checked
int j = 0; // j is the y value of the pixel that is having its RGB values checked
...
for(count = 0; count < size; count += 1){
unsigned char R = data[3 * (i * width + j)];
unsigned char G = data[3 * (i * width + j) + 1];
unsigned char B = data[3 * (i * width + j) + 2];
i
并j
定义您正在检查的像素的 X 和 Y 位置,但请注意,您永远不会在循环中更改它们。你的循环会一遍又一遍地做同样的事情。您可能想要的是一个双循环,遍历图像中的所有坐标:
for(int y=0; y<height; y++)
for(int x=0; x<width; x++){
unsigned char R = data[3 * (y * width + x) + 0];
unsigned char G = data[3 * (y * width + x) + 1];
unsigned char B = data[3 * (y * width + x) + 2];
推荐阅读
- haskell - 使用 Haskell 的随机元素网格
- mybatis-generator - 如何使用 ignoreQualifiersAtRuntime="true" 删除 auto sql 中的前缀?
- sql - 使用无界前面计算运行总计
- angular - ngFor 在具有不同属性的列中
- android - 我想在我的应用程序中添加一个共享按钮,但我不明白如何实现它,我在我的应用程序中显示来自 firebase 存储的图像
- javascript - 为什么after方法在jQuery中不起作用?
- spring-boot - 如何使用 Mockito 模拟实例化类的方法?
- apache-poi - docx4j 或 Apache-POI:如何从包含图像和英语以外的语言的 docx 文件中获取段落 ID?
- inno-setup - 如何使用 Inno Setup 为 Windows 命令行创建别名?
- java - Spring REST api OAuth2 验证来自外部授权服务器的令牌