Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从RGB bmp纯C-Windows操作系统的图像中写入灰度bmp的代码有什么问题_C_Bmp_Grayscale - Fatal编程技术网

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

从RGB bmp纯C-Windows操作系统的图像中写入灰度bmp的代码有什么问题,c,bmp,grayscale,C,Bmp,Grayscale,这是我的函数,我使用的是wikipedia 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' */

这是我的函数,我使用的是wikipedia 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;
//头信息的结构
#pragma包(推送,1)
/*Windows 3.x位图文件头*/
类型定义结构{
char文件类型[2];/*magic-始终为“B”“M”*/
无符号整数文件大小;
短期储备1;
储备不足2;
unsigned int dataoffset;/*实际位图数据的字节偏移量*/
}文件头;
/*Windows 3.x位图完整头,包括文件头*/
类型定义结构{
文件头文件头;
无符号整数标题;
整数宽度;
内部高度;
短平面;
short bitsperpixel;/*我们这里只支持值24*/
无符号整数压缩;/*我们不支持压缩*/
无符号整数位图大小;
内水平线;
垂直方向;
无符号整数颜色;
未签名的国际重要颜色;
}位图头;
#布拉格语包(流行语)
int RGB2GRY(字符*输入,字符*灰度图像){
//变量声明:
文件*fp,*灰色;
位图_头*hp;
int n;
字符*数据;
int-oldbitsperpix;
//打开输入文件:
fp=fopen(输入,“rb”);
如果(fp==NULL){
//清理
}
//读取输入文件标题:
hp=(位图_头*)malloc(sizeof(位图_头));
如果(hp==NULL)
返回3;
n=fread(hp,sizeof(位图头),1,fp);
如果(nbitmapsize);
如果(数据==NULL){
//清理
}
//把我放在头球后的位置。。。
fseek(fp,sizeof(char)*hp->fileheader.dataoffset,SEEK\u SET);
printf(“宽度%d和高度%d\n”,hp->Width,hp->Height);
int i,j;
无符号字符BGR[3];
无符号色强度[3];
/*无符号字符bmppad[hp->width]={0}*/
printf(“新位图大小%d\n\n”,hp->bitsperpixel);
//打开灰色图像文件:
灰色=fopen(灰色图像,“wb”);
如果(灰色==NULL){
//清理
}
//写入标题
n=fwrite(hp、sizeof(char)、sizeof(位图头)、灰色);
if(nfileheader.dataoffset,SEEK_SET);
对于(i=0;iheight;i++){
对于(j=0;jwidth;j++){
//逐像素读取
fread(BGR,3,1,fp);//3个位置的1个无符号字符
无符号字符颜色灰色;
colorGrey=(无符号字符)0.3*BGR[2]+0.6*BGR[1]+0.1*BGR[0];
颜色强度[2]=颜色灰;
颜色强度[1]=颜色灰;
颜色强度[0]=颜色灰;
/*printf(“B%d G%d R%d”,BGR[0],BGR[1],BGR[2]);
printf(“灰色%d”,颜色强度)*/
fwrite(颜色强度,3,1,灰色);
}
/*
//添加pad选项1
//fwrite(bmppad,sizeof(bmppad),1,灰色);
//添加pad选项2
对于(j=0;j>hp->width;j++){
fwrite(0,1,1,灰色);
}*/
}
fclose(fp);
fclose(灰色);
免费(hp);
免费(数据);
返回0;
}

在灰色输出文件中,我什么也得不到……此外,我想知道是否有办法将24位减少到8位

我的代码来自

公式来自


谢谢,

通过以灰色显示的方式更改颜色值,您实际上是在将32位彩色位图转换为32位灰色位图(这样不会节省任何空间;位图保持原来的大小)。另外,它解释了为什么不需要调整位图标题

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

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

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

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

#pragma包(推送,1)
类型定义结构{
无符号字符rgbBlue;
无符号字符rgbGreen;
无符号字符;
未签名字符;
}pal_条目;
#布拉格语包(流行语)
int ToGreyScale(文件*fp,文件*GRY,位图头*hp)
{
int i,j;
int iScanlineSizeIn=((hp->width*hp->bitsperpixel)+31)/32*4;
int iScanlineSizeOut=((hp->width*8)+31)/32*4;
无符号字符*scanlineIn=malloc(iScanlineSizeIn),*pIn;
无符号字符*scanlineOut=malloc(iScanlineSizeOut),*pOut;
pal_输入pal[256];
对于(i=0;ibitsperpixel=8;//设置每个像素的输出位
hp->fileheader.filesize=sizeof(位图_头)+sizeof(pal)+hp->width*iScanlineSizeOut;
fwrite(hp,sizeof(位图标题),1,灰色);//写入标题。。。
fwrite(pal,256*sizeof(pal_条目),1,灰色);/…后跟调色板
对于(i=0;iheight;i++)
{
if(fread(scanlineIn,iScanlineSizeIn,1,fp)!=1)返回(0);
pIn=扫描线输入;
pOut=扫描线输出;
对于(j=0;jwidth;j++)
{
*pOut++=(无符号字符)((0.1**pIn++)+(0.6**pIn++)+(0.3**pIn++));
}
fwrite(扫描线,iScanlineSizeOut,1,灰色);
}
免费(scanlineIn);
免费(扫描线输出);
申报表(1);
}   

常见的BMP问题:
bitmap\u header
可能需要进行
打包
。发布您对它的定义,并发布您系统的数据结构大小。(用于
写入(hp、sizeof(char)、sizeof(bitmap\u header)、灰色);
)这不是一个BMP头的问题,我浪费了很多内存来获取相同的BMP文件,只是将所有三个通道更改为相同的灰色值…正如Paul提到的…我知道我需要更改颜色调色板,但需要一步一步地进行。注意:像
.BMP
这样的文件格式需要精确的宽度整数。很好,代码使用了packed结构,而不是
short,int,
code实际上应该使用
int16\t,int32\t
#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);
}