bitmap生成

通过常规api生成超大位图时,可能会因为一次性分配大量内存空间而导致失败,因此,需要通过文件流的形式,将多个较小的位图,合并成一个大位图。

bitmap文件结构:

    struct BmpInfo
    {
        unsigned short bfType;
        unsigned long bfSize;
        unsigned short bfReserver1;
        unsigned short bfReserver2;
        unsigned long bfOffBits;

        BmpInfo()
        {
            bfType = 0x4D42;
            bfSize = 0;
            bfReserver1 = 0;
            bfReserver2 = 0;
            bfOffBits = 54;
        }
    };

bitmaphead文件结构:

    struct BmpHeadInfo
    {
        unsigned long biSize;
        long biWidth;
        long biHeight;  // pixel height + orientation
        unsigned short biPlanes;
        unsigned short biBitCount;
        unsigned long biCompression;
        unsigned long biSizeImage;
        long biXPelsPerMeter;
        long biYPelsPerMeter;
        unsigned long biClrUsed;
        unsigned long biClrImportant;

        BmpHeadInfo()
        {
            biSize = 40;  // 40字节
            biWidth = 0;
            biHeight = 0;
            biPlanes = 1;
            biBitCount = 32; // 32位真彩
            biCompression = 0;
            biSizeImage = 0;
            biXPelsPerMeter = 0;
            biYPelsPerMeter = 0;
            biClrUsed = 0;
            biClrImportant = 0;
        }
    };

位图合并:

 1     SkBitmap bmp1;
 2     
 3     if(!SkImageDecoder::DecodeFile("d:\\bmp\\red.bmp", &bmp1, SkBitmap::kARGB_8888_Config, SkImageDecoder::kDecodePixels_Mode))
 4     {
 5         return;
 6     }
 7 
 8     SkBitmap bmp2;
 9     if(!SkImageDecoder::DecodeFile("d:\\bmp\\blue.bmp", &bmp2, SkBitmap::kARGB_8888_Config, SkImageDecoder::kDecodePixels_Mode))
10     {
11         return;
12     }
13 
14     int w1, h1, w2,h2;
15     w1 = bmp1.width();
16     h1 = bmp1.height();
17     w2 = bmp2.width();
18     h2 = bmp2.height();
19     SkASSERT(w1 = w2);
20     int w = w1;
21 
22     int h = h1 + h2;
23 
24     long sz = w * h * 4;  // 每像素4字节
25     BmpInfo bmpInfo;
26     bmpInfo.bfSize = sz + bmpInfo.bfOffBits;
27 
28     BmpHeadInfo headinfo;
29     headinfo.biWidth = w;
30     headinfo.biHeight = -h;  // 修改扫描线顺序为从上到下,方便直接追加数据
31     headinfo.biSizeImage = sz;
32 
33     std::ofstream f("d:\\bmp\\test.bmp", std::ios_base::binary);
34 
35     // 文件信息
36     f.write((char*)(&bmpInfo.bfType), sizeof(unsigned short));
37     f.write((char*)(&bmpInfo.bfSize), sizeof(unsigned long));
38     f.write((char*)(&bmpInfo.bfReserver1), sizeof(unsigned short));
39     f.write((char*)(&bmpInfo.bfReserver2), sizeof(unsigned short));
40     f.write((char*)(&bmpInfo.bfOffBits), sizeof(unsigned long));
41 
42     // 文件头信息
43 
44     f.write((char*)(&headinfo.biSize), sizeof(unsigned long));
45     f.write((char*)(&headinfo.biWidth), sizeof(long));
46     f.write((char*)(&headinfo.biHeight), sizeof(long));
47     f.write((char*)(&headinfo.biPlanes), sizeof(unsigned short));
48     f.write((char*)(&headinfo.biBitCount), sizeof(unsigned short));
49     f.write((char*)(&headinfo.biCompression), sizeof(unsigned long));
50     f.write((char*)(&headinfo.biSizeImage), sizeof(unsigned long));
51     f.write((char*)(&headinfo.biXPelsPerMeter), sizeof(long));
52     f.write((char*)(&headinfo.biYPelsPerMeter), sizeof(long));
53     f.write((char*)(&headinfo.biClrUsed), sizeof(unsigned long));
54     f.write((char*)(&headinfo.biClrImportant), sizeof(unsigned long));
55 
56     f.write((char *)(bmp1.getPixels()), bmp1.getSafeSize());
57 
58     f.write((char *)(bmp2.getPixels()), bmp2.getSafeSize());
View Code

示例中为纵向方式合并图片,且需要满足合并的图片宽度相同,且同为32位真彩色。

 

posted @ 2014-12-16 10:26  rain_2012_qf  阅读(185)  评论(0编辑  收藏  举报