通过常规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());
示例中为纵向方式合并图片,且需要满足合并的图片宽度相同,且同为32位真彩色。