gpt4 book ai didi

c - 从图像 RGB bmp 纯 C 编写灰度 bmp 的这段代码有什么问题 - Windows 操作系统

转载 作者:行者123 更新时间:2023-11-30 19:15:48 28 4
gpt4 key购买 nike

这是我的函数,我根据维基百科 BITMAPINFOHEADER 使用标题 BMP。但是,我得到的文件没有任何图像...当放置填充时,该过程停止。

 // Structures for header info
#pragma pack(push,1)
/* Windows 3.x bitmap file header */
typedef struct {
char filetype[2]; /* magic - always 'B' 'M' */
unsigned int filesize;
short reserved1;
short reserved2;
unsigned int dataoffset; /* offset in bytes to actual bitmap data */
} file_header;

/* Windows 3.x bitmap full header, including file header */
typedef struct {
file_header fileheader;
unsigned int headersize;
int width;
int height;
short planes;
short bitsperpixel; /* we only support the value 24 here */
unsigned int compression; /* we do not support compression */
unsigned int bitmapsize;
int horizontalres;
int verticalres;
unsigned int numcolors;
unsigned int importantcolors;
} bitmap_header;
#pragma pack(pop)


int RGB2GREY(char* input, char *greyImage) {

//variable declaration:
FILE *fp, *grey;
bitmap_header* hp;
int n;
char *data;
int oldBitsperpixel;

//Open input file:
fp = fopen(input, "rb");
if(fp==NULL){
//cleanup
}

//Read the input file headers:
hp=(bitmap_header*)malloc(sizeof(bitmap_header));
if(hp==NULL)
return 3;

n=fread(hp, sizeof(bitmap_header), 1, fp);
if(n<1){
//cleanup
}

//Read the data of the image:
data = (char*)malloc(sizeof(char)*hp->bitmapsize);
if(data==NULL){
//cleanup
}
//Put me in the position after header...
fseek(fp,sizeof(char)*hp->fileheader.dataoffset,SEEK_SET);
printf("Width %d and Height %d\n",hp->width,hp->height);

int i, j;
unsigned char BGR[3];
unsigned colorIntensity[3];
/*unsigned char bmppad[hp->width] = {0};*/

printf("New bitmapSize %d\n\n",hp->bitsperpixel);

//Open greayImage file:
grey = fopen(greyImage, "wb");
if(grey==NULL){
//cleanup
}
//Writes the header
n=fwrite(hp,sizeof(char),sizeof(bitmap_header),grey);
if(n<1){
//cleanup
}
//Again going to position after header
fseek(out,sizeof(char)*hp->fileheader.dataoffset,SEEK_SET);
for (i=0; i<hp->height; i++){
for (j=0; j<hp->width; j++){
//Reading pixel by pixel
fread(BGR, 3, 1, fp); //1 unsigned char of 3 positions
unsigned char colorGrey;
colorGrey = (unsigned char) 0.3*BGR[2] + 0.6*BGR[1] + 0.1*BGR[0];
colorIntensity[2] = colorGrey;
colorIntensity[1] = colorGrey;
colorIntensity[0] = colorGrey;
/*printf("B %d G %d R %d ",BGR[0],BGR[1],BGR[2]);
printf("Gray %d ",colorIntensity);*/
fwrite(colorIntensity, 3, 1, grey);
}
/*
// Adding pad option1
//fwrite(bmppad, sizeof(bmppad), 1, grey);
//Adding pad option2
for (j=0; j>hp->width; j++){
fwrite(0, 1, 1, grey);
}*/
}
fclose(fp);
fclose(grey);
free(hp);
free(data);
return 0;

}

在灰色的输出文件中,我什么也没得到......而且,我想知道是否有办法从 24 位减少到 8 位。

ps。我的代码来自reading/writing bmp files in c

公式来自Create greyscale BMP from RGB BMP

谢谢

最佳答案

您实际上是通过以灰色显示的方式更改颜色值,将 32 位彩色位图转换为 32 位灰色位图(您不会以这种方式节省任何空间;位图保持与它一样大)曾是)。无论如何,它解释了为什么您不需要调整位图 header 。

但是,当您每三个字节读取一次并每三个字节更改一次时,您就不会考虑扫描线。

图像由扫描线组成,扫描线由像素组成。扫描线在偶数字边界上对齐,因此扫描线的最后几个字节未被使用(因此扫描线比其上的所有像素都长一点)。

要正确处理输入并创建输出,您的循环必须是:

(编辑:更新为每像素输出使用 1 个字节):

#pragma pack(push,1)
typedef struct {
unsigned char rgbBlue;
unsigned char rgbGreen;
unsigned char rgbRed;
unsigned char rgbReserved;
} pal_entry;
#pragma pack(pop)

int ToGreyScale(FILE *fp, FILE *grey, bitmap_header *hp)
{
int i, j;
int iScanlineSizeIn = ((hp->width * hp->bitsperpixel) + 31) / 32 * 4;
int iScanlineSizeOut= ((hp->width * 8 ) + 31) / 32 * 4;
unsigned char *scanlineIn = malloc(iScanlineSizeIn), *pIn;
unsigned char *scanlineOut= malloc(iScanlineSizeOut), *pOut;
pal_entry pal[256];

for (i=0; i<256; i++) // create a gray scale palette
{pal[i].rgbBlue= i; pal[i].rgbGreen= i; pal[i].rgbRed= i;}

hp->bitsperpixel= 8; // set output bits-per-pixel
hp->fileheader.filesize= sizeof(bitmap_header) + sizeof(pal) + hp->width*iScanlineSizeOut;

fwrite(hp, sizeof(bitmap_header), 1, grey); // write the header...
fwrite(pal, 256*sizeof(pal_entry), 1, grey); //..followed by palette

for (i=0; i<hp->height; i++)
{
if (fread(scanlineIn, iScanlineSizeIn, 1, fp) != 1) return(0);
pIn = scanlineIn;
pOut= scanlineOut;
for (j=0; j<hp->width; j++)
{
*pOut++ = (unsigned char) ((0.1 * *pIn++) + (0.6 * *pIn++) + (0.3 * *pIn++));
}
fwrite(scanlineOut, iScanlineSizeOut, 1, grey);
}
free(scanlineIn);
free(scanlineOut);
return(1);
}

关于c - 从图像 RGB bmp 纯 C 编写灰度 bmp 的这段代码有什么问题 - Windows 操作系统,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31844871/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com