绘制图层是指用户可以手动绘制线条、圆形或其他形状的图层。普通层是指 graphics32 层示例中描述的层(可以在运行时使用鼠标事件移动或调整大小的层)所以我很难组合这两种类型的层。在我的测试项目中,现在,我假设我只有一个绘图层和多个 PNG 层。因此,在我的项目中,我在 OnFormCreate 中为 ImgView32 设置了属性,例如:
procedure TForm1.FormCreate(Sender: TObject);
begin
AWidth:= 800;
AHeight:= 600;
FillColor:=clWhite;
with ImgView do
begin
Selection := nil;
RBLayer := nil;
Layers.Clear;
Scale := 1;
Scaled:=true;
Bitmap.SetSize(AWidth, AHeight);
Bitmap.DrawMode := dmTransparent;
Bitmap.Clear(FillColor);
end;
end;
在此之后,单击一个按钮,我添加了一些图层(包含透明的 PNG 图像)。所以就像这样
procedure TForm1.Button1Click(Sender: TObject);
begin
AddPNGLayer(1);
AddPNGLayer(2);
AddDrawingLayer;
AddPNGLayer(3);
end;
(我不会在这里详细说明添加PNG图层以保持问题简短。我只会说它使用与drawingLayer中使用的事件不同的onMouseDown事件(layerMouseDown))并且AddDrawingLayer如下:
procedure TForm1.AddDrawingLayer;
var
P:TPoint;
jumaH, JumaW, W, H: Single;
begin
imwidth := ImgView.Bitmap.Width;
imheight := ImgView.Bitmap.Height;
xofx := (ImgView.ClientWidth - 17 - imwidth) div 2; // substracting the width of the scrollbar
yofy := (ImgView.ClientHeight - 17 - imheight) div 2; // same here with height
bm32 := TBitmap32.Create;
bm32.DrawMode := dmTransparent;
bm32.SetSize(ImgView.Bitmap.Width,ImgView.Bitmap.Height);
bm32.Canvas.Pen.Width := 3;
bm32.Canvas.Pen.Color := clBlack32;//pencolor;
BB := TBitmapLayer.Create(ImgView.Layers);
try
BB.Bitmap.DrawMode := dmTransparent;
BB.Bitmap.SetSize(imwidth,imheight);
BB.Bitmap.Canvas.Pen.Width := 3;
BB.Bitmap.Canvas.Pen.Color := pencolor;
BB.Location := GR32.FloatRect(0, 0, imwidth, imheight);
BB.Scaled := true;
BB.Tag:=3;
//// Selection:=BB; // if I use this then I cant draw because the entire layer is selected and the mouseDown event works as a mover/resizer
// BB.OnMouseDown := DrLayerMouseDown;
// BB.OnMouseUp := DrLayerMouseUp;
// BB.OnMouseMove := DrLayerMouseMove;
// BB.OnPaint := DrLayerOnPaint;
RBLayer:=nil;
EdLayerIndex.Text:=IntToStr(BB.Index);
finally
BB.Free;
end;
FDrawingLine := false;
// swapBuffers32; // needed when mouse events are active
end;
EdLayerIndex 是一个编辑框,我在其中显示创建/选择的图层索引(用于调试)
- 正如您在上面看到的,如果我保留
Selection:=BB
然后RBLayer:=nil
drawingLayer 只能移动和调整大小,所以这不是一个好的解决方案,因为我想在这个特定图层中使用我的鼠标事件来绘制。 如果我仅
RBLayer:=nil
在保留的同时进行评论,Selection:=BB
则绘图层不再可移动,但我无法选择绘图层下的其他图层。我只能访问顶层(最后添加的PNG层)如果我发表评论,
Selection:=BB
那么我无法用鼠标选择其他图层。所以在我的例子中,我在drawingLayer之前声明了2个png图层,在它之后声明了一个。在运行时我只能选择最后一层(绘图层“上方”的那个)所以这也不是一个解决方案。
当我单击绘图层(或以其他方式选择它,例如在列表框或其他东西中)时,我该如何做到这一点,drawingLayer 将无法移动,但我的绘图鼠标事件会启动?在这一切期间,我可以随时离开drawingLayer,并选择其他图层来移动和玩耍。所以基本上我需要一个特定的层不要像其他层一样。
我想要实现的是使用 graphics32 具有经典的类似 Photoshop 或 paint.net 的行为。这些层属性如何实际工作非常令人困惑。
到目前为止,我想出了如何在透明层上动态绘制(线、圆、矩形)(使用鼠标事件)。所以我可以有一个绘图层。绘图发生在我的DrLayerMouseDown
, DrLayerMouseUp
, DrLayerMouseMove
,DrLayerPaint
事件中。但我似乎无法理解如何将这样的绘图层与常规的可移动/可调整大小的层结合起来。
其余代码(如setSelection
和)大部分取自 graphics32 库的图层示例RBResizing
。layerMouseDown
编辑
为了测试你的想法layerOptions
,我做了以下事情:
1.开始一个新的测试项目,上面有一个ImgView,还有一个按钮
2.在创建时我使用了和以前一样的代码
3.OnButtonClick 我使用修改后的 AddDrawingLayer 添加了一个图层,如下所示:
...
BB.Scaled := true;
Selection:=BB;
Selection.LayerOptions:=Selection.LayerOptions and (not LOB_MOUSE_EVENTS); // I also tried it with BB instead of Selection
BB.OnMouseDown := DrLayerMouseDown;
BB.OnMouseUp := DrLayerMouseUp;
BB.OnMouseMove := DrLayerMouseMove;
BB.OnPaint := DrLayerOnPaint;
...
期望它对鼠标事件不敏感。但是该层仍然是可移动的,而不是对鼠标不敏感。所以就像我什么都没做
所以我不认为它对我使用这个选项有帮助,除非我做错了所以在图层的 onCreate 上,这个选项似乎没有坚持。但是如果我禁用所有图层的鼠标事件,就像在下一个编辑中一样,那么绘图层就会被禁用(鼠标事件)
编辑
我还尝试了另一个测试项目,同样的想法:相同的 onCreate 和 onButtonClick 我添加了 3 个图层(使用库的图层示例),每个图层都包含一个图像(这次没有绘图层,以保持简单)。然后我添加了一个新按钮,如果单击它,将执行下一个代码:
for i := 0 to ImgView.Layers.Count-1 do
(ImgView.Layers.Items[i] as TPositionedLayer).LayerOptions:= (ImgView.Layers.Items[i] as TPositionedLayer).LayerOptions and (not LOB_MOUSE_EVENTS);
我的目的是使所有图层对鼠标事件不敏感。我成功了,单击新按钮后,无法再选择图层,但是当我想为图层重新启用鼠标事件时(使用下一个代码 onClick 添加第三个按钮):
for i := 0 to ImgView.Layers.Count-1 do
(ImgView.Layers.Items[i] as TPositionedLayer).LayerOptions:= (ImgView.Layers.Items[i] as TPositionedLayer).LayerOptions and (LOB_MOUSE_EVENTS);
没有显示错误,但是当我尝试选择一个图层以移动它时……所有图层的图像都从视图中消失了……给我留下了一个空白背景的空白 ImgView。
我究竟做错了什么?为了执行您对 LayerOptions 的建议,我需要能够禁用所有图层的鼠标事件,并为特定图层启用鼠标事件,然后在完成编辑后,我需要能够重新启用鼠标事件对于所有图层,但我猜我做错了。