• BMP格式图像读取与存储


    全局变量:
    1
    #include "stdafx.h" 2 #include <windows.h> 3 4 /*BMP位图数据是4字节对齐*/ 5 #define WIDTHBYTES(bits) ((DWORD)(((bits)+31) & (~31)) / 8) 6 #define WIDTHBYTES(bits) ((DWORD)((((bits)+31) / 32) * 4) 7 8 unsigned char *gPBmpBuf ; //指向图像数据的指针 9 int gBmpWidth ; //图像的宽 10 int gBmpHeight; //图像的高 11 RGBQUAD *gPColorTable ; //颜色表指针 12 int gBiBitCount; //图像类型,每个像素的位数 13 char bmp[100] = "E:/test_pic.bmp"; 14 char saveBmp[100] = "E:/save_pic.bmp";

    读取bmp文件:

     1 bool loadBmp(char *bmpName)
     2 {
     3     /*以二进制方式打开bmp文件*/
     4     FILE *fp = fopen(bmpName , "rb");
     5     if(NULL == fp)
     6     {
     7         printf("open file "%s" failed 
    " , bmpName);
     8         return false ;
     9     }
    10 
    11     /*跳过bmp文件结构体*/
    12     fseek(fp , sizeof(BITMAPFILEHEADER),0);
    13 
    14     /*读取bmp文件信息头*/
    15     BITMAPINFOHEADER infoHead ; 
    16     fread(&infoHead , sizeof(BITMAPINFOHEADER),1 , fp);
    17 
    18     /*获取图像宽,高,像素位数*/
    19     gBmpWidth  = infoHead.biWidth ; 
    20     gBmpHeight = infoHead.biHeight;
    21     gBiBitCount= infoHead.biBitCount;
    22 
    23     /*获取每行像素所占内存大小(必须为4的倍数)*/
    24     int lineByte = (gBmpWidth*gBiBitCount/8 + 3)/4*4 ;
    25 
    26     /*灰度图像有颜色表,且颜色表表项为256,24-位真彩色图像就不使用彩色板*/
    27     if(8 == gBiBitCount)
    28     {
    29         gPColorTable = (RGBQUAD *)malloc(sizeof(RGBQUAD)*256);
    30         fread(gPColorTable , sizeof(RGBQUAD) , 1  , fp);
    31     }
    32 
    33     /*申请位图数据空间,并将位图数据存放到内存*/
    34     gPBmpBuf = (unsigned char *)malloc(sizeof(unsigned char)*gBmpHeight*lineByte);
    35     fread(gPBmpBuf,1 ,gBmpHeight*lineByte,fp);
    36 
    37     fclose(fp);
    38 
    39     return true ;
    40 }

    保存bmp文件格式:

     1 bool storeBmp(char *bmpName , unsigned char *imgBuf , int width , int height,
     2               int gBiBitCount , RGBQUAD *gPColorTable )
     3 {
     4     /*对位图数据进行判空操作*/
     5     if(NULL == imgBuf)
     6     {
     7         return false ;
     8     }
     9 
    10     /*根据像素位数,判断当前颜色表大小*/
    11     int colorTableSize = 0 ;
    12     if(gBiBitCount == 8)
    13     {
    14         /*
    15            1字节用于蓝色分量
    16            1字节用于绿色分量
    17            1字节用于红色分量
    18            1字节用于填充符(设置为0)
    19          */
    20         colorTableSize = 1024 ; /*4*256*/
    21     }
    22 
    23     /*待存储图像数据每行像素的大小(4的倍数)*/
    24     int lineByte = (gBmpWidth*gBiBitCount/8 + 3)/4*4 ;
    25 
    26     FILE *fp = fopen(bmpName , "wb");
    27     if(NULL == fp)
    28     {
    29         printf("creat file failed !
    ");
    30         return false ;
    31     }
    32 
    33     /*填写位图文件头结构体*/
    34     BITMAPFILEHEADER fileHead ; 
    35     fileHead.bfType = 0x4D42 ; //bmp类型
    36     fileHead.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +
    37                       colorTableSize + lineByte*height ; 
    38     fileHead.bfReserved1 = 0 ;
    39     fileHead.bfReserved2 = 0 ;
    40     fileHead.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +
    41                          colorTableSize ;
    42     fwrite(&fileHead , sizeof(BITMAPFILEHEADER),1 , fp);
    43 
    44     /*填写位图信息结构体*/
    45     BITMAPINFOHEADER infoHead ;
    46     infoHead.biBitCount = gBiBitCount ; 
    47     infoHead.biClrImportant = 0 ;
    48     infoHead.biClrUsed = 0 ;
    49     infoHead.biCompression = 0 ;
    50     infoHead.biHeight = height ;
    51     infoHead.biPlanes = 1 ;
    52     infoHead.biSize = 40 ;
    53     infoHead.biSizeImage = lineByte*height ;
    54     infoHead.biWidth = width ;
    55     infoHead.biXPelsPerMeter = 0 ;
    56     infoHead.biYPelsPerMeter = 0 ;
    57     fwrite(&infoHead , sizeof(BITMAPINFOHEADER),1 , fp);
    58 
    59     /*填写颜色表*/
    60     if(gBiBitCount == 8)
    61     {
    62         fwrite(&gPColorTable , sizeof(RGBQUAD),256 , fp);
    63     }
    64 
    65      /*写位图数据进文件*/
    66     fwrite( imgBuf, height * lineByte, 1, fp );
    67 
    68     fclose(fp);
    69 
    70     return true ; 
    71 }

    main入口测试:

     1 int _tmain(int argc, _TCHAR* argv[])
     2 {
     3     
     4     bool ret = false ;
     5 
     6     ret |= loadBmp(bmp);
     7     ret |= storeBmp(saveBmp,gPBmpBuf,gBmpWidth,gBmpHeight,gBiBitCount,gPColorTable);
     8 
     9     if(false == ret)
    10     {
    11         printf("excut fail! 
    ");
    12     }
    13     else if(true == ret)
    14     {
    15         printf("excut success!
    ");
    16     }
    17     
    18     if(gBiBitCount == 8)
    19     {
    20         free(gPColorTable);
    21     }
    22 
    23     free(gPBmpBuf);
    24     
    25     return 0;
    26 }
  • 相关阅读:
    元类
    多态及多态性和鸭子类型
    类与对象和对应方法、封装
    面向对象与类
    内存管理与正则(re)模块
    Ajax
    Microsoft SQL Server2008安装教程
    兼容所有浏览器的关闭当前页面方法
    如何快速找到指定端口被哪个程序占用并释放该端口(解决bindException)
    MSSQL
  • 原文地址:https://www.cnblogs.com/qiqibaby/p/5237045.html
Copyright © 2020-2023  润新知