Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (WinAPI, Konsole) » JPEGs mit BITMAPINFOHEADER erstellen

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
04.03.2013, 13:39 Uhr
~ChrisCol
Gast


Hallo,

ich habe ein Problem mit dem Speichern von Bitmaps und hoffe, dass mir jemand helfen kann.

Zum Speichern verwende ich BITMAPINFOHEADER. Und es funktioniert auch soweit solange ich für biCompression BI_RGB verwende.

Ich will aber auch JPEGs und PNGs speichern können. Wenn ich also BI_JPEG in biCompression einstelle und dass Bild speichere, dann kann ich das Bild nicht aufmachen. Es kommt die Fehlermeldung "Bilddarstellung fehlgeschlagen". Außerdem kann ich sehen, dass die Größe des Bildes sich nicht ändert, sondern genauso groß wie beim BMP ist.

Hier ist mein Code:


C++:
FILE *fptr;
BITMAPINFOHEADER infoHeader;
BITMAPFILEHEADER header;
std::wstring file = _T("");
    
if (imageFormat == BI_RGB)
    file = path + _T(".bmp");        
else if (imageFormat == BI_JPEG)
    file = path + _T(".jpg");
else if (imageFormat == BI_PNG)
    file = path + _T(".png");
    

fptr = _tfopen(file.c_str(), _T("wb"));
if (!fptr)
    return false;


infoHeader.biSize = kInfoHeaderSize;
infoHeader.biWidth = x1 - x0 + 1;
infoHeader.biHeight = y1 - y0 + 1;
infoHeader.biPlanes = 1;
infoHeader.biBitCount = kRGB24Bit;    
infoHeader.biCompression = imageFormat;
infoHeader.biSizeImage = (x1 - x0 + 1) * (y1 - y0 + 1);
infoHeader.biXPelsPerMeter = 3780;
infoHeader.biYPelsPerMeter = 3780;
infoHeader.biClrUsed = 0;
infoHeader.biClrImportant = 0;
    

header.bfType = kHeaderType;
header.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +
                                (x1 - x0 + 1) * (y1 - y0 + 1) + kPaletteSize;
header.bfReserved1 = 0;
header.bfReserved2 = 5;
header.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +
                                infoHeader.biClrUsed * sizeof(RGBQUAD);

fwrite(&header,sizeof(BITMAPFILEHEADER),1,fptr);
    

fwrite(&infoHeader,sizeof(BITMAPINFOHEADER),1,fptr);

fseek(fptr,header.bfOffBits,SEEK_SET);
unsigned char RGB24[kRGB24Size];
for (int i = 0; i < infoHeader.biHeight; i++)
{        
    ccPelTraits<unsigned char>::pointer pTrRed = red.pointToRow(y1 - i);
    ccPelTraits<unsigned char>::pointer pTrGreen = green.pointToRow(y1 - i);
    ccPelTraits<unsigned char>::pointer pTrBlue = blue.pointToRow(y1 - i);
    unsigned char * pPelGreen = &pTrGreen[x0];
    unsigned char * pPelBlue = &pTrBlue[x0];
    for (unsigned char* pPelRed = &pTrRed[x0]; pPelRed - pTrRed < x1 + 1; pPelRed++)
    {
        RGB24[0] = *pPelBlue;
        RGB24[1] = *pPelGreen;
        RGB24[2] = *pPelRed;
        fwrite(&RGB24, sizeof(unsigned char), kRGB24Size, fptr);
        pPelGreen++;
        pPelBlue++;
    }
}
fclose(fptr);



Vielen Dank für eure Hilfe!
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
04.03.2013, 15:05 Uhr
Hans
Library Walker
(Operator)


Hi,


Zitat von ~ChrisCol:
Hallo,
Zum Speichern verwende ich BITMAPINFOHEADER. Und es funktioniert auch soweit solange ich für biCompression BI_RGB verwende.

Ich will aber auch JPEGs und PNGs speichern können. Wenn ich also BI_JPEG in biCompression einstelle und dass Bild speichere, dann kann ich das Bild nicht aufmachen. Es kommt die Fehlermeldung "Bilddarstellung fehlgeschlagen". Außerdem kann ich sehen, dass die Größe des Bildes sich nicht ändert, sondern genauso groß wie beim BMP ist.



Soweit ich das sehe, kann das auch gar nicht anders sein, da BITMAPINFOHEADER eine Datenstruktur ist, die nur für Windows-BMP-Dateien definiert ist. Wenn Du also Bilder im JPG und/oder PNG Format speichern willst, brauchst Du die entsprechenden Bibliotheken, die auch diese Formate erstellen können. Das wäre die Lib-PNG bzw. lib-JPEG.
Wenn Du Dich nicht mit den einzelnen Bibliotheken beschäftigen willst, kannst Du auch cxImage ausprobieren. Das ist eine Klassenbibliothek, für die Verarbeitung verschiedener Bildformate. Die hab ich kürzlich entdeckt, aber noch nichts damit gemacht, also kann ich auch nur mitteilen dass, und wo es die gibt.

Hans
--
Man muss nicht alles wissen, aber man sollte wissen, wo es steht. Zum Beispiel hier: Nachdenkseiten oder Infoportal Globalisierung.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
04.03.2013, 15:26 Uhr
~ChrisCol
Gast


Danke für die Antwort. Aber dann verstehe ich nicht was die Einstellung BI_JPEG und BI_PNG bewirkt...?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
04.03.2013, 16:26 Uhr
Hans
Library Walker
(Operator)


Hi,

also in der oben von mir verlinkten Doku von BITMAPINFOHEADER gibt es die Einstellungen BI_JPEG und BI_PNG nicht. Ich zitiere mal:

Zitat von MSDN:

biCompression

Specifies the type of compression for a compressed bottom-up bitmap (top-down DIBs cannot be compressed). This member can be one of the following values.
Value Description

BI_RGB An uncompressed format.

BI_BITFIELDS Specifies that the bitmap is not compressed and that the color table consists of three DWORD color masks that specify the red, green, and blue components of each pixel.
This is valid when used with 16- and 32-bpp bitmaps.
This value is valid in Windows Embedded CE versions 2.0 and later.

BI_ALPHABITFIELDS Specifies that the bitmap is not compressed and that the color table consists of four DWORD color masks that specify the red, green, blue, and alpha components of each pixel.
This is valid when used with 16- and 32-bpp bitmaps.
This value is valid in Windows CE .NET 4.0 and later.

You can OR any of the values in the above table with BI_SRCPREROTATE to specify that the source DIB section has the same rotation angle as the destination.



Nun kann es natürlich sein, dass Du da noch eine andere Bibliothek hast, die sich auch BITMAPINFOHEADER nennt. Wenn das so ist, (was ich zwar für unwahrscheinlich, aber nicht unmöglich halte) solltest Du es uns mitteilen, bevor wir aneinander vorbei schreiben.

Und du solltest auch nicht vergessen, das die Header, also die Dateiköpfe von JPG bzw. PNG anders definiert sind, als die von BMP-Dateien. (Wenn Du die oben verlinkten Seiten mal angeguckt hast, sollte es Dir aufgefallen sein, eine kurze Betrachtung mit einem HexEditor reicht auch schon.)
Für Details klickst Du: BMP, PNG und JPG. Das sind jeweils Links zu Wotsit, einer Dateiformat Info Seite.

Hans
--
Man muss nicht alles wissen, aber man sollte wissen, wo es steht. Zum Beispiel hier: Nachdenkseiten oder Infoportal Globalisierung.

Dieser Post wurde am 04.03.2013 um 16:36 Uhr von Hans editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
04.03.2013, 16:43 Uhr
Hans
Library Walker
(Operator)


Nachtrag: Mach doch mal folgendes "Experiment": Speicher einen Smilie, z.B. den hier , auf der Festplatte, lade das Bild anschliessend mit einem Bildbetrachter wie IrfanView und speicher es damit als BMP, PNG und JPG ab. Anschliessend nimmst Du einen HexEditor, z.B. HxD, und guckst Dir die Dateien an, bzw. die Bytes derselben.

Da kommt für den Smilie für die jeweils ersten 256 Bytes folgendes bei heraus:

BMP-Format:

Code:
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000  42 4D 26 05 00 00 00 00 00 00 36 04 00 00 28 00  BM&.......6...(.
00000010  00 00 0F 00 00 00 0F 00 00 00 01 00 08 00 00 00  ................
00000020  00 00 F0 00 00 00 00 00 00 00 00 00 00 00 00 01  ..­.............
00000030  00 00 00 00 00 00 19 19 19 00 FF FF FF 00 8B 6C  ...........ïl
00000040  32 00 8E 6F 35 00 91 72 38 00 93 74 3A 00 96 77  2.Äo5.ær8.ôt:.ûw
00000050  3D 00 9A 7B 41 00 A6 87 4D 00 A9 8A 50 00 B0 91  =.Ü{A.ªçM.®èP.¦æ
00000060  57 00 B7 98 5E 00 BC 9D 63 00 C1 A2 68 00 C7 A8  W.Àÿ^.+.c.-óh.ÿ
00000070  6E 00 CE AF 75 00 D4 B5 7B 00 E1 C2 88 00 E3 C4  n.+»u.ÈÁ{.ß-ê.Ò-
00000080  8A 00 EA CB 91 00 ED CE 94 00 F1 D2 98 00 F6 D7  è.Û-æ.Ý+ö.±Êÿ.÷Î
00000090  9D 00 FB DC A2 00 FF E0 A6 00 FD DE A4 00 FF E6  ..¹_ó.Óª.²Ìñ.µ
000000A0  AC 00 FF E9 AF 00 FF F0 B6 00 FF F7 BD 00 FF F5  ¼.Ú».­Â.¸¢.§
000000B0  BB 00 FF FF FF 00 00 00 00 00 00 00 00 00 00 00  +............
000000C0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000D0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000E0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000F0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................



JPG-Format:

Code:
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000  FF D8 FF E0 00 10 4A 46 49 46 00 01 01 00 00 01  ÿØÿà..JFIF......
00000010  00 01 00 00 FF DB 00 43 00 06 04 05 06 05 04 06  ....ÿÛ.C........
00000020  06 05 06 07 07 06 08 0A 10 0A 0A 09 09 0A 14 0E  ................
00000030  0F 0C 10 17 14 18 18 17 14 16 16 1A 1D 25 1F 1A  .............%..
00000040  1B 23 1C 16 16 20 2C 20 23 26 27 29 2A 29 19 1F  .#... , #&')*)..
00000050  2D 30 2D 28 30 25 28 29 28 FF DB 00 43 01 07 07  -0-(0%()(ÿÛ.C...
00000060  07 0A 08 0A 13 0A 0A 13 28 1A 16 1A 28 28 28 28  ........(...((((
00000070  28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28  ((((((((((((((((
00000080  28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28  ((((((((((((((((
00000090  28 28 28 28 28 28 28 28 28 28 28 28 28 28 FF C0  ((((((((((((((ÿÀ
000000A0  00 11 08 00 0F 00 0F 03 01 22 00 02 11 01 03 11  ........."......
000000B0  01 FF C4 00 16 00 01 01 01 00 00 00 00 00 00 00  .ÿÄ.............
000000C0  00 00 00 00 00 00 05 02 06 FF C4 00 22 10 00 02  .........ÿÄ."...
000000D0  02 03 00 02 01 05 00 00 00 00 00 00 00 00 02 03  ................
000000E0  01 04 05 06 12 00 07 11 13 22 23 24 33 FF C4 00  ........."#$3ÿÄ.
000000F0  15 01 01 01 00 00 00 00 00 00 00 00 00 00 00 00  ................



PNG-Format:

Code:
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000  89 50 4E 47 0D 0A 1A 0A 00 00 00 0D 49 48 44 52  ëPNG........IHDR
00000010  00 00 00 0F 00 00 00 0F 08 03 00 00 00 0C 08 65  ...............e
00000020  78 00 00 03 00 50 4C 54 45 19 19 19 FF FF FF 32  x....PLTE...2
00000030  6C 8B 35 6F 8E 38 72 91 3A 74 93 3D 77 96 41 7B  lï5oÄ8ræ:tô=wûA{
00000040  9A 4D 87 A6 50 8A A9 57 91 B0 5E 98 B7 63 9D BC  ÜMçªPè®Wæ¦^ÿÀc.+
00000050  68 A2 C1 6E A8 C7 75 AF CE 7B B5 D4 88 C2 E1 8A  hó-n¿Ãu»+{ÁÈê-ßè
00000060  C4 E3 91 CB EA 94 CE ED 98 D2 F1 9D D7 F6 A2 DC  -Òæ-Ûö+Ýÿʱ.Î÷ó_
00000070  FB A6 E0 FF A4 DE FD AC E6 FF AF E9 FF B6 F0 FF  ¹ªÓñ̲¼µ»Ú­
00000080  BD F7 FF BB F5 FF FF FF FF 00 00 00 00 00 00 00  ¢¸+§.......
00000090  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000A0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000B0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000C0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000D0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000E0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000000F0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................


--
Man muss nicht alles wissen, aber man sollte wissen, wo es steht. Zum Beispiel hier: Nachdenkseiten oder Infoportal Globalisierung.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
04.03.2013, 20:17 Uhr
TOSHMAX



Hier sind BI_JPEG und BI_PNG nochmals genauer erklärt.

Wenn ich das richtig verstanden habe und du z. B. BI_JPEG verwendest, wird erwartet dass du ein komplettes Bild im JPEG-Format anstatt der Pixel-Daten in die Bitmap schreibst. Das heißt, du müsstest das vorhandende Bild zuerst selbst umwandeln. In dem Fall würde die von Hans bereits erwähnte libjpeg helfen.

Allerdings denke ich, dass nur sehr wenige Programme diese exotischen Bitmaps überhaupt lesen können. Vor allem die geringe Dokumentation und dieser Satz lassen darauf schließen, dass das auch gar nicht beabsichtigt ist:

Zitat:
The BITMAPINFOHEADER structure is extended to allow a JPEG or PNG image to be passed as the source image to StretchDIBits.

Am einfachsten ist es wohl, wenn du mithilfe von libjpeg und libpng die Bilder direkt als .jpeg oder .png abspeicherst. Beispiele dazu sollte es auf den Projektseiten und Online massenhaft geben.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
05.03.2013, 14:33 Uhr
~ChrisCol
Gast


Ok und vielen Dank euch beiden. Ich werde es versuchen...
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (WinAPI, Konsole) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: