如何从位数组创建 Bitmap32?
How to create Bitmap32 from Bits array?
我有一个函数 returns 指向存储图像的内存的指针 Bitmap32.Bits:
function FileToMemoryAsBitmap32Bits: pointer;
var
bmp32: TBitmap32;
wic: TWICImage;
begin
Result := nil;
bmp32 := TBitmap32.Create();
try
wic := TWICImage.Create;
try
wic.LoadFromFile('256x256.jpg');
bmp32.Assign(wic);
GetMem(Result, 256*256*4);
Move(bmp32.Bits^, Result^, 256*256*4);
finally
FreeAndNil(wic);
end;
finally
FreeAndNil(bmp32);
end;
end;
在代码的某个地方,我需要从内存中的这个位创建一个新的 Bitmap32。如何正确操作?
我尝试执行以下操作:
var
p: Pointer;
NewBitmap32: TBitmap32;
// ...
p := FileToMemoryAsBitmap32Bits;
// ... do something with Bits in memory
NewBitmap32 := TBitmap32.Create(256, 256);
NewBitmap32.Bits := p;
但我得到一个错误:
E2129 Cannot assign to a read-only property
为@RudyVelthuis 添加:
procedure RenderMemoryToBitmap32(Output: TBitmap32; p: pointer; const x, y: integer);
var
d, i,j: integer;
OutputRowRGBA, RowRGBA: PColor32Array;
begin
RowRGBA := PColor32Array(p);
for j := 0 to 255 do begin
OutputRowRGBA := Output.Scanline[y+j]; // row in large bitmap
for i := 0 to 255 do begin
d := i + x; // offset
TColor32Entry(OutputRowRGBA[d]).B := TColor32Entry(RowRGBA[i]).B;
TColor32Entry(OutputRowRGBA[d]).G := TColor32Entry(RowRGBA[i]).G;
TColor32Entry(OutputRowRGBA[d]).R := TColor32Entry(RowRGBA[i]).R;
TColor32Entry(OutputRowRGBA[d]).A := TColor32Entry(RowRGBA[i]).A;
end;
inc(longword(RowRGBA), 256*4); // next row
end;
end;
您不能使用这种方式更改数据地址,内存已经分配并且bitmap32
不允许替换其地址。
但是您可以将存储的数据移动到此位置,就像您已经为存储所做的那样(但方向相反),但方向相反:
Move(p^, NewBitmap32.Bits^, 256*256*4);
虽然我不想质疑您将位图存储为比特流的需求,
也应该可以像这样克隆原始位图:
NewBitmap32 := TBitmap32.Create;
NewBitmap32.Assign(OriginalBitmap);
这将在保留位图的宽度和高度(否则会丢失)方面完美地克隆位图。在内存中使用 TBitmap32 而不是纯比特流的开销是最小的。
我有一个函数 returns 指向存储图像的内存的指针 Bitmap32.Bits:
function FileToMemoryAsBitmap32Bits: pointer;
var
bmp32: TBitmap32;
wic: TWICImage;
begin
Result := nil;
bmp32 := TBitmap32.Create();
try
wic := TWICImage.Create;
try
wic.LoadFromFile('256x256.jpg');
bmp32.Assign(wic);
GetMem(Result, 256*256*4);
Move(bmp32.Bits^, Result^, 256*256*4);
finally
FreeAndNil(wic);
end;
finally
FreeAndNil(bmp32);
end;
end;
在代码的某个地方,我需要从内存中的这个位创建一个新的 Bitmap32。如何正确操作?
我尝试执行以下操作:
var
p: Pointer;
NewBitmap32: TBitmap32;
// ...
p := FileToMemoryAsBitmap32Bits;
// ... do something with Bits in memory
NewBitmap32 := TBitmap32.Create(256, 256);
NewBitmap32.Bits := p;
但我得到一个错误:
E2129 Cannot assign to a read-only property
为@RudyVelthuis 添加:
procedure RenderMemoryToBitmap32(Output: TBitmap32; p: pointer; const x, y: integer);
var
d, i,j: integer;
OutputRowRGBA, RowRGBA: PColor32Array;
begin
RowRGBA := PColor32Array(p);
for j := 0 to 255 do begin
OutputRowRGBA := Output.Scanline[y+j]; // row in large bitmap
for i := 0 to 255 do begin
d := i + x; // offset
TColor32Entry(OutputRowRGBA[d]).B := TColor32Entry(RowRGBA[i]).B;
TColor32Entry(OutputRowRGBA[d]).G := TColor32Entry(RowRGBA[i]).G;
TColor32Entry(OutputRowRGBA[d]).R := TColor32Entry(RowRGBA[i]).R;
TColor32Entry(OutputRowRGBA[d]).A := TColor32Entry(RowRGBA[i]).A;
end;
inc(longword(RowRGBA), 256*4); // next row
end;
end;
您不能使用这种方式更改数据地址,内存已经分配并且bitmap32
不允许替换其地址。
但是您可以将存储的数据移动到此位置,就像您已经为存储所做的那样(但方向相反),但方向相反:
Move(p^, NewBitmap32.Bits^, 256*256*4);
虽然我不想质疑您将位图存储为比特流的需求, 也应该可以像这样克隆原始位图:
NewBitmap32 := TBitmap32.Create;
NewBitmap32.Assign(OriginalBitmap);
这将在保留位图的宽度和高度(否则会丢失)方面完美地克隆位图。在内存中使用 TBitmap32 而不是纯比特流的开销是最小的。