精华内容
下载资源
问答
  • 位图和图元文件
    千次阅读
    2019-03-03 19:14:27

    1.位图分为 与设备相关位图(DDB device dependent bitmap)尤其在需要关注性能的程序上使用,与设备无关位图(DIB)它提供了一个用来交换图像的文件格式。

    2.位图是点阵图形,把输出设备当做离散的像素处理;图元文件是矢量图形,把输出设备当做笛卡尔坐标系统,在上面画线填充图形。

    3.位图缺点是:一体积大由宽*高*像素(占多少位)算出字节 ,图元文件大小由gdi命令个数决定,二 与设备相关放大缩小失真,在黑白设备上显示彩色图片,效果会很不好。

    4.位图优点:速度快

    4.位图通常由真实的图像,而图元文件通常则是人们用计算机程序构建的,图元文件包含一系列图形函数调用,由二进制表示。在一个设计良好的绘图程序中可以轻松的抓取特定的图像对象(比如,一条线)并把它移动到某个地方。这是因为图片的所有组件都作为单独的记录存储。这样的操作不可能在一个画图程序中做到的,通常你只能在位图文件中删除或者插入某些图形。

    6.图元文件通过图形绘制命令来描述一个图像,所有这种图像缩放不会损失分辨率。位图则不行,两倍尺寸放大一个位图,你会的到两倍的分辨率,位图中的点不过是在水平和垂直方向上都被复制了一下而已。

    7.一个图元文件可以转化成位图文件,但会丢失一些信息,组成图元文件的多个图形对象不再独立,并被合并成一个图像。位图转化成图元文件要困难得多,通常只有简单的图像才能做到这一点,而且还需要大量的计算处理来分析图像的边缘和轮廓。

    8.尽管图元文件也可以剪切画存储在磁盘上,但最常见的还是被用于在多个程序之间通过剪切板来共享图片。图元文件使用一系列图形函数的调用来描述图片,所以他们占用的空间通常比位图文件少很多,并且他们更加与设备无关。位图只在窗口期间有效。

    9.wmf格式的应用场合

    ---- 由图元文件的特点,可知图元文件与其它格式的图象文件差别很大。

    ---- 首先,由于图元文件是以图象绘制操作序列来存放数据的,因此,它不适合于图象处理领域;其次,由于图元文件的图象显示速度慢,因此也不适合于需要快速显示的场合。

    ---- 但是,微软之所以设计了这种格式,自然有它独特的地方,这就是wmf格式文件所占的磁盘空间比其它任何格式的图形文件都要小得多。也就是说,只要用对场合,只这一条,便可击败所有格式无对手。

    ---- 一般地,图元文件的适用场合如下:

    ---- 1. 由采集数据绘制曲线的图象快速保存。

    ---- 2. 进程间的图象剪切板数据交换。

    更多相关内容
  • 基于MATLAB的Windows位图文件分析算法.pdf
  • 摘要:VC/C++源码,图形处理,像素大小 运行环境:Windows/Visual C/C++
  • 本代码用C++编写,能够读写位图文件(256色,24位)并提取RGB分量大小。没有利用MFC中的接口函数,对于理解BMP文件结构非常有用。
  • 如何在打开对话框中预览图片文件的示例,虽然预览的图像不是太清淅,但至少可以让人看清楚图片的内容是什么,还可显示出图片的宽高像素大小,实际占用字节大小,以及是多少位的真彩位图。 运行环境:Visual Studio...
  • windows位图结构

    2019-05-11 15:14:23
    位图文件应该具有.bmp扩展名。 位图文件格式:BITMAPFILEHEADER(位图文件头)结构,后接BITMAPINFOHEADER、BITMAPV4HEADER或 BITMAPV5HEADER(位图信息头)结构,后接RGBQUAD(颜色表)结构数组,后接Color-index...

    注:关于如何在MFC的图片控件中完整显示位图,请参考另一篇文章:
    https://blog.csdn.net/u014261408/article/details/90109820


    位图文件应该具有.bmp扩展名。

    位图文件格式:BITMAPFILEHEADER(位图文件头)结构,后接BITMAPINFOHEADERBITMAPV4HEADERBITMAPV5HEADER(位图信息头)结构,后接RGBQUAD(颜色表)结构数组,后接Color-index(颜色索引)数组——即实际的位图数据。

    位图格式如下表所示:

    BITMAPFILEHEADER
    BITMAPINFOHEADER
    RGBQUAD array
    Color-index array

    1. BITMAPFILEHEADER结构

    C++:

    typedef struct tagBITMAPFILEHEADER {
      WORD  bfType; //文件类型,必须是BM
      DWORD bfSize; //位图文件大小,单位是字节
      WORD  bfReserved1; //保留字,必须是0
      WORD  bfReserved2; //保留字,必须是0
      DWORD bfOffBits; //从BITMAPFILEHEADER结构第一个字节到实际位图数据的偏移量,单位是字节,
    } BITMAPFILEHEADER, *PBITMAPFILEHEADER;
    

    2. BITMAPINFOHEADERBITMAPV4HEADERBITMAPV5HEADER结构

    • BITMAPINFOHEADER:用于DIB设备无关位图
    • BITMAPV4HEADER:BITMAPINFOHEADER的扩展版本,可以向StretchDIBits函数传递JPEG或PNG图像。
    • BITMAPV5HEADER:BITMAPINFOHEADER的扩展版本

    C++:

    typedef struct tagBITMAPINFOHEADER {
      DWORD biSize; //结构体占有的字节数
      LONG  biWidth; //位图宽度,单位是像素(若是压缩格式,则表示解压缩之后的图片宽度)
      LONG  biHeight; //位图高度,单位是像素(正数表示位图结构是自底向上的, 负数表示
                                  //位图结构是自顶向下的)
      WORD  biPlanes; //The number of planes for the target device,必须设置为1
      WORD  biBitCount; //The number of bits-per-pixel.该值决定了定义每个像素 需要的位数以
                                      //及位图的颜色数,有0,1,4,8,16,24,32
      DWORD biCompression; //拥有自底向上结构的位图的压缩类型(自顶向下不能被压缩)
      DWORD biSizeImage; //图像大小,单位是字节
      LONG  biXPelsPerMeter; //目标设备(target device)的水平分辨率,单位是像素每米
      LONG  biYPelsPerMeter; //垂直分辨率,单位同上
      DWORD biClrUsed; //The number of color indexes in the color table that are actually used by 
                                      //the bitmap.
      DWORD biClrImportant; //显示位图所必须的颜色索引数
    } BITMAPINFOHEADER, *PBITMAPINFOHEADER;
    

    3. RGBQUAD结构

    表示在设备调色板中每一种颜色的RGB强度值

    C++:

    typedef struct tagRGBQUAD {
      BYTE rgbBlue; //颜色中的蓝色分量
      BYTE rgbGreen; //颜色中的绿色分量
      BYTE rgbRed; //颜色中的红色分量
      BYTE rgbReserved; //保留字节,必须为0
    } RGBQUAD;
    

    4. Color-index数组

    该数组为位图中的每一个像素,存储一个对RGBQUAD结构的索引,以此来表现颜色。因此,颜色索引数组具有的总位数(即占有的存储空间),等于位图的像素数乘以RGBQUAD结构的索引数。比如,一个8*8的黑白位图,其颜色数组共8*8*1=64位,因为1位即可索引黑白两种颜色。再比如,16色的32*32位图Redbrick.bmp,其颜色数组共32*32*4=4096位,因为4位可以索引16种颜色(2^4=16)。

    如果位图结构是自顶向下的(a top-down bitmap),颜色索引数组,即实际的位图数据,从位图的第一行开始编码。根据颜色索引数组的前n位表示的数字d,就可取得第一行最左面像素的颜色——在RGBQUAD结构中编号为d的颜色(n就是可以表示RGBQUAD结构中所有索引的二进制位数)。在索引到这一行最右面的元素时,从下一行最左面的元素继续进行索引,直到位图结束。如果是自底向上(a bottom-up bitmap)的位图,从位图的最下面一行开始,仍然从左到右,依次往上。

    注:本文参考MSDN——Bitmap Storage。

    展开全文
  • EXE/DLL文件中的资源(位图、图标、字符串等)查看器。以及版本信息等。代码较老,是VC6的项目工程,不过还是可用的,值得参考
  • 既然是图解,此处省去介绍....直接上图 以下代码中SetPixel()为在屏幕中打点的函数,在单片机中由自己实现, ...(pmybmp指向bmp文件的数组) //windows下加入缓冲提高速度 HDC hdc=GetDC(hWnd);//seco...

    既然是图解,此处省去介绍....直接上图

    以下代码中SetPixel()为在屏幕中打点的函数,在单片机中由自己实现,

    根据不同的位深来解析,都是根据以上图片方式,推导出来的算法.

    并没有实现压缩算法,图像高度为负的情况,并且未优化,图像较大时速度慢

    (pmybmp指向bmp文件的数组)

     

    //windows下加入缓冲提高速度

    HDC hdc=GetDC(hWnd);//second method
    HDC hmdc = CreateCompatibleDC(hdc);
    HBITMAP hbmp = CreateCompatibleBitmap(hdc, bminfohdr.biWidth, bminfohdr.biHeight);
    SelectObject(hmdc, hbmp);

     

     

     

     

     

            char *pmybmp = (char*)BMP_WAVE;
            BITMAPFILEHEADER bmfilehdr;
            BITMAPINFOHEADER bminfohdr; 
    
            memcpy(&bmfilehdr, &pmybmp[0], sizeof(BITMAPFILEHEADER));//14
            memcpy(&bminfohdr, &pmybmp[14], sizeof(BITMAPINFOHEADER));//40
            printf("\n..............................\n");
            printf("\nsizeof(BITMAPFILEHEADER)=%d\n", sizeof(BITMAPFILEHEADER));
            printf("bmfilehdr.bfType=%#02x\n", bmfilehdr.bfType);
            printf("bmfilehdr.bfSize=%#04x,bmp文件大小:%d字节\n", bmfilehdr.bfSize, bmfilehdr.bfSize);
            printf("bmfilehdr.bfOffBits=%#04x (到RGBQUAD偏移字节)\n", bmfilehdr.bfOffBits);
            printf("sizeof(BITMAPINFOHEADER)=%d\n", sizeof(BITMAPINFOHEADER));
            printf("bminfohdr.biSize=%#04x  ( 结构体BITMAPINFOHEADER大小,=sizeof(BITMAPINFOHEADER) )\n", bminfohdr.biSize);
            printf("bminfohdr.biWidth=%#04x  (位图宽:%dpixels)\n", bminfohdr.biWidth, bminfohdr.biWidth);
            printf("bminfohdr.biHeight=%#04x  (位图高:%dpixels)\n", bminfohdr.biHeight, bminfohdr.biHeight);
            printf("bminfohdr.biPlanes=%#02x  (平面数)\n", bminfohdr.biPlanes);
            printf("bminfohdr.biBitCount=%#02x  (%d位深,1:单色,4:16色,8:256色,16:高彩色,24:真彩色,32:增强真彩色)\n", bminfohdr.biBitCount, bminfohdr.biBitCount);
            printf("bminfohdr.biCompression=%d  (压缩算法:0:BI_RGB,1:BI_RLE8,2:BI_RLE4,3:BI_BITFIELEDS,4:BI_JPEG,5:BI_PNG)\n", bminfohdr.biCompression);
            printf("bminfohdr.biSizeImage=%d  (位图缓冲,BI_RGB常为0)\n", bminfohdr.biSizeImage);
            printf("bminfohdr.biXPelsPerMeter=%d  (水平分辨率,pixels/meter)\n", bminfohdr.biXPelsPerMeter);
            printf("bminfohdr.biYPelsPerMeter=%d  (垂直分辨率,pixels/meter)\n", bminfohdr.biYPelsPerMeter);
            printf("bminfohdr.biClrUsed=%d  (位深为1~8时,用于指定调用板用到的颜色数,0表示全部都用到)\n", bminfohdr.biClrUsed);
            printf("bminfohdr.biClrImportant=%d  (0表示所有色彩都重要)\n", bminfohdr.biClrImportant);
      
               switch (bminfohdr.biBitCount)//位深,bpp,bit per pixel
               {
                   //色彩位数
               case 32://0x20,增强真彩色,RGBA	///bminfohdr.biCompression == BI_RGB ||bminfohdr.biCompression ==BI_BITFIELDS
               {
    
                   for (long h = 0; h < bminfohdr.biHeight; h++)
                   {
                       for (long w = 0; w < bminfohdr.biWidth; w++)
                       {
                           unsigned long idxRGB = bmfilehdr.bfOffBits + w*bminfohdr.biBitCount / 8 + (bminfohdr.biWidth*bminfohdr.biBitCount / 8)*h;
                           //由索引到调色板,0XBB,0XGG,0XGG  //bmfilehdr.bfOffBits指向 调色板 的开头
                           RGBQUAD *pixelclr = (RGBQUAD*)&pmybmp[idxRGB];
                           SetPixel(hmdc, w, bminfohdr.biHeight - h - 1, RGB(pixelclr->rgbRed, pixelclr->rgbGreen, pixelclr->rgbBlue)); // bminfohdr.biHeight>0,图像上下倒置,所以要bminfohdr.biHeight - h
                       }
    
                   }
    
               }
    
               break;
    
               case 24://24bit/pixel,0x18,真彩色,16777216色
               {
                   long pad0 = (4 - bminfohdr.biBitCount / 8 * bminfohdr.biWidth % 4) % 4;//补0字节数,bitcount 为位数要除以8!!!
                   for (long h = 0; h < bminfohdr.biHeight; h++)
                   {
                       for (long w = 0; w < bminfohdr.biWidth; w++)
                       {
                           unsigned long idxRGB = bmfilehdr.bfOffBits + w*bminfohdr.biBitCount / 8 + (bminfohdr.biWidth*bminfohdr.biBitCount / 8 + pad0)*h;
                           //由索引到调色板,0XBB,0XGG,0XGG  //bmfilehdr.bfOffBits指向 调色板 的开头
                           RGBTRIPLE *pixelclr = (RGBTRIPLE*)&pmybmp[idxRGB];
                           // printf("index:%d,RGB(%d,%d,%d)\n", idxRGB, pixelclr->rgbtRed, pixelclr->rgbtGreen, pixelclr->rgbtBlue);
                           SetPixel(hmdc, w, bminfohdr.biHeight - h - 1, RGB(pixelclr->rgbtRed, pixelclr->rgbtGreen, pixelclr->rgbtBlue)); // bminfohdr.biHeight>0,图像上下倒置,所以要bminfohdr.biHeight - h
                       }
    
                   }
              }
    
               break;
    
               case 16://0x10,高彩色,65536色,RGB565,RGB444,RGB555
                   switch (bminfohdr.biSize)
                   {
                   case 0x28://X1RGB555,最高位空
                   {
                       int pad0 = 32 - bminfohdr.biBitCount*bminfohdr.biWidth % 32;
                       for (long h = 0; h < bminfohdr.biHeight; h++)
                       {
                           for (long w = 0; w < bminfohdr.biWidth; w++)
                           {
                               unsigned long idxRGB = bmfilehdr.bfOffBits + w*bminfohdr.biBitCount / 8 + (bminfohdr.biWidth*bminfohdr.biBitCount + pad0)*h / 8;
                               //由索引到调色板,0XBB,0XGG,0XGG  //bmfilehdr.bfOffBits指向 调色板 的开头
                               USHORT color = *(USHORT*)&pmybmp[idxRGB];
                               RGBTRIPLE pixelclr;
                               pixelclr.rgbtRed = ((0x7c00 & color) >> 7);//RED:D6D5D4D3D2,即每个分量只有5位,靠MSB位置处放
                               pixelclr.rgbtGreen = ((0x03e0 & color) >> 2);//GREEN:D6D5D4D3D2
                               pixelclr.rgbtBlue = ((0x001f & color) << 3);//BLUE:D6D5D4D3D2
                               SetPixel(hmdc, w, bminfohdr.biHeight - h - 1, RGB(pixelclr.rgbtRed, pixelclr.rgbtGreen, pixelclr.rgbtBlue)); // bminfohdr.biHeight>0,图像上下倒置,所以要bminfohdr.biHeight - h
                           }
    
                       }
                   }
    
                   break;
                   case 0x38://根据掩膜来取RGB,X4RGB444,RGB565
                   {
                       if (bminfohdr.biCompression == BI_BITFIELDS)
                       {
                           struct CLRMASK
                           {
                               DWORD RedMask, GreenMask, BlueMask, AlphaMask;
                           };
                           int rr = 0, rg = 0, rb = 0;
                           CLRMASK *clr = (CLRMASK*)&pmybmp[icolor_table];
                           //printf("icolor_table:%02X,RGBA_MASK:%04x,%04x,%04x,%04x\n", icolor_table, clr->RedMask, clr->GreenMask, clr->BlueMask, clr->AlphaMask);
    
                           int pad0 = (32 - bminfohdr.biBitCount*bminfohdr.biWidth % 32) % 32;
                           //cmd.puts("...............,.............\n");
                           if (clr->RedMask == 0xf800 && clr->GreenMask == 0x07e0 && clr->BlueMask == 0x001f) { rr = 8; rg = 3; rb = 3; }
                           else if (clr->RedMask == 0x0f00 && clr->GreenMask == 0x00f0 && clr->BlueMask == 0x000f) { rr = 4; rg = 0; rb = 4; }
                           for (long h = 0; h < bminfohdr.biHeight; h++)
                           {
                               for (long w = 0; w < bminfohdr.biWidth; w++)
                               {
                                   unsigned long idxRGB = bmfilehdr.bfOffBits + w*bminfohdr.biBitCount / 8 + (bminfohdr.biWidth*bminfohdr.biBitCount + pad0)*h / 8;
                                   //由索引到调色板,0XBB,0XGG,0XGG  //bmfilehdr.bfOffBits指向 调色板 的开头
                                   USHORT color = *(USHORT*)&pmybmp[idxRGB];
                                   RGBTRIPLE pixelclr;
                                   pixelclr.rgbtRed = (BYTE)((clr->RedMask & color) >> rr);//RED:D6D5D4D3D2,即每个分量只有5位,靠MSB位置处放
                                   pixelclr.rgbtGreen = (BYTE)((clr->GreenMask & color) >> rg);//GREEN:D6D5D4D3D2
                                   pixelclr.rgbtBlue = (BYTE)((clr->BlueMask & color) << rb);//BLUE:D6D5D4D3D2
                                   SetPixel(hmdc, w, bminfohdr.biHeight - h - 1, RGB(pixelclr.rgbtRed, pixelclr.rgbtGreen, pixelclr.rgbtBlue)); // bminfohdr.biHeight>0,图像上下倒置,所以要bminfohdr.biHeight - h
                               }
    
                           }
                       }
    
    
                   }
                   break;
                   }
                   break;
    
               case 8://8bit/pixel,256色
               {
                   long pad0 = (4 - bminfohdr.biBitCount * bminfohdr.biWidth / 8 % 4) % 4;//补0字节数
                   //if (pad0 == 4) pad0 = 0;
                   for (long h = 0; h < bminfohdr.biHeight; h++)
                   {
                       for (long w = 0; w < bminfohdr.biWidth + pad0; w++)
                       {
                           //位图颜色数据索引
                           unsigned long	ibmoffset = w + (bminfohdr.biWidth + pad0) * h;
                           unsigned char	 iclrtbl = pmybmp[bmfilehdr.bfOffBits + ibmoffset];
                           //由索引到调色板,0XBB,0XGG,0XGG,0XAA  //icolor_table指向 调色板 的开头
                           RGBQUAD *pixelclr = (RGBQUAD*)&pmybmp[icolor_table + iclrtbl * 4];
                           SetPixel(hmdc, w, bminfohdr.biHeight - h - 1, RGB(pixelclr->rgbRed, pixelclr->rgbGreen, pixelclr->rgbBlue)); // bminfohdr.biHeight>0,图像上下倒置,所以要bminfohdr.biHeight - h
                       }
    
                   }
                   //	printf("FINISHED\n");
               }
               break;
    
               case 4: //4bit/pixel,16色位图
                    //	bminfohdr.biCompression
               {
                   int pad0 = (32 - bminfohdr.biBitCount*bminfohdr.biWidth % 32) % 32;
                   for (long h = 0; h < bminfohdr.biHeight; h++)
                   {
                       for (long w = 0; w < bminfohdr.biWidth; w++)
                       {
                           //索引,4位的索引,即半字节索引
                           unsigned long	ibmoffset = bmfilehdr.bfOffBits + w / 2 + (bminfohdr.biBitCount*bminfohdr.biWidth + pad0) / 8 * h;
                           unsigned char	 iclrtbl = (pmybmp[ibmoffset] >> ((1 - (w & 0x1)) * 4)) & 0x0f;
                           //由索引到调色板,0XBB,0XGG,0XGG,0XAA 
                           //icolor_table指向 调色板 的开头
                           RGBQUAD *pixelclr = (RGBQUAD*)&pmybmp[icolor_table + iclrtbl * 4];
                           SetPixel(hmdc, w, bminfohdr.biHeight - h - 1, RGB(pixelclr->rgbRed, pixelclr->rgbGreen, pixelclr->rgbBlue)); // bminfohdr.biHeight>0,图像上下倒置,所以要bminfohdr.biHeight - h
                       }
                   }
               }
               break;
    
               case 1://单色,一般为黑白,1=白,0=黑,但其实两是两种可定义的颜色,即双色位图 
               {
                   int pad0 = (32 - bminfohdr.biBitCount*bminfohdr.biWidth % 32) % 32;
                   for (long h = 0; h < bminfohdr.biHeight; h++)
                   {
                       for (long w = 0; w < bminfohdr.biWidth; w++)
                       {
                           long idx = (w + h*(bminfohdr.biWidth + pad0)) / 8;
                           unsigned char  mask = (1 << (7 - w % 8));
                           unsigned char dat = pmybmp[bmfilehdr.bfOffBits + idx];
    
                           SetPixel(hmdc, w, bminfohdr.biHeight - h - 1, (dat & mask) ? RGB(255, 255, 255) : RGB(0, 0, 0)); // bminfohdr.biHeight>0,图像上下倒置,所以要bminfohdr.biHeight - h
                       }
                   }
               }
               break;
             }

      

    //windows下加入缓冲提高速度      
    BitBlt(hdc,1,1,bminfohdr.biWidth,bminfohdr.biHeight, hmdc, 0, 0, SRCCOPY);
    DeleteObject(hbmp);
    DeleteDC(hmdc);
    ReleaseDC(hWnd,hdc);


    补充:在WINDOWS上可以用一条语句代替以上代码,速度非常之快,超乎想象,不知道WINDOWS内部是怎么实现的    
     SetDIBitsToDevice(hdc, 0, 0, bminfohdr.biWidth, bminfohdr.biHeight, 0, 0, 0, bminfohdr.biHeight, (pmybmp+ bmfilehdr.bfOffBits), (BITMAPINFO*)&pmybmp[14], DIB_RGB_COLORS); 
    //lpvBits :Pointer to DIB color data stored as an array of bytes.
    //BITMAPFILEHEADER.bfOffBits:Specifies the offset, in bytes, from the BITMAPFILEHEADER structure to the bitmap bits

     

    展开全文
  • Windows位图文件格式

    2011-06-21 15:40:00
    Windows位图文件格式 位图概述位图格式位图文件头结构包含关于类型,大小以及与设备无关的文件层。typedef struct tagBITMAPFILEHEADER { WORD bfType; DWORD bfSize; WORD bfReserved1; WORD bfReserved2; ...

    Windows位图文件格式

     

    位图概述

    位图格式
    位图文件头
    结构包含关于类型,大小以及与设备无关的文件层。
    typedef struct tagBITMAPFILEHEADER {
      WORD bfType; 
      DWORD bfSize; 
      WORD bfReserved1; 
      WORD bfReserved2; 
      DWORD bfOffBits; 
    } BITMAPFILEHEADER;

    typedef struct tagBITMAPINFOHEADER { 
      DWORD biSize;                        // 大小
      LONG biWidth;                        // 宽度
      LONG biHeight;                       // 高度
      WORD biPlanes;                       // 平面?
      WORD biBitCount                      // 为个数
      DWORD biCompression;                 // 压缩
      DWORD biSizeImage;                   // 图像大小
      LONG biXPelsPerMeter;                // 每公尺X上的像素
      LONG biYPelsPerMeter;                // 每公尺Y上的像素
      DWORD biClrUsed;                     // ???
      DWORD biClrImportant;                // ???
    } BITMAPINFOHEADER; 
    位图信息头

    该结构体包含关于与颜色格式相关的设备无关位图。

    指定的颜色表内的颜色索引,该索引是在位土内被使用的。如果这个值是零。
    如果biClrUsed是非零值且biBitCount值小于16, biClrUsed成员指定实际图形引擎或设备驱动的存取值。
    biClrImportant被指定的颜色索引必须显示在位图上。
    如果颜色值是零,所有颜色是必须的。

     

     

    目录

    位图格式分析

    一.位图文件存储格式

    二.BitmapFileHeader

    三.BitmapInfo

    四.BitmapInfoHeader

    五.BitmapData

    六.保存位图为文件

    1. 错误信息函数

    2. 建立位图信息结构体函数

    3. 建立位图文件函数

    4. 保存位图到文件函数

    七.从文件加载位图

    1.错误信息函数

    2. 从位图文件加载图象函数

     

    一.位图文件存储格式

    位图文件存储格式请参考图1.1。

     

    图1.1 位图文件存储格式

    图说明请参考表1.1。

    表1.1 位图文件存储格式说明

    结构体

    说明

    BitmapFileHeader

    位图文件信息头

    BitmapInfo

    位图信息,由以下两个结构体组成

    BitmapInfoHeader

    位图信息头

    RGBQUAD

    颜色表

    BitmapData

    位图数据

    二.BitmapFileHeader

    typedef struct tagBITMAPFILEHEADER { // bmfh

        WORD    bfType;

        DWORD   bfSize;

        WORD    bfReserved1;

        WORD    bfReserved2;

        DWORD   bfOffBits;

    } BITMAPFILEHEADER;

    bfType:文件类型,0x4d42,也就是BM

    bfSize:文件大小,计算方法是
    位图文件头大小【sizeof(BITMAPFILEHEADER)】
    +位图信息头大小【pbih->biSize】
    +颜色表大小【pbih->biClrUsed*sizeof(RGBQUAD)】
    +位图数据大小【pbih->biSizeImage】

    bfReserved1:预留字段,为0。

    bfReserved2:预留字段,为0。

    bfOffBits:图象数据的偏移量,计算方法是
    位图文件头大小【sizeof(BITMAPFILEHEADER)】
    +位图信息头大小【pbih->biSize】
    +颜色表大小【pbih->biClrUsed*sizeof(RGBQUAD)】

     

    三.BitmapInfo

    typedef struct tagBITMAPINFO { // bmi

        BITMAPINFOHEADER bmiHeader;

        RGBQUAD          bmiColors[1];

    } BITMAPINFO;

    bmiHeader:位图信息头,见下节的结构体说明。

    bmiColors:RGB颜色表数组。一般不存储到位图,在GetDIBits时将丢失这个信息,biClrUsed将被设置为0。

     

    四.BitmapInfoHeader

    typedef struct tagBITMAPINFOHEADER{ // bmih

        DWORD biSize;

        LONG   biWidth;

        LONG   biHeight;

        WORD   biPlanes;

        WORD   biBitCount

        DWORD biCompression;

       DWORD biSizeImage;

        LONG   biXPelsPerMeter;

        LONG   biYPelsPerMeter;

        DWORD biClrUsed;

        DWORD biClrImportant;

    } BITMAPINFOHEADER;

    biSize:结构体大小。

    biWidth:位图宽度,象素。对应位图宽度,bmp.bmWidth。

    biHeight:位图高度,象素。对应位图高度,bmp.bmHeight。

    biPlanes:调色板数目,一般是1。对应位图调色板数目,bmp.bmPlanes。

    biBitCount:颜色位数。对应位图bmp.bmBitsPixel。

    biClrUsed:使用的颜色数,在24位以下时需要使用,计算方法
    if(cClrBits < 24) pbmi->bmiHeader.biClrUsed=(1<<cClrBits);

    biSizeImage:图象数据大小,计算方法
    位图宽度象素数目转换成字节【(pbmi->bmiHeader.biWidth+7)/8】
    *位图高度象素数目【pbmi->bmiHeader.biHeight】
    *象素位数【cClrBits】

    注:宽度象素数目+7再除以8,用来处理余数的情况,如位图宽度为2,除以8为0,所以要+7再除以8。

    五.BitmapData

    24位位图图象数据的存储是RGB序列,在windows中是BGR序列:

    象素B蓝色分量值

    象素G绿色分量值

    象素R红色分量值

    32位位图象素数据的存储是RGBA序列,A是Alpha值,windows是BGRA序列:

    象素B蓝色分量值

    象素G绿色分量值

    象素R红色分量值

    象素alpha分量值

    16位图象的分布是:

    最高位保留,为0

    高5位,红色分量

    中间5位,绿色分量

    最低5位,蓝色分量

     

    六.保存位图为文件

    可以将程序中的图象保存为文件,具体代码如下:

    1. 错误信息函数

    //错误信息

    void exitWND(LPCTSTR msg)

    {

         MessageBox(NULL,msg,"Error",0);

         exit(0);

    }

    2. 建立位图信息结构体函数

    //建立位图信息结构体

    PBITMAPINFO CreateBitmapInfoStruct(HBITMAP hBmp)

    {

         BITMAP bmp;

         if(!GetObject(hBmp,sizeof(BITMAP),&bmp))

             exitWND("Error when get object from hbitmap");

         //获取颜色位数

         WORD cClrBits;

         cClrBits=(WORD)(bmp.bmPlanes*bmp.bmBitsPixel);

         if(cClrBits == 1)

             cClrBits=1;

         else if(cClrBits <= 4)

             cClrBits=4;

         else if(cClrBits <= 8)

             cClrBits=8;

         else if(cClrBits <= 16)

             cClrBits=16;

         else if(cClrBits <= 24)

             cClrBits=24;

         else cClrBits=32;

         //分配位图信息结构体

         PBITMAPINFO pbmi;

         if(cClrBits != 24)

             pbmi=(PBITMAPINFO)

             LocalAlloc(LPTR,sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*(1<<cClrBits));

         else

             pbmi=(PBITMAPINFO)

             LocalAlloc(LPTR,sizeof(BITMAPINFOHEADER));                           

         //初始化位图结构体

         pbmi->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);

         pbmi->bmiHeader.biWidth=bmp.bmWidth;

         pbmi->bmiHeader.biHeight=bmp.bmHeight;

         pbmi->bmiHeader.biPlanes=bmp.bmPlanes;

         pbmi->bmiHeader.biBitCount=bmp.bmBitsPixel;

         if(cClrBits < 24)

             pbmi->bmiHeader.biClrUsed=(1<<cClrBits);

         //不压缩位图

         pbmi->bmiHeader.biCompression=BI_RGB;

         //初始化图象数据大小

         pbmi->bmiHeader.biSizeImage=

             (pbmi->bmiHeader.biWidth+7)/8

             *pbmi->bmiHeader.biHeight

             *cClrBits;

         //所有的设备颜色都重要

         pbmi->bmiHeader.biClrImportant=0;

         //返回指针

         return pbmi;

    }

    3. 建立位图文件函数

    //建立位图文件

    void CreateBMPFile(LPTSTR pszFile,PBITMAPINFO pbi,HBITMAP hBmp,HDC hDC)

    {

         PBITMAPINFOHEADER pbih=(PBITMAPINFOHEADER)pbi;

         LPBYTE lpBits;

         lpBits=(LPBYTE)GlobalAlloc(GMEM_FIXED,pbih->biSizeImage);

         if(!lpBits)

             exitWND("error to global alloc memory");

         //获取位图图象数据

         GetDIBits(hDC,hBmp,0,(WORD)pbih->biHeight,lpBits,pbi,DIB_RGB_COLORS);

         //建立位图文件

         HANDLE hf;

         hf=CreateFile(pszFile,GENERIC_READ|GENERIC_WRITE,

             NULL,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);

         if(hf == INVALID_HANDLE_VALUE)

             exitWND("error to create file");

         //建立位图文件信息头

         BITMAPFILEHEADER hdr;

         hdr.bfType=0x4d42;

         hdr.bfSize=(DWORD)(sizeof(BITMAPFILEHEADER)+

             pbih->biSize+pbih->biClrUsed*sizeof(RGBQUAD)+

             pbih->biSizeImage);

         hdr.bfReserved1=0;

         hdr.bfReserved2=0;

         //计算位图数据偏移量

         hdr.bfOffBits=(DWORD)sizeof(BITMAPFILEHEADER)+

             pbih->biSize+pbih->biClrUsed*sizeof(RGBQUAD);

         //写入位图文件头

         DWORD wt;

         if(!WriteFile(hf,(LPVOID)&hdr,sizeof(BITMAPFILEHEADER),&wt,NULL))

             exitWND("error when write bitmap file header");

         //写入位图信息头

         if(!WriteFile(hf,(LPVOID)pbih,

             sizeof(BITMAPINFOHEADER)+pbih->biClrUsed*sizeof(RGBQUAD),

             &wt,NULL))

             exitWND("error when write bitmap info header and RGBquad");

         //写入位图数据

         if(!WriteFile(hf,(LPVOID)lpBits,pbih->biSizeImage,&wt,NULL))

             exitWND("error when write data");

         //关闭文件

         if(!CloseHandle(hf))

             exitWND("error when close file handle");

         //释放图象数据所占内存

         GlobalFree(lpBits);

    }

    4. 保存位图到文件函数

    //保存位图到文件

    void SaveBitmapFile(LPTSTR fileName,HWND hWnd,HBITMAP bmp)

    {

         PBITMAPINFO pbmi;

         pbmi=CreateBitmapInfoStruct(bmp);

         HDC hdc;

         hdc=GetDC(hWnd);

         CreateBMPFile(fileName,pbmi,bmp,hdc);

         ReleaseDC(hWnd,hdc);

    }

     

    七.从文件加载位图

    从文件加载位图,用ReadFile定位文件需要使用OVERLAPPED,展开位图到DC使用StretchDIBits函数。代码如下:

    1.错误信息函数

    //错误信息

    void exitWND(LPCTSTR msg)

    {

         MessageBox(NULL,msg,"Error",0);

         exit(0);

    }

    2. 从位图文件加载图象函数

    //从位图文件加载图象

    HBITMAP LoadBitmapFile(LPCTSTR fileName,HWND hWnd)

    {

         //打开文件

         HANDLE hf;

         hf=CreateFile(fileName,GENERIC_READ,FILE_SHARE_READ,

             NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);

         if(hf == INVALID_HANDLE_VALUE){

             exitWND("error when open file handle");

             return 0x00;

         }

         //展开位图文件到DC

         DWORD read;

         //读取文件信息头

         BITMAPFILEHEADER bfh;

         OVERLAPPED olbfh;

         memset(&olbfh,0,sizeof(OVERLAPPED));

         olbfh.Offset=0;

         ReadFile(hf,&bfh,sizeof(bfh),&read,&olbfh);

         //读取位图信息

         BITMAPINFO bi;

         OVERLAPPED olbi;

         memset(&olbi,0,sizeof(OVERLAPPED));

         olbi.Offset=sizeof(BITMAPFILEHEADER);

         ReadFile(hf,&bi.bmiHeader,sizeof(bi.bmiHeader),&read,&olbi);

         //读取位图数据

         LPBYTE lpBits;

         lpBits=(LPBYTE)GlobalAlloc(GMEM_FIXED,bi.bmiHeader.biSizeImage);

         OVERLAPPED ollpbits;

         memset(&ollpbits,0,sizeof(OVERLAPPED));

         ollpbits.Offset=bfh.bfOffBits;

         ReadFile(hf,lpBits,bi.bmiHeader.biSizeImage,&read,&ollpbits);

         //建立和窗口关联的DC

         HDC hdc;

         hdc=GetDC(hWnd);

         HDC mem;

         mem=CreateCompatibleDC(hdc);

         //建立和DC关联的位图

         HBITMAP bmp;

         bmp=CreateCompatibleBitmap(hdc,bi.bmiHeader.biWidth,bi.bmiHeader.biHeight);

         SelectObject(mem,bmp);

         //在DC中展开

         StretchDIBits(mem,

             0,0,bi.bmiHeader.biWidth,bi.bmiHeader.biHeight,

             0,0,bi.bmiHeader.biWidth,bi.bmiHeader.biHeight,

             (LPVOID)lpBits,&bi,DIB_RGB_COLORS,SRCCOPY);

         //清理工作

         GlobalFree(lpBits);

         DeleteDC(mem);

         ReleaseDC(hWnd,hdc);

         CloseHandle(hf);

         //返回位图对象

         return bmp;

    }


    展开全文
  • windows 位图结构详解

    2015-05-22 10:28:06
    位图文件可看成由4个部分组成:位图文件头(bitmap-file header)、位图信息头(bitmap-information header)、彩色表(color table)和定义位图的字节阵列,它具有如下所示的形式。 位图文件的组成 ...
  • 画图是每一个windows系统中都有的程序,虽然这个程序一直没有添加很多新的功能,但是基础功能...无效的位图文件或不支持文件的格式。出现这样的错误提示时我们可以使用下面的这个方法进行修复!方法步骤:1、打开电...
  • Font Whiz 是一个开源的固定宽度位图字体生成器,适用于 Linux、Windows 和 Mac。 它可以使用已安装的字体或文件中的字体。 创建此工具是为了将字体输出到图像,以便在游戏开发中进行快速渲染。
  • VC++实现带位图预览的打开文件对话框,现在Windows系统还在用的效果,这是仿的,只帖出具体的实现代码。有需要的可下载本代码文件。 运行环境:Windows/Visual C/C++
  • 软件介绍 而且字体可使用在windows或电子设备中(手机、DVD播放机、LCD等),软件支持导入你的Windows电脑中的所有安装字体,同时内建一个C文件字体集,包含跳表和位图数据的所有字符。 BitFon
  •  BMP(全称Bitmap)是Windows操作系统中的标准图像文件格式,可以分成两类:设备相关位图(DDB)和设备无关位图(DIB),使用非常广。它采用位映射存储格式,除了图像深度可选以外,不采用其他任何压缩,因此,BMP...
  • Windows Phone 8中的库渲染位图字体使用手册: 第1步:将具有相同名称和位置的fnt和png文件放入您的项目中(例如:Assets / BitmapFont) 第2步:加载字体(在启动应用程序时应执行):使用静态变量存储字体并在启动...
  • 西电C语言程序设计实验之位图图像文件缩放

    千次阅读 多人点赞 2021-05-28 16:07:20
    位图图像文件缩放 编写一个程序,可以在命令行输入参数,完成指定文件的缩放,并存储到新文件,命令行参数如下: zoom file1.bmp 200 file2.bmp 第一个参数为可执行程序名称,第二个参数为原始图像文件名,第三个...
  • GDI+ 保存HDC为位图文件

    千次阅读 2020-08-07 16:21:42
    //GDI+为图片的加载、存储,屏蔽了内部编解码、压缩解压缩等的具体细节,给程序员带来了极大的方便 //目前版本的GDI+支持bmp jpeg gif tiff png等几...//使用GDI+ 保存HDC为位图文件 #include <rpc.h> #in...
  • Windows位图,Bitmap,位图文件结构,图像处理 网上找到的一个文件,感觉不错。 涉及到了Windows位图的各种处理,还有一些基本的图形算法。 感觉以后可能会用到,所以就传上来了。
  • 位图(bmp)文件格式分析

    万次阅读 多人点赞 2018-05-29 19:18:24
    位图(bmp)文件格式分析 作者:深蓝(由博主分享) 一、什么是位图 计算机能以位图和矢量图格式显示图像。 1、位图(Bitmap): 图像又称点阵图或光栅图,它使用我们称为像素(象素,Pixel)的一格一格的小点来描述...
  • Windows 位图

    千次阅读 2016-12-12 14:45:11
    目 录 第1章 简介 1 1.1 DFB 1 1.2 DDB 1 1.3 DIB 2 第2章 相关API 3 ... 2.1 创建 3 2.1.1 CreateCompatibleBitmap 3 2.1.2 CreateBitmap 3 2.1.3 Cre
  • BMP位图文件默认的文件扩展名是.BMP,有时它也会以.DIB或.RLE作扩展名。BMP格式的图片,没有使用任何压缩算法,这种方式在以前使用的比较多,现在用的就比较少了,不过为了学习图像处理算法,所以先以该种格式的文
  • 它使您可以同时使用位图和矢量图形来创建传统的手绘动画(卡通)。 Pencil2D是免费的开放源代码。 Pencil2D网站: ://www.pencil2d.org/ 下载 Pencil2D 0.6.5(2020年7月31日) 视窗 苹果 Linux 每晚构建 每晚...
  • 本来是打算弄个BadApple玩玩,不过不满足于简单地读取文本文件并输出,所以最后变成了研究如何用C语言读取位图文件并通过二维数组来存储像素信息。 第一步自然是弄清楚bmp的文件格式。在各种位图格式中,bmp因为...
  • 易语言BmpOperate.fnr,BmpOperate.fne支持库中文名为易语言位图操作支持库,该易语言支持库实现了对位图(*.bmp)文件数据的操作。 易语言BmpOperate.fnr,BmpOperate.fne支持库为一般支持库,需要易语言系统3.8版本...
  • 位图文件, JPG格式,PNG格式

    千次阅读 2015-07-23 09:49:54
    位图文件Windows标准格式图形文件,它将图像定义为由点(像素)组成,每个点可以由多种色彩表示,包括2、4、8、16、24和32位色彩。例如,一幅1024×768分辨率的32位真彩图片,其所占存储字节数为:1024×768×32/8...
  • 位图文件结构

    千次阅读 2012-11-27 20:33:52
    一、位图文件结构 1.位图文件头 2.位图信息 2.1位图信息头 2.2 颜色表 2.位图数据 二、位图文件读写操作 1.类的声明 2.位图的读取 3.位图读取过程中的调色板的创建和调用 4.位图的显示 5.位图的存储 6....
  • 位图文件(Bitmap)

    千次阅读 2014-06-15 00:47:49
    位图文件(Bitmap),扩展名可以是。bmp或者。dib。位图是Windows标准格式图形文件,它将图像定义为由点(像素)组成,每个点可以由多种色彩表示,包括2、4、8、16、24和32位色彩。例如,一幅1024×768分辨率的32位...
  • 希望前辈们能给个demo程序。或者最基本的窗口上加载一个位图图片就好,加载位图时用的LoadImage 初学windows编程,不太懂上下文设备,希望大神能给个例程,让我学习。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 42,186
精华内容 16,874
关键字:

windows如何创建位图文件