用c语言读取24位位图bmp文件

用c语言读取24位位图bmp文件,第1张

可以使用C语言标准函数库中的fopen、fseek、fclose等系列函数来打开bmp位图文件,以及进行相应的处理,下面是一个demo,仅供参考。以下代码在vc6.0中编译通过。

#include <stdio.h>

#include <stdlib.h>

#define BITMAPFILEHEADERLENGTH 14   // The bmp FileHeader length is 14

#define BM 19778                    // The ASCII code for BM

/* Test the file is bmp file or not */

void bmpFileTest(FILE* fpbmp)

/* To get the OffSet of header to data part */

void bmpHeaderPartLength(FILE* fpbmp)

/* To get the width and height of the bmp file */

void BmpWidthHeight(FILE* fpbmp)

//get r,g,b data

void bmpDataPart(FILE* fpbmp)

// output data to corresponding txt file

void bmpoutput(FILE *fpout)

unsigned int OffSet = 0    // OffSet from Header part to Data Part

long width           // The Width of the Data Part

long height          // The Height of the Data Part

unsigned char r[2000][2000],output_r[2000][2000]

unsigned char g[2000][2000],output_g[2000][2000]

unsigned char b[2000][2000],output_b[2000][2000]

int main(int argc, char* argv[])

{

     /* Open bmp file */

unsigned char *fp_temp

     FILE *fpbmp

     FILE *fpout

     fpbmp= fopen("1.bmp", "rb")

     if (fpbmp == NULL)

     {

 printf("Open bmp failed!!!\n")

 return 1

     }

     fpout= fopen("out.bmp", "wb+")

     if (fpout == NULL)

     {

 printf("Open out.bmp failed!!!\n")

 return 1

     }

     

     bmpFileTest(fpbmp)                //Test the file is bmp file or not

     bmpHeaderPartLength(fpbmp)        //Get the length of Header Part

     BmpWidthHeight(fpbmp)             //Get the width and width of the Data Part

     

     

//

fseek(fpbmp, 0L, SEEK_SET)

fseek(fpout, 0L, SEEK_SET)

 

fp_temp=(unsigned char *)malloc(OffSet)

         fread(fp_temp, 1, OffSet, fpbmp)

fwrite(fp_temp,1,OffSet,fpout)

     

bmpDataPart(fpbmp)                //Reserve the data to file 

     

/*

 

 

 如果您想对图片进行处理,请您再这里插入处理函数!!!!!!!!!!!!!!!!!!

 

*/

bmpoutput(fpout)

fclose(fpbmp)

fclose(fpout)

         return 0

}

void bmpoutput(FILE* fpout)

{

         int i, j=0

         int stride

unsigned char* pixout=NULL

   

stride=(24*width+31)/8

stride=stride/4*4

pixout=(unsigned char *)malloc(stride)

 

fseek(fpout, OffSet, SEEK_SET)

for(j=0j<heightj++)

{

   for(i=0i<widthi++)

        {

            pixout[i*3+2]=output_r[height-1-j][i]

            pixout[i*3+1]=output_g[height-1-j][i]

            pixout[i*3]  =output_b[height-1-j][i]

        }

fwrite(pixout, 1, stride, fpout)

}

}

void bmpDataPart(FILE* fpbmp)

{

         int i, j=0

int stride

unsigned char* pix=NULL

FILE* fpr

         FILE* fpg

FILE* fpb

     

     if((fpr=fopen("bmpr.txt","w+")) == NULL)

     {

    printf("Failed to construct file bmpr.txt.!!!")

exit(1)

     }

     if((fpg=fopen("bmpg.txt","w+")) == NULL)

     {

 printf("Failed to construct file bmpg.txt.!!!")

 exit(1)

     }

if((fpb=fopen("bmpb.txt","w+")) == NULL)

     {

printf("Failed to construct file bmpb.txt.!!!")

exit(1)

     }

 

     fseek(fpbmp, OffSet, SEEK_SET)

stride=(24*width+31)/8

stride=stride/4*4

pix=(unsigned char *)malloc(stride)

 

for(j=0j<heightj++)

{

fread(pix, 1, stride, fpbmp)

   for(i=0i<widthi++)

        {

            r[height-1-j][i]   =pix[i*3+2]

            g[height-1-j][i]   =pix[i*3+1]

            b[height-1-j][i]   =pix[i*3]

output_r[height-1-j][i]   =pix[i*3+2]

            output_g[height-1-j][i]   =pix[i*3+1]

            output_b[height-1-j][i]   =pix[i*3]

        }

}

 for(i =0 i < height i++)

     {

for(j = 0 j < width-1 j++)

{   

fprintf(fpb,"%4d",b[i][j])

fprintf(fpg,"%4d",g[i][j])

fprintf(fpr,"%4d",r[i][j])

}

fprintf(fpb,"%4d\n",b[i][j])

fprintf(fpg,"%4d\n",g[i][j])

fprintf(fpr,"%4d\n",r[i][j])

 }

  

fclose(fpr)

fclose(fpg)

fclose(fpb)

 

}

void bmpFileTest(FILE* fpbmp)

{     

     unsigned short bfType = 0

 

     fseek(fpbmp, 0L, SEEK_SET)//seek_set 起始位置

     fread(&bfType, sizeof(char), 2, fpbmp)

     if (BM != bfType)

     {

 printf("This file is not bmp file.!!!\n")

 exit(1)

     }

}

/* To get the OffSet of header to data part */

void bmpHeaderPartLength(FILE* fpbmp)

{

     fseek(fpbmp, 10L, SEEK_SET)

     fread(&OffSet, sizeof(char), 4, fpbmp)  

     printf("The Header Part is of length %d.\n", OffSet)

}

/* To get the width and height of the bmp file */

void BmpWidthHeight(FILE* fpbmp)

{

     fseek(fpbmp, 18L, SEEK_SET)

     fread(&width, sizeof(char), 4, fpbmp)

     fseek(fpbmp, 22L, SEEK_SET)

     fread(&height, sizeof(char), 4, fpbmp)

     printf("The Width of the bmp file is %ld.\n", width)

     printf("The Height of the bmp file is %ld.\n", height)

}

我也遇到过类似的问题,位图数据读取到内存,然后在保存的文件中。

新位图文件,虽然能够显示但是图片内容中存在大量错误。

后来发现问题的关键在于

fopen(bmpname,"rb")

注意rb标志,不管是只读标志还是只写标志,或者读写标志后面要加+。

也就是rb+

不加+的标志是针对的文本读写的。

加+的标志是针对二进制数据读写的。

而位图文件是一种二进制数据。

对于一个24位色的图,你直接就拿int(32位机器,长度32位)型二维数组存就行了。肯定能存这个24位数,没必要把颜色分开存。如果分开存你就用下面的结构体数组的方法吧。建议参考,十分方便实用。

RGB24使用24位来表示一个像素,RGB分量都用8位表示,取值范围为0-255。注意在内存中RGB各分量的排列顺序为:BGR BGR BGR…。通常可以使用RGBTRIPLE数据结构来 *** 作一个像素,它的定义为:

typedef struct tagRGBTRIPLE

{BYTE rgbtBlue// 蓝色分量

BYTE rgbtGreen// 绿色分量

BYTE rgbtRed// 红色分量

} RGBTRIPLE


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/tougao/11928576.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-19
下一篇2023-05-19

发表评论

登录后才能评论

评论列表(0条)

    保存