我正在尝试将 RotationLayer 与常规 TBitmapLayer 结合起来,以便能够尽可能地使用 ImgView32 图层。
所以我的想法是:
- 我有一个 TBitmapLayer(我需要它是 BitmapLayer,因为我用它做的不仅仅是旋转)。它加载了 BMP 图像
- 我在表单上放置了一个 TGaugeBar(就像 GR32 示例中的一样)
- 当鼠标按下该仪表时,我开始进行计算:我创建一个 RotationLayer,在其中放置原始 BitmapLayer.Bitmap 的内容
- 仪表的 OnChange,我使用在 MouseDown 中创建的 RotLayer 对象并给它一个角度,并将选择分配为 TBitmap,RotLayer.Bitmap
- 在 MouseUp 上,我释放了使用的临时 RotationLayer 对象
所以基本上:将图像从实际层移动到临时旋转层,在那里进行旋转,然后,完成后,将旋转后的图像移回 BitmapLayer ...
所以最后,我的逻辑似乎有效,除了我需要使用另一个 SO 问题中提供的函数手动在 BitmapLayer 上进行实际旋转(链接如下)。因为看起来rotationLayer实际上并没有旋转它的位图中的图像。它似乎只显示它旋转...
现在我的问题是:
- 我需要能够“调整”原始 TBitmapLayer 的大小,这样它就不会裁剪旋转的图像以适合旧的 BitmapLayer
- 显示rotationLayer 时,我使用BitmapCenter 将其显示在初始BitmapLayer 的顶部(我找不到另一种将其定位在我想要的位置的方法)。然而这个 BitmapCenter 似乎有两种用途:一种是定位图层,另一种是设置旋转所围绕的点。我怎样才能仍然将旋转层精确地定位在原始 BitmapLayer 的顶部,并且仍然在 Bitmap 中间有 BitmapCenter(旋转中心)?
- 似乎当我开始旋转时,旋转层被创建并加载了我的位图,我认为 alphaChannel 发生了一些事情,因为我认为图像变得有点暗和半透明,每次我将 BitmapLayer.Bitmap 分配给 RotationLayer .位图。我注意到,通过注释 MasterAlpha:=200 行,图像不会失去亮度,但现在当 RotationLayer 可见时,图层矩形的空白部分变为黑色。所以看起来很糟糕......而且当我执行 MouseUP 时(所以当我将旋转的位图分配给 BitmapLayer.Bitmap 时,一些黑线在旋转图像的外部仍然可见,因此在空白区域中)。关于如何保持原始图像干净的任何建议?
请帮助我解决这三个问题。
到目前为止的工作代码是:
procedure TMainForm.myrotMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
l,r,t,b:single;
flrect:TFloatRect;
begin
ro:=TRotlayer.Create(imgView.Layers);
ro.Bitmap:=TBitmap32.Create;
with ro.Bitmap do
begin
BeginUpdate;
ro.Bitmap.Assign((Selection as TBitmapLayer).Bitmap);
TLinearResampler.Create(ro.Bitmap);
//ensure good looking edge, dynamic alternative to SetBorderTransparent
TCustomResampler(ro.Bitmap.Resampler).PixelAccessMode := pamTransparentEdge;
ro.BitmapCenter := FloatPoint(-(Selection as TBitmapLayer).Location.Left, -(Selection as TBitmapLayer).Location.Top);
// MasterAlpha := 200;
FrameRectS(BoundsRect, $FFFFFFFF);
DrawMode := dmBlend;
EndUpdate;
Changed;
end;
ro.Scaled := True;
(Selection as TBitmapLayer).Bitmap.Assign(ro.Bitmap);
end;
procedure TMainForm.myrotChange(Sender: TObject);
begin
ro.Angle := myRot.Position;
(Selection as TBitmapLayer).Bitmap.Assign(ro.Bitmap);
end;
procedure TMainForm.myrotMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
bmx:=TBitmap32.Create;
bmx.Assign((Selection as TBitmapLayer).Bitmap);
RotateBitmap(bmx, -(Round(ro.Angle)), false, clWhite32, true);
(Selection as TBitmapLayer).Bitmap.Assign(bmx);
bmx.Free;
ro.Free;
end;
RotateBitmap 函数是从这个SO question中挑选出来的
旋转透明图像时也存在问题...使用上面的代码自行测试它们并加载一些具有透明度的PNG,您就会理解问题所在。