2 Stimmen

libjpeg/CreateDIBSection-Problem

Ich schreibe eine Win32-basierte Anwendung, die jpeg-Bilder aus einer Datenbank anzeigt. Ich habe libjpeg als Decoder gewählt, aber die meisten Bilder werden nicht korrekt angezeigt. Das Problem kann behoben werden, indem man die Breite des Bildes um eins erhöht oder verringert, allerdings werden Bilder, die vorher korrekt angezeigt wurden, nach dieser Korrektur nicht mehr korrekt angezeigt. Hier ist ein Teil meines Codes (ohne die Umwandlung von RGB in BGR):

int JpegToRaw(BYTE *input, int insize, BYTE *output, int &width, int &height)
{
    struct jpeg_decompress_struct cinfo;
    struct jpeg_error_mgr jerr;

    cinfo.err = jpeg_std_error(&jerr);
    jpeg_create_decompress(&cinfo);

    jpeg_mem_src(&cinfo, input, insize);
    jpeg_read_header(&cinfo, TRUE);

    jpeg_start_decompress(&cinfo);

    //--cinfo.output_width; or ++cinfo.output_width;

    int row_stride = cinfo.output_width * 3;
    int outsize = row_stride * cinfo.output_height;
    output = (BYTE *)malloc(outsize * sizeof(BYTE));
    BYTE *pos = output;

    while (cinfo.output_scanline < cinfo.output_height)
    {
        jpeg_read_scanlines(&cinfo, &pos, 1);
        pos += row_stride;
    }

    width = cinfo.output_width;
    height = cinfo.output_height;

    jpeg_finish_decompress(&cinfo);
    jpeg_destroy_decompress(&cinfo);
    return outsize;
}

HBITMAP RawToBitmap(BYTE *input, int size, int width, int height)
{
    BITMAPINFO bi;
    bi.bmiHeader.biSize        = sizeof(bi24BitInfo.bmiHeader);
    bi.bmiHeader.biWidth       = width;
    bi.bmiHeader.biHeight      = -height;
    bi.bmiHeader.biPlanes      = 1;
    bi.bmiHeader.biBitCount    = 24;
    bi.bmiHeader.biCompression = BI_RGB;

    HBITMAP hBitmap = CreateDIBSection(NULL, &bi, DIB_RGB_COLORS, NULL, NULL, 0);
    SetBitmapBits(hBitmap, size, input);
    return hBitmap;
}

Ich bin sicher, ich übergebe gültige jpeg-Arrays an JpegToRaw() aber ich habe keine Ahnung, warum die Bilder unterschiedlich angezeigt werden. Kann mir jemand helfen, es zu bekommen?

3voto

efotinis Punkte 13896

Die Dokumentation über BITMAPINFO sagt dies über ein DIB aus:

[ ] jede Abtastzeile muss mit Nullen aufgefüllt werden, damit sie auf einer LONG-Datentypgrenze endet.

Dies bedeutet, dass row_stride muss ein Vielfaches von 4 Bytes sein. Hier ist eine Möglichkeit, dies zu berechnen:

int row_stride = (cinfo.output_width * 3 + 3) / 4 * 4;

Ebenso muss die Größe einer DDB-Zeile ein Vielfaches von 2 sein.

2voto

Adrian McCarthy Punkte 42872

Bei den Windows-Bitmaps müssen die Scanlines auf DWORD-Grenzen aufgefüllt werden. Ihre Testbilder könnten eine ungerade Breite haben.

0voto

fred Punkte 11

Sie brauchen libjpeg nicht! Jpeg ist nativ in Windows (Shell), wie alle Grafikformate

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X