i've solved my Problem - with a function that converts FMX.Graphics.TBitmap to Windows Bitmap Format (in a TBytesStream)
it only generates 24bits per Pixel, uncompressed BMPs, but for me that is fine (only 128x128 Pixel Thumbnails)
Type TBitmapFileHeader = Record
bfType : Word; // ASCII "BM" (Hex: 0x424D)
bfSize : FixedUInt; // Size of BMP File
bfReserved : FixedUInt; // Reserved, Default 0x00000000
bfOffBits : FixedUInt; // Offset of Imagedata, Default 0x00000036 (Header (14) + Infoheader(40) = 54)
end;
TBitmapInfoHeader = Record
biSize : FixedUInt; // Größe der BITMAPINFOHEADER-Struktur in Byte
biWidth : FixedInt; // Breite der Bitmap in Pixel.
biHeight : FixedInt; // Der Betrag gibt die Höhe der Bitmap in Pixel an.
// Ist der Wert positiv, so ist die Bitmap eine sogenannte "bottom-up"-Bitmap (die Bilddaten beginnen mit der untersten und enden mit der obersten Bildzeile). Dies ist die gebräuchlichste Variante.
// Ist der Wert negativ, so ist die Bitmap eine "top-down"-Bitmap (die Bilddaten beginnen mit der obersten und enden mit der untersten Bildzeile).
biPlanes : Word; // 1 (Stand in einigen älteren Formaten wie PCX für die Anzahl der Farbebenen, wird aber für BMP nicht verwendet)
biBitCount : Word; // Gibt die Farbtiefe der Bitmap in bpp an; muss einer der folgenden Werte sein: 1, 4, 8, 16, 24 oder 32. Bei 1, 4 und 8 bpp sind die Farben indiziert.
biCompression : FixedUInt; // Einer der folgenden Werte:
// 0 (BI_RGB): Bilddaten sind unkomprimiert.
// 1 (BI_RLE8): Bilddaten sind lauflängenkodiert für 8 bpp. Nur erlaubt wenn biBitCount=8 und biHeight positiv.
// 2 (BI_RLE4): Bilddaten sind lauflängenkodiert für 4 bpp. Nur erlaubt wenn biBitCount=4 und biHeight positiv.
// 3 (BI_BITFIELDS): Bilddaten sind unkomprimiert und benutzerdefiniert (mittels Farbmasken) kodiert. Nur erlaubt wenn biBitCount=16 oder 32.
biSizeImage : FixedUInt; // Wenn biCompression=BI_RGB: Entweder 0 oder die Größe der Bilddaten in Byte.
// Ansonsten: Größe der Bilddaten in Byte.
biXPelsPerMeter : FixedInt; // Horizontale Auflösung des Zielausgabegerätes in Pixel pro Meter; wird aber für BMP-Dateien meistens auf 0 gesetzt.
biYPelsPerMeter : FixedInt; // Vertikale Auflösung des Zielausgabegerätes in Pixel pro Meter; wird aber für BMP-Dateien meistens auf 0 gesetzt.
biClrUsed : FixedUInt; // Wenn biBitCount=1: 0.
// Wenn biBitCount=4 oder 8: die Anzahl der Einträge der Farbtabelle; 0 bedeutet die maximale Anzahl (2, 16 oder 256).
// Ansonsten: Die Anzahl der Einträge der Farbtabelle (0=keine Farbtabelle). Auch wenn sie in diesem Fall nicht notwendig ist, kann dennoch eine für die Farbquantisierung empfohlene Farbtabelle angegeben werden.
biClrImportant : FixedUInt; // Wenn biBitCount=1, 4 oder 8: Die Anzahl sämtlicher im Bild verwendeten Farben; 0 bedeutet alle Farben der Farbtabelle.
// Ansonsten:
// Wenn eine Farbtabelle vorhanden ist und diese sämtliche im Bild verwendeten Farben enthält: deren Anzahl.
// Ansonsten: 0.
end;
Function ConvertTBitmapToBMP(orgBitmap: FMX.Graphics.TBitmap) : tBytesStream;
var x, y, p : Integer;
offBits : Integer;
dataSize : Integer;
BmpFHeader : TBitmapFileHeader;
BmpIHeader : TBitmapInfoHeader;
BitData : TBitmapData;
AC : TAlphaColor;
begin
Result := NIL;
if Assigned(orgBitmap) then begin
if (orgBitmap.Map(TMapAccess.ReadWrite, BitData)) then begin
try
Result := tBytesStream.Create;
BmpIHeader.biSize := SizeOf(TBitmapInfoHeader);
BmpIHeader.biWidth := orgBitmap.width;
BmpIHeader.biHeight := orgBitmap.height;
BmpIHeader.biPlanes := 1;
BmpIHeader.biBitCount := 24;
BmpIHeader.biCompression := 0;
BmpIHeader.biSizeImage := orgBitmap.width * orgBitmap.height * (BmpIHeader.biBitCount DIV 8);
BmpIHeader.biXPelsPerMeter := 0;
BmpIHeader.biYPelsPerMeter := 0;
BmpIHeader.biClrUsed := 0;
BmpIHeader.biClrImportant := 0;
offBits := SizeOf(TBitmapFileHeader) + SizeOf(TBitmapInfoHeader);
dataSize := orgBitmap.width * orgBitmap.height * (BmpIHeader.biBitCount DIV 8);
BmpFHeader.bfType := $4D42;
BmpFHeader.bfSize := offBits + dataSize;
BmpFHeader.bfReserved := 0;
BmpFHeader.bfOffBits := offBits;
Result.Clear;
Result.Write(BmpFHeader.bfType, 2);
Result.Write(BmpFHeader.bfSize, 4);
Result.Write(BmpFHeader.bfReserved, 4);
Result.Write(BmpFHeader.bfOffBits, 4);
Result.Write(BmpIHeader.biSize, 4);
Result.Write(BmpIHeader.biWidth, 4);
Result.Write(BmpIHeader.biHeight, 4);
Result.Write(BmpIHeader.biPlanes, 2);
Result.Write(BmpIHeader.biBitCount, 2);
Result.Write(BmpIHeader.biCompression, 4);
Result.Write(BmpIHeader.biSizeImage, 4);
Result.Write(BmpIHeader.biXPelsPerMeter, 4);
Result.Write(BmpIHeader.biYPelsPerMeter, 4);
Result.Write(BmpIHeader.biClrUsed, 4);
Result.Write(BmpIHeader.biClrImportant, 4);
Result.Size := BmpFHeader.bfSize;
for y := 0 to orgBitmap.height - 1 do begin
for x := 0 to orgBitmap.width - 1 do begin
AC := BitData.GetPixel(x, y);
p := (((orgBitmap.height-y) * orgBitmap.width) + x) * (BmpIHeader.biBitCount DIV 8);
Result.Bytes[offBits+p ] := TAlphaColorRec(AC).B;
Result.Bytes[offBits+p+1] := TAlphaColorRec(AC).G;
Result.Bytes[offBits+p+2] := TAlphaColorRec(AC).R;
end;
end;
Result.Position := 0;
finally
orgBitmap.Unmap(BitData);
end;
end;
end;
end;