6

我有字节数组,其中每三个字节描述 1 个像素(RGB)。任务是将其转换为 jpeg 或 png。

实际上,我正在使用 Zint(用于生成条形码的开源库),它使用 libpng 生成图像文件并将其保存到文件系统,但在 Zint 中,除了生成图像之外的函数 png_plot() 还将其保存在磁盘上,这是不可取的。

结果我认为有两种方法:
1.从位图字节数组到bmp-> jpeg / png(使用其他一些lib)
2.编写钩子或类似于png_plot()

你能给我一些建议吗?谢谢你。

更新:对于@peacemaker


FILE *f;
zint_symbol *my_symbol;
my_symbol = ZBarcode_Create();
ZBarcode_Encode_and_Buffer(my_symbol, (unsigned char *)argv[1], 0, 0);
f = fopen("bitmap.bmp", "w");
fwrite(my_symbol->bitmap, sizeof(*(my_symbol->bitmap)), my_symbol->bitmap_height * my_symbol->bitmap_width, f);
ZBarcode_Delete(my_symbol);
fclose(f);
4

3 回答 3

4

为了在图像格式之间进行转换,最简单的方法是使用由MFCATL共享并在头文件 atlimage.h 中定义的CImage类。

CImage image; 
HRESULT res = image.Load("in.bmp");
image.Save("out.jpg");
image.Save("out.gif");
image.Save("out.png");
image.Save("out.tif");





如果您有一个 RGB 缓冲区并想创建一个位图:只需创建一个位图头并将其保存到文件中,然后将 RGB 缓冲区添加到其中。

要创建头文件,您可以使用头文件 WinGDI.h 中定义的GDI中的BITMAPFILEHEADERBITMAPINFOHEADERRGBQUAD结构

以下是有关如何填充标题数据的示例:

BITMAPINFOHEADER bmpInfoHdr;

bmpInfoHdr.biSize = sizeof(BITMAPINFOHEADER);
bmpInfoHdr.biHeight = nHeight;
bmpInfoHdr.biWidth =  nWidthPadded;
bmpInfoHdr.biPlanes = 1;
bmpInfoHdr.biBitCount = bitsPerPixel;           
bmpInfoHdr.biSizeImage = nHeight * nWidthPadded * nSPP; 
bmpInfoHdr.biCompression =  BI_RGB; 
bmpInfoHdr.biClrImportant = 0;  
bmpInfoHdr.biClrUsed = 0;
bmpInfoHdr.biXPelsPerMeter = 0;
bmpInfoHdr.biYPelsPerMeter = 0;
bmpFileHdr.bfType = BITMAP_FORMAT_BMP;
bmpFileHdr.bfSize =  (DWORD) (sizeof(BITMAPFILEHEADER) + bmpInfoHdr.biSize +
                      sizeof(RGBQUAD)*numColors + bmpInfoHdr.biSizeImage);
bmpFileHdr.bfReserved1 = 0;
bmpFileHdr.bfReserved2 = 0;
bmpFileHdr.bfOffBits = (DWORD) (sizeof(BITMAPFILEHEADER) + bmpInfoHdr.biSize + 
                        sizeof(RGBQUAD)*numColors);


请注意,位图是倒置存储的,并且图像的宽度必须在 DWORD 上对齐,RLE 压缩的位图除外。(它们必须是 4 字节的倍数,如有必要,请添加填充)。

if ((nWidth%4) != 0)
    nPadding = ((nWidth/4) + 1) * 4;

保存缓冲区时,将所需的填充添加到每一行...


总而言之,这些是从 rgb 缓冲区创建位图文件所需的步骤:

//1. create bmp header 

//2. save header to file:
 write(file, &bmpFileHdr, sizeof(BITMAPFILEHEADER));
 write(file, &bmpInfoHdr, sizeof(BITMAPINFOHEADER));
 write(file, &colorTable, numColors * sizeof(RGBQUAD));

//3. add rgb buffer to file:
for(int h=0; h<nHeight; h++) {
   for(int w=0; w<nWidth; w++) {
      //3.a) add row to file
      //3.b) add padding for this row to file
   }
}
于 2013-11-14T15:13:07.833 回答
0

我使用了 ATL 的 CImage 类。

int width=0, height=0;
char * val = "9788994774480"; 
zint_symbol *my_symbol;
my_symbol = ZBarcode_Create();

//ZBarcode_Encode_and_Buffer(my_symbol,(unsigned char *) val, 0, 0);
ZBarcode_Encode(my_symbol, (unsigned char *) val, 0);
ZBarcode_Buffer(my_symbol, 0);

height = my_symbol->bitmap_height;
width = my_symbol->bitmap_width;
char * imgBits = my_symbol->bitmap;

CImage img;
img.Create(width, height, 24 /* bpp */, 0 /* No alpha channel */);

int nPixel = 0;
for(int row = 0; row < height; row++)
{
    for(int col = 0; col < width; col++)
    {
        BYTE r = (BYTE)imgBits[nPixel];
        BYTE g = (BYTE)imgBits[nPixel+1];
        BYTE b = (BYTE)imgBits[nPixel+2];
        img.SetPixel(col, row , RGB(r, g, b));

        nPixel += 3;
    }
}

img.Save("CImage.bmp", Gdiplus::ImageFormatBMP);

ZBarcode_Delete(my_symbol);
于 2014-01-22T06:35:25.903 回答
0

除了使用 SetPixel 之外,还有其他方法吗?我遇到了 SetPixel 的主要性能问题,需要一种替代方法...我尝试使用CreateDIBSection无济于事。条码显示倾斜且无法使用。这是我的代码:

void *bits = (unsigned char*)(my_symbol->bitmap);
HBITMAP hBitmap = CreateDIBSection(pDC->GetSafeHdc(), &info, DIB_RGB_COLORS, (void **)&pDestData, NULL, 0);
memcpy(pDestData, my_symbol->bitmap, info.bmiHeader.biSizeImage);
img.Attach(hBitmap);

产生相同结果的另一个选项是:

    BITMAPINFO info;
    BITMAPINFOHEADER BitmapInfoHeader;    
    BitmapInfoHeader.biSize = sizeof(BITMAPINFOHEADER);   
    BitmapInfoHeader.biWidth = my_symbol->bitmap_width;
    BitmapInfoHeader.biHeight = -(my_symbol->bitmap_height);
    BitmapInfoHeader.biPlanes = 1;   
    BitmapInfoHeader.biBitCount = 24;   
    BitmapInfoHeader.biCompression = BI_RGB;  
    BitmapInfoHeader.biSizeImage = 0;   
    BitmapInfoHeader.biXPelsPerMeter = 0;   
    BitmapInfoHeader.biYPelsPerMeter = 0;   
    BitmapInfoHeader.biClrUsed = 0;   
    BitmapInfoHeader.biClrImportant = 0;

    info.bmiHeader = BitmapInfoHeader;

    HBITMAP hbmp = CreateDIBitmap(dc, &BitmapInfoHeader, CBM_INIT, (LPVOID *)my_symbol->bitmap, (LPBITMAPINFO)&info, DIB_RGB_COLORS);
    img.Attach(hbmp);
于 2015-06-22T09:32:27.353 回答