我对delphi完全陌生,我有一个项目需要从指针加载图片到包含原始像素数据的C数组。
我不能简单地使用TPicture.LoadFromFile
,因为实际加载是在C ++ DLL中执行的。我从DLL中得到的只是指向图像宽度,高度,格式的指针,以及指向保存像素数据的数组的指针。
DLL_Image = packed record
Width : UInt32; { Width of image. [px] }
Height : UInt32; { Height of image. [px] }
Format : ImageFormat; { (Color) Format of image. }
Data : ^UInt8; { Points to image data. }
end;
DLL_PImage = ^DLL_Image;
我尝试的是将图像数据加载到TMemoryStream
后跟TPicture.LoadFromStream()
的情况,该方法不起作用。 IIRC,我必须向流中写入TPicture
的适当实例,以使此工作生效。
有没有一种方法可以从数据数组中加载图像?
答案 0 :(得分:5)
通过将像素数据复制到TBitmap
的扫描线上,可以轻松地使用给定的像素数据创建VCL TBitmap
对象。
这是一个简单的例子。
首先,我们创建一些样本原始像素数据:
function MakePixelData(const AWidth, AHeight: Integer): pointer;
var
p: PRGBQuad;
y, x: Integer;
begin
GetMem(Result, AWidth * AHeight * sizeof(TRGBQuad));
p := PRGBQuad(Result);
y := 0;
while y < AHeight do
begin
x := 0;
while x < AWidth do
begin
p.rgbRed := 255 * x div AWidth;
p.rgbGreen := 255 * y div AHeight;
p.rgbBlue := 255;
Inc(x);
Inc(p);
end;
Inc(y);
end;
end;
procedure FreePixelData(var AData: pointer);
begin
FreeMem(AData);
end;
MakePixelData
函数在堆上为给定大小的位图分配一些内存,并用简单的渐变填充它:
然后使用FreePixelData
过程释放此内存。
现在有趣的是,使用此原始像素数据获得VCL TBitmap
对象:
procedure TForm1.FormCreate(Sender: TObject);
const
W = 400;
H = 200;
var
RawPixelData: pointer;
bm: TBitmap;
y: Integer;
function PixelData(ARowIndex: Integer): pointer;
begin
Result := PByte(RawPixelData) + ARowIndex * W * sizeof(TRGBQuad);
end;
begin
RawPixelData := MakePixelData(W, H);
try
bm := TBitmap.Create;
try
bm.SetSize(W, H);
bm.PixelFormat := pf32bit;
for y := 0 to bm.Height - 1 do
CopyMemory(bm.ScanLine[y], PixelData(y), bm.Width * sizeof(TRGBQuad));
bm.SaveToFile('D:\Desktop\Bitmap from raw pixel data.bmp');
finally
bm.Free;
end;
finally
FreePixelData(RawPixelData);
end;
end;
这将从原始像素数据创建VCL TBitmap
。只是为了证明它有效,我将其另存为文件。但是您也可以将其显示在TImage
控件中,也可以将其用于某些自定义VCL绘图。
请小心在所有地方使用相同的像素格式。在我的示例中,我使用32位RGBX数据。