Delphi DIB con DIB Header in TBitmap
Domanda
Sono gentilmente chiedendo di aiutarmi con questo problema:
C'è un array di byte (data: PByte
) che contiene i dati DIB E DIBHeader:
TDibHeader = record
size: Cardinal;
width: Integer;
height: Integer;
planes: Word;
bits: Word;
compression: Cardinal;
image_size: Cardinal;
x_res: Integer;
y_res: Integer;
n_colors: Cardinal;
important_colors: Cardinal;
end;
Come convertire DIB a TBitmap mantenendo il basso utilizzo della CPU?
Ho provato http://files.codes -sources.com/fichier.aspx?id=43989&f=GdipApi.pas senza successo.
Ho assegnato DIB a un flusso di memoria:
DibMemStream.Clear;
DibMemStream.SetSize(header.image_size);
MoveMemory(DibMemStream.Memory,DibBuffer,header.image_size);
Credo che ci dovrebbe essere un colpo di testa da qualche parte DIB scritto prima Bitmap.LoadFromMemoryStream (DibMemStream). Non so dove.
Tutte le idee per favore?
Grazie!
Soluzione
Ho usato il seguente schema per convertire le immagini in memoria di TBitmap:
1) Struttura Fill TBMPHeader
TBMPHeader = packed record
bmfHeader: TBitmapFileHeader;
bmiHeader: TBitmapInfoHeader;
bmiColors: {depends on image format, may be absent};
end;
2) BMPHeader + Image Data di MemoryStream
3) Carico TBitmap da MemoryStream usando TBitmap.LoadFromStream
sembra avere struttura bmiHeader riempito già. Aggiungere (forse) bmiColors bmfHeader e.
Ecco il codice che ho usato per la conversione a 256 colori in scala di grigi in memoria di TBitmap (molti anni fa, mi dispiace, in modo da nessun dettaglio):
procedure TksImage.CopyToBitmap(Bitmap: TBitmap);
var
Stream: TStream;
begin
Stream:= TMemoryStream.Create;
try
SaveToStream(Stream);
Stream.Position:= 0;
Bitmap.LoadFromStream(Stream);
finally
Stream.Free;
end;
end;
procedure TksImage.SaveToStream(Stream: TStream);
type
TBMPHeader = packed record
bmfHeader: TBitmapFileHeader;
bmiHeader: TBitmapInfoHeader;
bmiColors: array[0..255] of TRGBQuad;
end;
var
BMPHeader: TBMPHeader;
N: LongWord;
I: Integer;
begin
FillChar(BMPHeader, SizeOf(BMPHeader), 0);
with BMPHeader.bmfHeader do begin
bfType:= $4D42; {'BM'}
bfOffBits:= SizeOf(BMPHeader);
if FChannels = 4 then Dec(bfOffBits, SizeOf(BMPHeader.bmiColors));
bfSize:= bfOffBits + LongWord(FImageSize);
end;
with BMPHeader.bmiHeader do begin
biSize:= SizeOf(BMPHeader.bmiHeader);
biWidth:= FWidth;
biHeight:= FHeight;
biPlanes:= 1;
biBitCount:= 8 * FChannels;
biCompression:= BI_RGB;
biSizeImage:= FImageSize;
{((((biWidth * biBitCount) + 31) and not 31) shr 3) * biHeight;}
end;
N:= 0;
for I:= 0 to 255 do begin
LongWord(bmpHeader.bmiColors[I]):= N;
Inc(N, $010101);
end;
Stream.Write(BMPHeader, BMPHeader.bmfHeader.bfOffBits);
Stream.Write(FImageData^, FImageSize);
end;
Altri suggerimenti
E 'passato molto tempo da quando ho fatto codifica qualsiasi Delphi e io non sono stato in grado di testare questo, ma se è possibile fornire un handle per il DIB, c'è una funzione - hDIBToTBitmap1 () - che dovrebbe fare il trucco in questo link:
http://www.efg2.com/Lab/Library /Delphi/Graphics/LeadToolsConversions.TXT