gpt4 book ai didi

delphi - 为什么在delphi 10.3中CopyRect翻转了第二张图像?

转载 作者:行者123 更新时间:2023-12-03 14:58:38 27 4
gpt4 key购买 nike

我想对我的页面进行屏幕截图并将结果放入位图中,因为页面上有滚动条,所以我必须截取多个屏幕截图,并且我想合并这些位图。

如果使用此代码进行屏幕截图并保存:Take a screenshot of a particular area in Delphi 7

我使用代码从本页 http://www.delphigroups.info/2/8/309463.html 合并它们

如果我直接复制它,则会导致使用第一个图像,而使用第二个图像的白色矩形。所以我尝试稍微改变一下,现在我将两个图像放在一个文件中。

这是我用来连接位图的代码:

    function ConcatenateBitmaps(const MainBitmap: TBitmap; const BitmapToAdd: 
TBitmap): TBitmap;
begin
Result := MainBitmap;

If BitmapToAdd.Width > MainBitmap.Width then
Result.Width := BitmapToAdd.Width;

Result.Height := MainBitmap.Height + MainBitmap.Height;
Result.Canvas.CopyRect(
Rect(0,MainBitmap.Height,BitmapToAdd.Width,BitmapToAdd.Height),
BitmapToAdd.Canvas,
Rect(0,0,BitmapToAdd.Width,BitmapToAdd.Height)
);
end;

问题是第二个图像正在垂直和水平翻转;

我在这里做错了什么?

编辑:结果的例子,第一张图片是好的,第二张图片是翻转的: enter image description here

正如我现在所看到的,我的描述是错误的,它是水平镜像的,垂直翻转的

最佳答案

原因和快速修复:

问题出在这部分:

Rect(0,MainBitmap.Height,BitmapToAdd.Width,BitmapToAdd.Height)

您创建一个矩形,其中顶部是结果图像的总高度,底部是要添加的位图的高度。所以这个矩形基本上是倒置的(它的底部在它的顶部之上)。

而且它也可能变形,因为该矩形的高度不是要添加的位图的高度。

快速修复是:

Rect(0,Result.Height- BitmapToAdd.Height,BitmapToAdd.Width,Result.Height)

其他问题和困惑:

但我认为您感到困惑的原因是您认为 Result 和 MainBitmap 是两个不同的位图,而实际上它们都是对同一位图的引用。您在开始时所做的分配只是复制引用,而不是实际的 TBitmap 对象。

此外,您还混淆了“高度”和“底部”。 TRect 希望您设置顶部和底部坐标,而不是顶部和高度。这与上一个问题一起,不仅导致位图颠倒,而且还会被拉伸(stretch),并部分覆盖以前的图像。添加的图像越多,效果就越清晰。

我个人认为在这种情况下修改现有位图会更有效,主要是因为否则您将不得不一直清理旧位图,而且您有一个可以神奇地创建位图的函数。您会遇到位图对象的所有权问题,以及内存泄漏的风险,这不好,尤其是在处理大型位图时。

我建议的版本:

所以,我只是将其作为一个过程,通过向其中添加第二个位图来修改第一个位图。

在下面的版本中,我还使用了 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

关于delphi - 为什么在delphi 10.3中CopyRect翻转了第二张图像?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55743717/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com