Delphi Graphics32鼠标相对位置(相对于图层)
我有一个ImgView32,它锚定到所有表单页边距。形式是最大化的 ImgView的位图不是固定的(它可以有不同的大小) 我试图用这个问题的代码在透明层上画一条线: 现在的问题是,使用精确的代码,我只能在左上角绘制,如下图所示: 如您所见,这些线只能在左上角绘制。 如果我试图给起点和终点增加一些价值,整个事情就会变得疯狂。因此,我必须找到一种方法,以这样的方式转换点,用户将能够只绘制中心矩形的内部(在图像中可见) 我没有主意了 请帮忙 这是整个单元:Delphi Graphics32鼠标相对位置(相对于图层),delphi,delphi-xe,graphics32,Delphi,Delphi Xe,Graphics32,我有一个ImgView32,它锚定到所有表单页边距。形式是最大化的 ImgView的位图不是固定的(它可以有不同的大小) 我试图用这个问题的代码在透明层上画一条线: 现在的问题是,使用精确的代码,我只能在左上角绘制,如下图所示: 如您所见,这些线只能在左上角绘制。 如果我试图给起点和终点增加一些价值,整个事情就会变得疯狂。因此,我必须找到一种方法,以这样的方式转换点,用户将能够只绘制中心矩形的内部(在图像中可见) 我没有主意了 请帮忙 这是整个单元: unit MainU; interfac
unit MainU;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs,GR32, GR32_Image, GR32_Layers, GR32_Backends, GR32_PNG, StdCtrls,
ExtCtrls;
type
TForm5 = class(TForm)
ImgView: TImgView32;
Button1: TButton;
Memo: TMemo;
Edit3: TEdit;
Button2: TButton;
RadioGroup1: TRadioGroup;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure ImgViewPaintStage(Sender: TObject; Buffer: TBitmap32;
StageNum: Cardinal);
procedure ImgViewResize(Sender: TObject);
private
{ Private declarations }
FStartPoint, FEndPoint: TPoint;
FDrawingLine: boolean;
bm32: TBitmap32;
BL : TBitmapLayer;
FSelection: TPositionedLayer;
public
{ Public declarations }
procedure AddLineToLayer;
procedure AddCircleToLayer;
procedure SwapBuffers32;
procedure LayerMouseDown(Sender: TObject; Buttons: TMouseButton;Shift: TShiftState; X, Y: Integer);
procedure LayerMouseUp(Sender: TObject; Buttons: TMouseButton;Shift: TShiftState; X, Y: Integer);
procedure LayerMouseMove(Sender: TObject; Shift: TShiftState;X, Y: Integer);
procedure LayerOnPaint(Sender: TObject; Buffer: TBitmap32);
procedure SetSelection(Value: TPositionedLayer);
property Selection: TPositionedLayer read FSelection write SetSelection;
Procedure SelectGraficLayer(idu:string);
procedure AddTransparentPNGlayer;
end;
var
Form5: TForm5;
implementation
{$R *.dfm}
var
imwidth: integer;
imheight: integer;
OffsX, OffsY: Integer;
const
penwidth = 3;
pencolor = clBlue; // Needs to be a VCL color!
procedure TForm5.AddLineToLayer;
begin
bm32.Canvas.Pen.Color := pencolor;
bm32.Canvas.Pen.Width := penwidth;
bm32.Canvas.MoveTo(FStartPoint.X, FStartPoint.Y);
bm32.Canvas.LineTo(FEndPoint.X, FEndPoint.Y);
end;
procedure TForm5.FormCreate(Sender: TObject);
var
P: TPoint;
W, H: Single;
begin
imwidth := Form5.ImgView.Width;
imheight := Form5.ImgView.Height;
with ImgView.PaintStages[0]^ do
begin
if Stage = PST_CLEAR_BACKGND then Stage := PST_CUSTOM;
end;
bm32 := TBitmap32.Create;
bm32.DrawMode := dmTransparent;
bm32.SetSize(imwidth,imheight);
bm32.Canvas.Pen.Width := penwidth;
bm32.Canvas.Pen.Color := pencolor;
with ImgView do
begin
Selection := nil;
Layers.Clear;
Scale := 1;
Scaled := True;
Bitmap.DrawMode := dmTransparent;
Bitmap.SetSize(imwidth, imheight);
Bitmap.Canvas.Pen.Width := 4;//penwidth;
Bitmap.Canvas.Pen.Color := clBlue;
Bitmap.Canvas.FrameRect(Rect(20, 20, imwidth-20, imheight-20));
Bitmap.Canvas.TextOut(15, 32, 'ImgView');
end;
AddTransparentPNGLayer;
BL := TBitmapLayer.Create(ImgView.Layers);
try
BL.Bitmap.DrawMode := dmTransparent;
BL.Bitmap.SetSize(imwidth,imheight);
BL.Bitmap.Canvas.Pen.Width := penwidth;
BL.Bitmap.Canvas.Pen.Color := pencolor;
BL.Location := GR32.FloatRect(0, 0, imwidth, imheight);
BL.Scaled := False;
BL.OnMouseDown := LayerMouseDown;
BL.OnMouseUp := LayerMouseUp;
BL.OnMouseMove := LayerMouseMove;
BL.OnPaint := LayerOnPaint;
except
Edit3.Text:=IntToStr(BL.Index);
BL.Free;
raise;
end;
FDrawingLine := false;
SwapBuffers32;
end;
procedure TForm5.FormDestroy(Sender: TObject);
begin
bm32.Free;
BL.Free;
end;
procedure TForm5.ImgViewPaintStage(Sender: TObject; Buffer: TBitmap32;
StageNum: Cardinal);
const //0..1
Colors: array [Boolean] of TColor32 = ($FFFFFFFF, $FFB0B0B0);
var
R: TRect;
I, J: Integer;
OddY: Integer;
TilesHorz, TilesVert: Integer;
TileX, TileY: Integer;
TileHeight, TileWidth: Integer;
begin
TileHeight := 13;
TileWidth := 13;
TilesHorz := Buffer.Width div TileWidth;
TilesVert := Buffer.Height div TileHeight;
TileY := 0;
for J := 0 to TilesVert do
begin
TileX := 0;
OddY := J and $1;
for I := 0 to TilesHorz do
begin
R.Left := TileX;
R.Top := TileY;
R.Right := TileX + TileWidth;
R.Bottom := TileY + TileHeight;
Buffer.FillRectS(R, Colors[I and $1 = OddY]);
Inc(TileX, TileWidth);
end;
Inc(TileY, TileHeight);
end;
end;
procedure TForm5.ImgViewResize(Sender: TObject);
begin
OffsX := (ImgView.ClientWidth - imwidth) div 2;
OffsY := (ImgView.ClientHeight - imheight) div 2;
BL.Location := GR32.FloatRect(OffsX, OffsY, imwidth+OffsX, imheight+OffsY);
end;
procedure TForm5.LayerMouseDown(Sender: TObject; Buttons: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
FStartPoint := Point(X-OffsX, Y-OffsY);
FDrawingLine := true;
end;
procedure TForm5.LayerMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
if FDrawingLine then
begin
SwapBuffers32;
BL.Bitmap.Canvas.Pen.Color := pencolor;
BL.Bitmap.Canvas.MoveTo(FStartPoint.X-OffsX, FStartPoint.Y-OffsY);
BL.Bitmap.Canvas.LineTo(X-OffsX, Y-OffsY);
end;
end;
procedure TForm5.LayerMouseUp(Sender: TObject; Buttons: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
FDrawingLine := false;
FEndPoint := Point(X-OffsX, Y-OffsY);
AddLineToLayer;
SwapBuffers32;
end;
procedure TForm5.LayerOnPaint(Sender: TObject; Buffer: TBitmap32);
begin
SwapBuffers32;
end;
procedure TForm5.SetSelection(Value: TPositionedLayer);
begin
if Value <> FSelection then
begin
FSelection := Value;
end;
end;
procedure TForm5.SwapBuffers32;
begin
TransparentBlt(
BL.Bitmap.Canvas.Handle, 0, 0, BL.Bitmap.Width, BL.Bitmap.Height,
bm32.Canvas.Handle, 0, 0, bm32.Width, bm32.Height, clWhite);
end;
procedure TForm5.AddTransparentPNGlayer;
var
mypng:TPortableNetworkGraphic32;
B : TBitmapLayer;
P: TPoint;
W, H: Single;
begin
try
mypng := TPortableNetworkGraphic32.Create;
mypng.LoadFromFile('C:\Location\Of\ATransparentPNGFile.png');
B := TBitmapLayer.Create(ImgView.Layers);
with B do
try
mypng.AssignTo(B.Bitmap);
Bitmap.DrawMode := dmBlend;
with ImgView.GetViewportRect do
P := ImgView.ControlToBitmap(GR32.Point((Right + Left) div 2, (Top + Bottom) div 2));
W := Bitmap.Width * 0.5;
H := Bitmap.Height * 0.5;
Location := GR32.FloatRect(P.X - W, P.Y - H, P.X + W, P.Y + H);
Scaled := True;
OnMouseDown := LayerMouseDown;
except
Free;
raise;
end;
Selection := B;
Edit3.Text:=IntToStr(B.Index);
finally
mypng.Free;
end;
end;
end.
unitmainu;
接口
使用
窗口、消息、系统工具、变体、类、图形、控件、窗体、,
对话框,GR32,GR32_图像,GR32_层,GR32_后端,GR32_PNG,stdctrl,
ExtCtrls;
类型
TForm5=类(TForm)
ImgView:TImgView32;
按钮1:t按钮;
备忘录:TMemo;
编辑3:TEdit;
按钮2:t按钮;
放射组1:传统组;
过程表单创建(发送方:ToObject);
销毁程序表(发送方:TObject);
程序按钮1点击(发送方:ToObject);
程序按钮2点击(发送者:对象);
过程ImgViewPaintStage(发送方:TObject;缓冲区:TBitmap32;
StageNum:基数);
程序ImgViewResize(发送方:TObject);
私有的
{私有声明}
FStartPoint,FEndPoint:TPoint;
FDrawingLine:布尔值;
bm32:TBitmap32;
BL:TBitmapLayer;
FSelection:TPositionedLayer;
公众的
{公开声明}
程序AddLineToLayer;
程序AddCircleToLayer;
程序SwapBuffers32;
过程层UseDown(发送方:ToObject;按钮:TMouseButton;Shift:tShift状态;X,Y:整数);
过程层使用(发送方:ToObject;按钮:TMouseButton;Shift:tShift状态;X,Y:整数);
过程层MoveMove(发送方:ToObject;Shift:TShiftState;X,Y:整数);
程序LayerOnPaint(发送方:TObject;缓冲区:TBitmap32);
程序设置选择(值:TPositionedLayer);
属性选择:TPositionedLayer read FSelection write SetSelection;
过程SelectGraficLayer(idu:字符串);
程序添加透明层;
结束;
变量
表5:TForm5;
实施
{$R*.dfm}
变量
imwidth:整数;
imheight:整数;
OffsX,OffsY:整数;
常数
笔宽=3;
铅笔色=蓝色;//需要是VCL颜色!
程序TForm5.AddLineToLayer;
开始
bm32.Canvas.Pen.Color:=铅笔色;
bm32.Canvas.Pen.Width:=penwidth;
bm32.Canvas.MoveTo(FStartPoint.X,FStartPoint.Y);
bm32.Canvas.LineTo(FEndPoint.X,FEndPoint.Y);
结束;
过程TForm5.FormCreate(发送方:TObject);
变量
P:TPoint;
W、 H:单程;
开始
imwidth:=Form5.ImgView.Width;
imheight:=Form5.ImgView.Height;
使用ImgView.PaintStages[0]^do
开始
如果Stage=PST\u CLEAR\u BACKGND,则Stage:=PST\u CUSTOM;
结束;
bm32:=TBitmap32.Create;
bm32.DrawMode:=dmTransparent;
bm32.设置大小(imwidth,imheight);
bm32.Canvas.Pen.Width:=penwidth;
bm32.Canvas.Pen.Color:=铅笔色;
用ImgView做
开始
选择:=零;
层次分明;
比例:=1;
缩放:=真;
Bitmap.DrawMode:=dmTransparent;
位图.SetSize(imwidth,imheight);
Bitmap.Canvas.Pen.Width:=4//笔宽;
Bitmap.Canvas.Pen.Color:=clBlue;
FrameRect(Rect(20,20,imwidth-20,imheight-20));
位图.Canvas.TextOut(15,32,'ImgView');
结束;
添加透明层;
BL:=TBitmapLayer.Create(ImgView.Layers);
尝试
BL.Bitmap.DrawMode:=dmTransparent;
BL.Bitmap.SetSize(imwidth,imheight);
BL.Bitmap.Canvas.Pen.Width:=penwidth;
BL.Bitmap.Canvas.Pen.Color:=铅笔色;
BL.位置:=GR32.FloatRect(0,0,imwidth,imheight);
BL.缩放:=假;
BL.OnMouseDown:=LayerMouseDown;
BL.OnMouseUp:=LayerMouseUp;
BL.OnMouseMove:=LayerMouseMove;
BL.OnPaint:=LayerOnPaint;
除了
Edit3.Text:=IntToStr(BL.Index);
BL.自由;
提高;
结束;
FDrawingLine:=假;
SwapBuffers32;
结束;
程序TForm5.FormDestroy(发送方:ToObject);
开始
bm32.免费;
BL.自由;
结束;
过程TForm5.ImgViewPaintStage(发送方:TObject;缓冲区:TBitmap32;
StageNum:基数);
常数//0..1
颜色:TColor32=($FFFFFFFF,$FFB0B0)的数组[布尔值];
变量
R:TRect;
一、 J:整数;
奥迪:整数;
TilesHorz,TilesVert:整数;
TileX,TileY:整数;
TileHeight,TileWidth:整数;
开始
瓷砖高度:=13;
波浪宽度:=13;
TilesHorz:=缓冲区宽度div TileWidth;
TilesVert:=缓冲区高度div TileHeight;
TileY:=0;
对于J:=0到TilesVert do
开始
蒂莱克斯:=0;
奥迪:=J和1美元;
对于I:=0到TilesHorz do
开始
R.左:=TileX;
R.顶部:=TileY;
R.右侧:=TileX+TileWidth;
R.底部:=瓷砖+瓷砖高度;
FillRectS(R,Colors[I和$1=OddY]);
公司(TileX,TileWidth);
结束;
公司(TileY,TileHeight);
结束;
结束;
程序TForm5.ImgViewResize(发送方:TObject);
开始
OffsX:=(ImgView.ClientWidth-imwidth)div 2;
偏移量:=(ImgView.ClientHeight-imheight)第2分区;
BL.位置:=GR32.FloatRect(OffsX,OffsY,imwidth+OffsX,imheight+OffsY);
结束;
步骤t用于M5.LayerMouseDown(发送方:ToObject;按钮:TMouseButton;
移位:t移位状态;X,Y:整数);
开始
FStartPoint:=点(X-offx,Y-OffsY);
FDrawingLine:=真;
结束;
步骤t用于m5.LayerMove(发送方:ToObject;Shift:TShiftState;X,Y:整数);
开始
如果是FDrawingLine,那么
开始
SwapBuffers32;
BL.Bitmap.Canvas.Pen.Color:=铅笔色;
BL.Bitmap.Canvas.MoveTo(FStartPoint.X-OffsX,FStartPoint.Y-OffsY);
BL.Bitmap.Canvas.LineTo(X-OffsX,Y-OffsY);
结束;
结束;
步骤t用于m5.LayerMouseUp(发送方:ToObject;按钮:TMouseButton;
移位:t移位状态;X,Y:整数);
开始
FDrawingLine:=假;
procedure TForm5.ImgViewResize(Sender: TObject);
begin
OffsX := (ImgView.ClientWidth - imwidth) div 2;
OffsY := (ImgView.ClientHeight - imheight) div 2;
BL.Location := GR32.FloatRect(OffsX, OffsY, imwidth+OffsX, imheight+OffsY);
end;
procedure TForm5.SwapBuffers32;
begin
TransparentBlt(
BL.Bitmap.Canvas.Handle, 0, 0, BL.Bitmap.Width, BL.Bitmap.Height,
bm32.Canvas.Handle, 0, 0, bm32.Width, bm32.Height, clWhite);
end;
procedure TForm5.LayerMouseDown(Sender: TObject; Buttons: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
FStartPoint := Point(X-OffsX, Y-OffsY);
FDrawingLine := true;
end;
procedure TForm5.LayerMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
if FDrawingLine then
begin
SwapBuffers32;
BL.Bitmap.Canvas.Pen.Color := pencolor;
BL.Bitmap.Canvas.MoveTo(FStartPoint.X, FStartPoint.Y);
BL.Bitmap.Canvas.LineTo(X-OffsX, Y-OffsY);
end;
end;
procedure TForm5.LayerMouseUp(Sender: TObject; Buttons: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
FDrawingLine := false;
FEndPoint := Point(X-OffsX, Y-OffsY);
AddLineToLayer;
SwapBuffers32;
end;
procedure TForm5.LayerOnPaint(Sender: TObject; Buffer: TBitmap32);
begin
SwapBuffers32;
end;
procedure TForm5.AddLineToLayer;
begin
bm32.Canvas.Pen.Color := pencolor;
bm32.Canvas.Pen.Width := penwidth;
bm32.Canvas.MoveTo(FStartPoint.X, FStartPoint.Y);
bm32.Canvas.LineTo(FEndPoint.X, FEndPoint.Y);
end;
procedure TForm5.LayerMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if FDrawingLine then
begin
SwapBuffers32;
BL.Bitmap.Canvas.Pen.Color := pencolor;
// BL.Bitmap.Canvas.MoveTo(FStartPoint.X-OffsX, FStartPoint.Y-OffsY);
BL.Bitmap.Canvas.MoveTo(FStartPoint.X, FStartPoint.Y);
BL.Bitmap.Canvas.LineTo(X-OffsX, Y-OffsY);
end;
end;
procedure TForm5.LayerMouseUp(Sender: TObject; Buttons: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if FDrawingLine then
begin
FDrawingLine := false;
FEndPoint := Point(X-OffsX, Y-OffsY);
AddLineToLayer;
SwapBuffers32;
end;
end;
procedure TForm5.ImgViewResize(Sender: TObject);
begin
// centering the drawing area
OffsX := (ImgView.ClientWidth - imwidth) div 2;
OffsY := (ImgView.ClientHeight - imheight) div 2;
BL.Location := GR32.FloatRect(OffsX, OffsY, imwidth+OffsX, imheight+OffsY);
end;