【发布时间】:2016-03-31 15:19:46
【问题描述】:
我仍然无法访问位图图像中的颜色位。问题是,将位图的内容保存到缓冲区后,我不知道:
从哪里开始循环(如果我从 0 开始,我认为它会擦除标题)?
如何访问字节并进行更改(将 BMP 中的颜色转换为输出中所需的颜色)?
还有,如何将缓冲区插入到新的位图文件中?
我要修改的所有图像都具有可被 4 整除的行(当填充特定字节时我必须插入 0)和每像素 24 位。即使是很少的提示也将不胜感激。
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "bmp_header.h"
int main(void)
{
FILE *f;
f = fopen("captcha.bmp","rb");
if ((f = fopen("captcha.bmp", "rb")) == NULL)
{
printf("Error opening file %s.\n", "captcha.bmp");
exit(1);
}
fread(&BMP_header,sizeof(BMP_header),1,f);
fread(&BMP_info_header,sizeof(BMP_info_header),1,f);
fseek(f,BMP_header.imageDataOffset,SEEK_SET);
int rows = (BMP_info_header.bitPix * BMP_info_header.width + 31 ) /32 * 4 ;
char *PixelArray =malloc( rows * abs(BMP_info_header.height)*sizeof(char));
int i;
for( i =sizeof(BMP_header)+sizeof(BMP_info_header); i<=(rows * abs(BMP_info_header.height))-2;i+=3)
{
PixelArray[i]=255; // just a random value to test if this makese any sense
PixelArray[i+1]=255;
PixelArray[i+2]=255;
}
return 0;
}
还有,这是bmp_header.h的内容:
#pragma pack(1)
struct bmp_fileheader
{
unsigned char fileMarker1; /* 'B' */
unsigned char fileMarker2; /* 'M' */
unsigned int bfSize; /* File's size */
unsigned short unused1;
unsigned short unused2;
unsigned int imageDataOffset; /* Offset to the start of image data */
}BMP_header,BMP_header_out;
struct bmp_infoheader
{
unsigned int biSize; /* Size of the info header - 40 bytes */
signed int width; /* Width of the image */
signed int height; /* Height of the image */
unsigned short planes;
unsigned short bitPix;
unsigned int biCompression;
unsigned int biSizeImage; /* Size of the image data */
int biXPelsPerMeter;
int biYPelsPerMeter;
unsigned int biClrUsed;
unsigned int biClrImportant;
}BMP_info_header,BMP_info_header_out;
#pragma pack()
【问题讨论】:
-
尝试更改一个像素而不是所有像素。顺便说一句,圣诞快乐。
-
你不必把它全部放在一个循环中。我想我不明白这个说法:
int rows = (BMP_info_header.bitPix * BMP_info_header.width + 31 ) /32 * 4 ;。你能解释一下这里31、32和4的意义是什么吗? -
啊,好吧。那我会读那部分。我只是想删除循环,以便您可以编辑 1 个像素并查看它是否有效。编辑所有像素时,要找到问题要困难得多。我必须离开20分钟左右。我很快就会回来。
-
好的,我在这里看到了几个问题。 PixelArray 的 malloc 中不需要
* sizeof(char)。 malloc 大小不基于字符的大小 - 仅基于像素图像数据的字节大小。不过,最大的错误是做i =sizeof(BMP_header)+sizeof(BMP_info_header);,然后使用 i (不是从 0 开始)来索引你的 malloced PixelArray (它确实从 0 开始)。还有一个错误是sizeof(BMP_header)+sizeof(BMP_info_header)是颜色表的偏移量,而不是像素数据的偏移量。 -
i<=(rows * abs(BMP_info_header.height))-2表示您不想编辑最后几行?另外,你确定你的像素只有 3 个字节吗? (与类似 4 的东西相反)。