2

我有一个函数,它返回一个指向图像存储为 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 无法分配给只读属性

为@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;
4

2 回答 2

2

您不能使用这种方式更改数据的地址,内存已经分配并且bitmap32不允许替换其地址。

但是您可以在此位置移动存储的数据,就像(但反向)您已经为存储所做的那样(但反向):

 Move(p^, NewBitmap32.Bits^,  256*256*4);
于 2019-01-31T06:11:34.407 回答
1

虽然我不想质疑您将位图存储为位流的需求,但也应该可以像这样克隆原始位图:

NewBitmap32 := TBitmap32.Create;
NewBitmap32.Assign(OriginalBitmap);

这将在保留位图的宽度和高度(否则会丢失)方面完美地克隆位图。在内存中使用 TBitmap32 而不是纯比特流的开销很小。

于 2019-02-01T03:57:22.393 回答