2012-12-21 28 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