2012-12-21 51 views
3

問題如何在現有像素數據周圍包裝TCanvas?

我有一個包含位圖圖像的32位像素數據的數組。

TPixel = packed record 
    B: Byte; 
    G: Byte; 
    R: Byte; 
    A: Byte; 
end; 

Size = MyBitmapWidth * MyBitmapHeight; 

MyBitmapData : array[0..Size-1] of TPixel; 

是否有可能創建一個新的TCanvas對象並將其附加到我現有的像素數據?畫布對象還需要分配給它的句柄。

背景

我使用創建位圖數據的第三方庫(如32個比特象素陣列)。我想在另一個以TCanvas.Handle作爲參數的函數中使用相同的像素數據。

+0

如果該函數使用TCanvas.Handle作爲它的參數,那麼你不需要* TCanvas。你需要的是一個'HDC' - 一個Windows設備上下文的句柄。 –

+1

我一直在寫一個答案,解釋爲什麼它是不可能的,但現在我想它可能是。它需要能夠創建一個'HBitmap'來保存對像素緩衝區的引用,然後創建一個DC(使用'CreateCompatibleDC'),最後在DC中選擇位圖(使用'SelectObject')。我不確定的唯一部分是第一部分;我無法從文檔中知道「CreateDIBitmap」或「CreateDIBSection」是否保留對原始數據的引用。 ('TCanvas'與這個過程無關,但是如果你確實需要的話,只要在你準備好的時候分配'Handle:= hDC'。) –

回答

1

根據陣列中數據的方向,您可能需要改變方向,如: pscanLine32 [j] .rgbReserved:= Arr [i * Width + Height - j] .A;

type 
    TPixel = packed record 
    B: Byte; 
    G: Byte; 
    R: Byte; 
    A: Byte; 
    end; 

    TMyBitmapData = array of TPixel; 

type 
    pRGBQuadArray = ^TRGBQuadArray; 
    TRGBQuadArray = ARRAY [0 .. $EFFFFFF] OF TRGBQuad; 

Procedure FillBitMap(var bmp: TBitMap; Arr: TMyBitmapData; Width, Height: Integer); 
var 
    pscanLine32: pRGBQuadArray; 
    i, j: Integer; 
begin 
    if not Assigned(bmp) then 
    bmp := TBitMap.Create; 
    bmp.PixelFormat := pf32Bit; 
    bmp.ignorepalette := true; 
    bmp.Width := Width; 
    bmp.Height := Height; 
    for i := 0 to bmp.Height - 1 do 
    begin 
    pscanLine32 := bmp.Scanline[i]; 
    for j := 0 to bmp.Width - 1 do 
    begin 
     pscanLine32[j].rgbReserved := Arr[i * Width + j].A; 
     pscanLine32[j].rgbBlue := Arr[i * Width + j].B; 
     pscanLine32[j].rgbRed := Arr[i * Width + j].R; 
     pscanLine32[j].rgbGreen := Arr[i * Width + j].G; 
    end; 
    end; 
end; 

procedure TForm4.Button1Click(Sender: TObject); 
var 
    MyBitmapWidth: Integer; 
    MyBitmapHeight: Integer; 
    Size: Cardinal; 
    MyBitmapData: TMyBitmapData; 
    bmp: TBitMap; 
    x: Integer; 
begin 
    MyBitmapWidth := 100; 
    MyBitmapHeight := 100; 
    Size := MyBitmapWidth * MyBitmapHeight; 
    SetLength(MyBitmapData, Size); 

    for x := 0 to MyBitmapWidth - 1 do 
    begin 
    MyBitmapData[x * MyBitmapWidth + x].A := 255; 
    MyBitmapData[x * MyBitmapWidth + x].R := 255; 
    end; 


    bmp := TBitMap.Create; 
    try 
    FillBitMap(bmp, MyBitmapData, MyBitmapWidth,MyBitmapHeight); 
    Image1.picture.Assign(bmp); 
    finally 
    bmp.Free; 
    end; 

end; 
+2

你的答案似乎是製作一個全新的像素數據副本。我不認爲這就是問題所要求的。相反,問題是如何在現有的*像素緩衝區周圍包裝TCanvas對象;那個'TCanvas'對象的調用方法會直接修改原始緩衝區的內容。 –

+0

@RobKennedy我不舒服,但我不認爲它可能使用外部DBI結構的位圖,它是HDC。我應該刪除我的帖子作爲Off Topic嗎? – bummi

+0

感謝您的答案Bummi,但羅布是正確的。我想創建一個TCanvas對象並且利用現有的像素數據。 – Shannon