代码改变世界

纯C下的读写BMP文件代码

2007-10-24 15:00  htc开发  阅读(255)  评论(0编辑  收藏  举报

 

纯C代码下读写BMP文件代码,简单易懂。

 

/*************************************************************
**  Copyright (c) 2007, Shanghai 
**  
**  文件名称:read_write_bmp_with_C.c
**  编译:    Visual C++  / ANSI C / ISO C++
**    日期:    2007.10.24
*************************************************************
*/


#include "stdio.h"
#include 
"stdlib.h"

#define PIXPLINE  320

typedef 
struct tagRGBQUAD{     //定义每个像素的数据类型
        unsigned char  rgbBlue;
        unsigned 
char  rgbGreen;
        unsigned 
char  rgbRed;
}
    RGBQUAD;

int bmp_read(unsigned char *image, int xsize, int ysize, char *filename) {
    
char fname_bmp[128];
    sprintf(fname_bmp, 
"%s.bmp", filename);
    
    FILE 
*fp;
    
if (!(fp = fopen(fname_bmp, "rb"))) 
      
return -1;
      
    unsigned 
char header[54];
    fread(header, 
sizeof(unsigned char), 54, fp);
    fread(image, 
sizeof(unsigned char), (size_t)(long)xsize * ysize * 3, fp);
    
    fclose(fp);
    
return 0;
}


int bmp_write(unsigned char *image, int xsize, int ysize, char *filename) {
    unsigned 
char header[54= {
      
0x420x4d00000000,
        
54000400000000000010240
        
00000000000000000000
        
0000
    }
;
    
    
long file_size = (long)xsize * (long)ysize * 3 + 54;
    header[
2= (unsigned char)(file_size &0x000000ff);
    header[
3= (file_size >> 8& 0x000000ff;
    header[
4= (file_size >> 16& 0x000000ff;
    header[
5= (file_size >> 24& 0x000000ff;
    
    
long width = xsize;
    header[
18= width & 0x000000ff;
    header[
19= (width >> 8&0x000000ff;
    header[
20= (width >> 16&0x000000ff;
    header[
21= (width >> 24&0x000000ff;
    
    
long height = ysize;
    header[
22= height &0x000000ff;
    header[
23= (height >> 8&0x000000ff;
    header[
24= (height >> 16&0x000000ff;
    header[
25= (height >> 24&0x000000ff;

    
char fname_bmp[128];
    sprintf(fname_bmp, 
"%s.bmp", filename);
    
    FILE 
*fp;
    
if (!(fp = fopen(fname_bmp, "wb"))) 
      
return -1;
      
    fwrite(header, 
sizeof(unsigned char), 54, fp);
    fwrite(image, 
sizeof(unsigned char), (size_t)(long)xsize * ysize * 3, fp);
    
    fclose(fp);
    
return 0;
}


void clonebmp(unsigned char *image,int xsize,int ysize)
{
    bmp_read(image, xsize, ysize, 
"orgbmp");  //orgbmp为当前目录下的bmp文件名
    bmp_write(image, xsize, ysize, "clone_bmp");//clone_bmp为克隆的bmp文件名
}



    
/****************************************************************************
* 名称:youwritetobmp()
* 功能:写入bmp文件
* 入口参数:RGBQUAD *pixarr ---- 要写入的像素数组指针, int xsize ---- 图像宽度, int ysize ---- 图像高度, char *filename --图像名称
* 出口参数:无
* 返回值:-1:错误  ;0:正确
***************************************************************************
*/

int youwritetobmp(RGBQUAD *pixarr, int xsize, int ysize, char *filename) {
    unsigned 
char header[54= {
      
0x420x4d00000000,
        
540004000000
        
00000010240
        
0000000000,
        
0000000000
        
0000
    }
;
    
int i;
    
int j;
    
long file_size = (long)xsize * (long)ysize * 3 + 54;
    header[
2= (unsigned char)(file_size &0x000000ff);
    header[
3= (file_size >> 8& 0x000000ff;
    header[
4= (file_size >> 16& 0x000000ff;
    header[
5= (file_size >> 24& 0x000000ff;
    
    
long width;
    
if(!(xsize%4))    width=xsize;
    
else            width= xsize+(4-xsize%4);    //如不是4的倍数,则转换成4的倍数
    header[18= width & 0x000000ff;
    header[
19= (width >> 8&0x000000ff;
    header[
20= (width >> 16&0x000000ff;
    header[
21= (width >> 24&0x000000ff;
    
    
long height = ysize;
    header[
22= height &0x000000ff;
    header[
23= (height >> 8&0x000000ff;
    header[
24= (height >> 16&0x000000ff;
    header[
25= (height >> 24&0x000000ff;

    
char fname_bmp[128];
    sprintf(fname_bmp, 
"%s.bmp", filename);
    
    FILE 
*fp;
    
if (!(fp = fopen(fname_bmp, "wb"))) 
      
return -1;
      
    fwrite(header, 
sizeof(unsigned char), 54, fp);

    RGBQUAD zero
={0,0,0};  //不足字节,用zero填充
    
    
for(j=0;j<ysize;j++){
        
if(!(xsize%4)){
            
for(i=0;i<xsize;i++)
                 fwrite(pixarr
+i, sizeof(RGBQUAD),1, fp);
            }

        }

        
else
        
{
            
for(i=0;i<xsize;i++)
                 fwrite(pixarr
+i, sizeof(RGBQUAD),1, fp);
            }

            
for(i=xsize;i<xsize+(4-xsize%4);i++){
                fwrite(
&zero, sizeof(RGBQUAD),1, fp);
            }

        }

    }

    
    fclose(fp);
    
return 0;

}


int main() {
    unsigned 
char *image;
    
int xsize = 320;
    
int ysize = 163;

    RGBQUAD pixarray[PIXPLINE]; 
//一行像素值数组

    image 
= (unsigned char *)malloc((size_t)xsize * ysize * 3);
    
if (image == NULL) 
      
return -1;
    clonebmp(image,xsize,ysize);    
//功能一:实现一副图像的拷贝


    youwritetobmp(pixarray,xsize,ysize,
"yourimage");//功能二:实现像素的精确绘制,像素值在pixarray数组中
    
    free(image);
    
return -1;
}