Причина и быстрое исправление:
Проблема в этой части:
Rect(0,MainBitmap.Height,BitmapToAdd.Width,BitmapToAdd.Height)
Вы делаете прямоугольник, из которого top
- это общая высотарезультирующее изображение, а внизу - высота растрового изображения для добавления.Таким образом, этот прямоугольник в основном перевернут (его нижняя часть выше его верхней части).
И, вероятно, также деформируется, поскольку высота этого прямоугольника не является высотой растрового изображения для добавления.
Быстрое исправление будет:
Rect(0,Result.Height- BitmapToAdd.Height,BitmapToAdd.Width,Result.Height)
Другие проблемы и путаница:
Но я думаю, что причина вашей путаницы в том, что вы думаете, что Result и MainBitmap - это две разные битовые карты, хотя на самом деле они обе являются ссылками на одну и ту же битовую карту.Задание, которое вы делаете в начале, просто копирует ссылку, а не фактический объект TBitmap.
Кроме того, вы смешиваете «высоту» и «низ».TRect ожидает, что вы установите верхнюю и нижнюю координаты, а не верх и высоту.Это, вместе с предыдущей проблемой, приводит не только к тому, что растровое изображение переворачивается вверх ногами, но также к тому, что оно будет растягиваться и частично покрывать предыдущие изображения.Чем больше изображений вы добавите, тем яснее будет этот эффект.
Лично я считаю, что в этом сценарии гораздо эффективнее изменить существующее растровое изображение, главным образом потому, что в противном случае вам пришлось бы очистить свое старое растровое изображение.время, плюс у вас есть функция, которая волшебным образом создает растровые изображения.Возникает вопрос о владении объектами растрового изображения, и с этим возникает риск утечек памяти, что не очень хорошо, особенно при работе с большими растровыми изображениями.
Моя предложенная версия:
Итак, я бы просто сделал это процедурой, в которой первое растровое изображение изменяется путем добавления второго растрового изображения к нему.
В приведенной ниже версии я также использовал Canvas.ClipRect
, который для растрового изображения по сути является ограничивающим прямоугольником растрового изображения.И затем я использовал OffsetRect
, чтобы «переместить» этот прямоугольник (увеличив его верхний Y и нижний Y).
Делая это в отдельной переменной, вы можете получить относительно чистую версию по сравнению с быстрым исправлением, которое я представил выше, потому что вы можете использовать размеры MainBitmap до его фактического изменения.
procedure AppendBitmap(const MainBitmap: TBitmap; const BitmapToAdd:
TBitmap);
var
TargetRect: TRect;
begin
// Widen the main bitmap if needed
if BitmapToAdd.Width > MainBitmap.Width then
MainBitmap.Width := BitmapToAdd.Width;
// Set TargetRect to the right size
TargetRect := BitmapToAdd.Canvas.ClipRect;
// And then to the right position
OffsetRect(TargetRect, 0, MainBitmap.Height);
// Make room for the bitmap to add
MainBitmap.Height := MainBitmap.Height + BitmapToAdd.Height;
// Draw it in the created space
MainBitmap.Canvas.CopyRect(
TargetRect,
BitmapToAdd.Canvas,
BitmapToAdd.Canvas.ClipRect
);
end;
А если хотите, вы можете создать функцию-обертку с подписью оригинала, которая создаст копию основного изображения и вернет ее.Обратите внимание, что MainBitmap и результат этой функции больше не являются одним и тем же растровым изображением, и вы должны быть уверены, что правильно освободили их оба, когда закончите.
function ConcatenateBitmaps(const MainBitmap: TBitmap; const BitmapToAdd:
TBitmap): TBitmap;
begin
Result := TBitmap.Create;
Result.Assign(MainBitmap);
AppendBitmap(Result, BitmapToAdd);
end;
PS: мне нравятся вопросыкак то, из чего я чему-то учусь.Я никогда не понимал, что вы можете перевернуть изображение, перевернув прямоугольник, переданный в CopyRect.: D