最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
当前位置: 首页 - 正文

c语言读取BMP

来源:动视网 责编:小OO 时间:2025-09-23 16:08:21
文档

c语言读取BMP

C语言读取和显示BMP文件(zt)默认分类  2009-09-1914:23  阅读106   评论0 字号:大大 中中 小小C语言读取和显示BMP文件Postedon2008-01-2101:12hoodlum1980阅读(2624)评论(0) 编辑收藏网摘在TC2.0下,隶属于16位子系统,所以int是2字节,long是4字节,char是1字节。绘图系统模式是VGA,颜色当然也很有限,所以读取bmp像素后需要把像素颜色转换为“最近”的已有VGA颜色。用intGetColor(intr,in
推荐度:
导读C语言读取和显示BMP文件(zt)默认分类  2009-09-1914:23  阅读106   评论0 字号:大大 中中 小小C语言读取和显示BMP文件Postedon2008-01-2101:12hoodlum1980阅读(2624)评论(0) 编辑收藏网摘在TC2.0下,隶属于16位子系统,所以int是2字节,long是4字节,char是1字节。绘图系统模式是VGA,颜色当然也很有限,所以读取bmp像素后需要把像素颜色转换为“最近”的已有VGA颜色。用intGetColor(intr,in
C语言读取和显示BMP文件 (zt)

默认分类   2009-09-19 14:23   阅读106   评论0   

字号: 大大  中中  小小 

C语言读取和显示BMP文件 

Posted on 2008-01-21 01:12 hoodlum1980 阅读(2624) 评论(0)  编辑 收藏 网摘 

在TC2.0下,隶属于16位子系统,所以int是2字节,long是4字节,char是1字节。绘图系统模式是VGA,颜色当然也很有限,所以读取bmp像素后需要把像素颜色转换为“最近”的已有VGA颜色。用int GetColor(int r,int g,int b)实现返回一个颜色值(color code)。用putpixel(int x,int y,int color)绘制一个像素。

      下图是几种在.NET Framework中的已知颜色和其RGB值(下图当然也是使用代码绘制的,代码略)。

      

      16种颜色是位于RGB立方体中的16个点,相当于寻找一个最接近指定颜色的点。为了简化计算,计算出两点距离的平方即可。

      为了加快搜索,我们可以用下面的类似绘制“金刚石”的代码提前求出最短距离的平方,这个数据将应用到GetColor函数中。原因是我们已知最近的两个颜色点的距离,如果某点与某颜色的距离小于最短距离的一半,则此颜色就是我们要找的结果。

Compute Minimum Dist^2 Code

int COLORS[16][3]={.};

/* i,j - color index */

/* ret - distance^2 */

long GetDist(int i,int j)

{

        long dist=0;

        dist+=(COLORS[i][0]-COLORS[j][0])*(COLORS[i][0]-COLORS[j][0]);

        dist+=(COLORS[i][1]-COLORS[j][1])*(COLORS[i][1]-COLORS[j][1]);

        dist+=(COLORS[i][2]-COLORS[j][2])*(COLORS[i][2]-COLORS[j][2]);

        return dist;

}

void main(void)

{

        int i, j;

        long dist,mindist=195075;

        for(i=0;i<15;i++)

        {

                for(j=i+1;j<16;j++)

                {

                        dist=GetDist(i,j);

                        if(dist                                mindist=dist;

                }

        }

        printf("mindis^2=%d",mindist);

}_

      在下面的代码里为了简化处理,我们仅考虑了一种比较常见的BMP文件,即bpp=24,未经压缩的文件。

Code

#include 

#include 

#include 

#include 

int MAX_Y=480;

int MAX_X=0;

int COLORS[16][3]=

    {

        /* R   G   B        Index    ColorName        */

        {  0,  0,  0},     /* 00 Black                */

        {  0,  0,255},     /* 01 Blue                */

        {  0,128,  0},        /* 02 Green                */

        {  0,255,255},     /* 03 Cyan                */

        {255,  0,  0},     /* 04 Red                */

        {255,  0,255},     /* 05 Magenta            */

        {165, 42, 42},     /* 06 Brown                */

        {211,211,211},     /* 07 LightGray        */

        {169,169,169},     /* 08 DarkGray            */

        {173,216,230},     /* 09 LightBlue        */

        {144,238,144},     /* 10 LightGreen        */

        {144,238,238},        /* 11 LightCyan        */

        {238,144,144},     /* 12 LightRed            */

        {238,144,238},     /* 13 LightMegenta    */

        {255,255,  0},     /* 14 Yellow            */

        {255,255,255},        /* 15 White                */

    };

/* pixel : keep channel order with readfile order */

typedef struct _PIXEL

{

    unsigned char b;

    unsigned char g;

    unsigned char r;

} PIXEL;

/* color item in palette */

typedef struct _RGBQUAD

{

    unsigned char rgbBlue;

    unsigned char rgbGreen;

    unsigned char rgbRed;

    unsigned char rgbReserved;

} RGBQUAD;

/* bitmap file header */

typedef struct _BITMAPFILEHEADER

{

    unsigned int type;

    long fileSize;

    long reserved;

    long offbits;

} BITMAPFILEHEADER,*PBITMAPFILEHEADER;

/* bitmap info header */

typedef struct _BITMAPINFOHEADER

{

    long dwSize;

    long width;

    long height;

    int  planes;

    int  bpp;

    long compression;

    long sizeImage;

    long hResolution;

    long vResolution;

    long colors;

    long importantColors;

} BITMAPINFOHEADER,*PBITMAPINFOHEADER;

/* Functions Declare List */

int      GetColor();

void    ReadImage();

void    DrawAxes();

void    CopyScreen();

/* Entry Point Function */

void main()

{

    int driver,mode;

    char filename[255];

    printf("input the filename of bitmap file:\\n");

    scanf("%s",filename);

    driver=DETECT;

    initgraph(&driver,&mode,"c:\\\c\\\\");

    /* draw a bitmap */

    ReadImage(filename);

    getch();

    closegraph();

}

/* read pixels from imagefile and display */

void ReadImage(char* filename)

{

    FILE* stream;

    char string[255];

    int i,j,width,height,color;

    size_t bytesRead,stride,itemSize=1;

    long offset;

    BITMAPFILEHEADER fileHeader;

    BITMAPINFOHEADER infoHeader;

    unsigned char *pPixels,red,green,blue;

    stream=fopen(filename,"rb");

    if(stream==NULL)

    {

        printf("open file error!\\n");

        exit(0);

    }

    fseek(stream,0,0);

    fread(&fileHeader,1,sizeof(fileHeader),stream);

    fread(&infoHeader,1,sizeof(infoHeader),stream);

    width=infoHeader.width;

    height=infoHeader.height;

    /* stride: scan line bytes count. padding for 4 bytes */

    stride=(infoHeader.bpp*width+31)/32*4;

    pPixels=malloc(stride);

    for(j=height-1;j>=0;j--)

    {

        /* !!! stride (2 bytes) must be convert to long (4 bytes) */

        offset=fileHeader.offbits+j*((long)stride);

        fseek(stream,offset,0);

        bytesRead=fread(pPixels,itemSize,stride,stream);

        for(i=0;i        {

            red    = pPixels[i*3+2];

            green    = pPixels[i*3+1];

            blue    = pPixels[i*3];

            color=GetColor(red,green,blue);

            putpixel(100+i,height+100-j,color);

        }

    }

    fclose(stream);    /* close the bitmap file */

    free(pPixels);

    setcolor(63);

    /* draw the bitmap border rect */

    rectangle(100,100,100+width,100+height);

    /* Draw X and Y axes */

    DrawAxes(width,height);

    setcolor(3);

    sprintf(string,"FileName:\\"%s\\" bpp=%d",filename,infoHeader.bpp);

    outtextxy(100,30,string);

    outtextxy(200,460,"press any key to save screen to a bitmap.");

    getch();

    /* copy the screen and save to bmp file */

    CopyScreen("c:\\\c\\\\SCREEN.BMP",0,0,199+width,199+height);

}

/* compute a color by RGB  */

int GetColor(unsigned int red,unsigned int green,unsigned int blue)

{

    int i,index=0;

    unsigned long dist,temp;

    temp=195075;

    for(i=0;i<16;i++)

    {

        dist=0;

        dist+=(COLORS[i][0]-red)*(COLORS[i][0]-red);

        dist+=(COLORS[i][1]-green)*(COLORS[i][1]-green);

        dist+=(COLORS[i][2]-blue)*(COLORS[i][2]-blue);

         /* minimum dist^2=2492, 623=[minimum dist^2]/4 */

        if(dist<=623) 

            return i;

        if(dist        {

            index=i;

            temp=dist;

        }

    }

    return index;

}

/* draw X and Y axes */

void DrawAxes(int width,int height)

{

    int i,j;

    char text[50];

    setcolor(15);

    line(100,100,150+width,100);            /* X axis */

    line(150+width,100,145+width,97);

    line(150+width,100,145+width,103);

    outtextxy(154+width,95,"X");

    line(100,100,100,150+height);         /* Y axis */

    line(100,150+height,97,145+height);

    line(100,150+height,103,145+height);

    outtextxy(95,154+height,"Y");

    for(i=0;i<=width+20;i+=10)

    {

        sprintf(text,"%d",i);

        line(100+i,97,100+i,100);

        if(i%50==0)

        {

            line(100+i,94,100+i,97);     /* make longer */

            sprintf(text,"%d",i);

            outtextxy(95+i,85,text);

        }

    }

    for(j=0;j<=height+20;j+=10)

    {

        line(97,j+100,100,j+100);

        if(j%50==0)

        {

            line(94,j+100,97,j+100);    /* make longer */

            sprintf(text,"%d",j);

            outtextxy(70,j+98,text);

        }

    }

    sprintf(text,"ImageSize: %d * %d pixels",width,height);

    setcolor(2);

    outtextxy(100,50,text);

}

/* copy the screen and save to a bmp file */

void CopyScreen(char* filename,int left,int top,int right,int bottom)

{

    int i,j,width,height,bpp=4,colorUsed=16,stride,index0,index1;

    BITMAPFILEHEADER fileHeader;

    BITMAPINFOHEADER infoHeader;

    RGBQUAD *palette;

    unsigned char *pPixels;

    FILE *stream;

    width=right-left+1;

    height=bottom-top+1;

    stride=(width*bpp+31)/32*4;

    /* fill file header */

    fileHeader.type=0x4D42;    /* filetype:"BM" ascii code */

    fileHeader.fileSize=sizeof(infoHeader);

    fileHeader.fileSize+=sizeof(RGBQUAD)*colorUsed;

    fileHeader.fileSize+=((long)stride)*height;

    fileHeader.reserved=0;

    fileHeader.offbits=sizeof(fileHeader)+sizeof(infoHeader)+4*16;

    /* fill info header */

    infoHeader.dwSize=sizeof(BITMAPINFOHEADER);

    infoHeader.width=width;

    infoHeader.height=height;

    infoHeader.planes=1;    /* must set to 1 */

    infoHeader.bpp=bpp;

    infoHeader.compression=0;

    infoHeader.sizeImage=((long)stride)*height;

    infoHeader.hResolution=0x27;

    infoHeader.vResolution=0x27;

    infoHeader.colors=16;

    infoHeader.importantColors=0;

    /* fill RGBQUAD items */

    palette=malloc(sizeof(RGBQUAD)*16);

    if(palette==NULL)

    {

        printf("malloc for palette fail!");

        return;

    }

    for(i=0;i<16;i++)

    {

        palette[i].rgbRed = COLORS[i][0];

        palette[i].rgbGreen = COLORS[i][1];

        palette[i].rgbBlue = COLORS[i][2];

        palette[i].rgbReserved = 0;

    }

    /* open the file in wb mode */

    stream=fopen(filename,"wb");

    if(stream==NULL)

    {

        printf("open file fail!");

        return;

    }

    fwrite(&fileHeader,sizeof(fileHeader),1,stream);

    fwrite(&infoHeader,sizeof(infoHeader),1,stream);

    fwrite(palette,sizeof(RGBQUAD),16,stream);

    free(palette);

    /* write the bitmap data: color indexes ,bpp=4 */

    pPixels=malloc(stride);

    if(pPixels==NULL)

    {

        printf("malloc for pPixels fail!");

        return;

    }

    for(j=bottom;j>=top;j--)

    {

        memset(pPixels,0,stride);

        for(i=left;i<=right;i+=2)

        {

            /* 2 pixels to 1 byte */

            index0=getpixel(i,j);

            index1=(i==right)? 0: getpixel(i+1,j);

            pPixels[i/2]=(index0<<4)+index1;

        }

        fwrite(pPixels,1,stride,stream);

    }

    fclose(stream);

}   /* ---------END------------ */_

      首先我们要知道的几个概念:

      bpp:位深度,单位是位/像素(bits per pixel),bpp决定了所能表示的颜色数量。例如bpp=1,则说明图像只有黑白两色(二值图像)。bpp=8,为普通的灰度图像。bpp=24,是最常见的RGB三通道彩色图片。

      stride:扫描行宽度,单位是字节。这是一个在图像数据块(文件或内存中的)中进行定位非常重要的概念,指一行像素占据的内存大小。它必须是4bytes整数倍。因此stride从下面表达式的计算:

      stride=(bm.Width*bpp+31)/32*4;      

      在这里我们必须注意,读取BMP文件时,文件地址是long型(4bytes),即32位的地址,当计算偏移地址时,我们必须把16位的size_t或者int类型首先转化为long型,以免高位地址丢失,导致不能正确定位文件。例如下面这句代码中的类型显示转换是不可缺少的。

       offset=fileHeader.offbits+j*((long)stride);

      由于在TC VGA绘图模式下无法截屏(没有DC),所以通过另存为一个4bpp的bmp图片来做示范。

(24 bpp Win32 bmp)->(TC VGA Graph Mode“截屏”)

  

(请您对文章做出评价)

文档

c语言读取BMP

C语言读取和显示BMP文件(zt)默认分类  2009-09-1914:23  阅读106   评论0 字号:大大 中中 小小C语言读取和显示BMP文件Postedon2008-01-2101:12hoodlum1980阅读(2624)评论(0) 编辑收藏网摘在TC2.0下,隶属于16位子系统,所以int是2字节,long是4字节,char是1字节。绘图系统模式是VGA,颜色当然也很有限,所以读取bmp像素后需要把像素颜色转换为“最近”的已有VGA颜色。用intGetColor(intr,in
推荐度:
  • 热门焦点

最新推荐

猜你喜欢

热门推荐

专题
Top