Как создать Bitmap32 из массива битов? - PullRequest
0 голосов
/ 31 января 2019

У меня есть функция, которая возвращает указатель на память, в которой изображение хранится как 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;

Ответы [ 2 ]

0 голосов
/ 01 февраля 2019

Хотя я не хочу подвергать сомнению ваши потребности в отношении сохранения растрового изображения как битового потока, также должна быть возможность клонировать исходное растровое изображение следующим образом:

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

Это идеально клонирует растровое изображениес точки зрения сохранения ширины и высоты растрового изображения (которое в противном случае теряется).Затраты на использование TBitmap32 в памяти вместо чистого потока битов минимальны.

0 голосов
/ 31 января 2019

Вы не можете изменить адрес данных, используя этот способ, память уже выделена, и bitmap32 не позволяет заменить ее адрес.

Но вы можете перемещать сохраненные данные в этом месте, как (но в обратном порядке.направление) вы уже сделали для хранения, но в обратном направлении:

 Move(p^, NewBitmap32.Bits^,  256*256*4);
...