2010-01-29 34 views
0

我好心問你幫我解決這個問題:含德爾福DIB與DIB頭到TBitmap

有一個字節數組(data: PByte)DIB數據和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; 
 

如何轉換DIB添加到TBitmap,同時保持CPU使用率低?我試過http://files.codes-sources.com/fichier.aspx?id=43989&f=GdipApi.pas沒有成功。

我分配DIB到內存流:

 

    DibMemStream.Clear; 
    DibMemStream.SetSize(header.image_size); 
    MoveMemory(DibMemStream.Memory,DibBuffer,header.image_size); 
 

我想應該有DIB頭Bitmap.LoadFromMemoryStream(DibMemStream)在什麼地方寫的。不知道在哪裏。

有什麼想法嗎?

謝謝!

回答

3

我已經使用了以下方案以在內存中的圖像轉換爲TBitmap:

1)填充TBMPHeader結構

TBMPHeader = packed record 
    bmfHeader: TBitmapFileHeader; 
    bmiHeader: TBitmapInfoHeader; 
    bmiColors: {depends on image format, may be absent}; 
    end; 

2)收件BMPHeader +圖像數據使用TBitmap.LoadFromStream

你似乎有bmiHeader結構已經從填充的MemoryStream MemoryStream的

3)負載TBitmap。添加bmfHeader和(也許)bmiColors。

下面是我用256色灰度內存圖像轉換爲TBitmap代碼(很多年前,對不起,所以沒有詳細說明):

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; 
+0

Serg,當bmiColors從記錄中刪除時,它就像一個魅力:) 謝謝! – benjamin 2010-01-31 13:02:17

+0

在保持透明度的情況下爲PNG圖像做這個工作嗎? – 2011-11-28 10:30:50

0

自從我做了任何Delphi編碼已經很長時間了,我還沒有能夠測試這個,但是如果您可以提供DIB的句柄,那麼有一個函數 - hDIBToTBitmap1() - 應該做的在此鏈接:

http://www.efg2.com/Lab/Library/Delphi/Graphics/LeadToolsConversions.TXT

+0

如何通過PBYTE數組作爲THandle(需要hDIB)。 THandle()鑄造不會做伎倆,但類似的東西? – benjamin 2010-01-29 18:02:31

+0

'PByte'和'THandle'是兩個非常不同的東西,所以你將無法投射。 – jpfollenius 2010-01-30 13:11:03