Delphi Graphics32鼠标相对位置(相对于图层)

Delphi Graphics32鼠标相对位置(相对于图层),delphi,delphi-xe,graphics32,Delphi,Delphi Xe,Graphics32,我有一个ImgView32,它锚定到所有表单页边距。形式是最大化的 ImgView的位图不是固定的(它可以有不同的大小) 我试图用这个问题的代码在透明层上画一条线: 现在的问题是,使用精确的代码,我只能在左上角绘制,如下图所示: 如您所见,这些线只能在左上角绘制。 如果我试图给起点和终点增加一些价值,整个事情就会变得疯狂。因此,我必须找到一种方法,以这样的方式转换点,用户将能够只绘制中心矩形的内部(在图像中可见) 我没有主意了 请帮忙 这是整个单元: unit MainU; interfac

我有一个ImgView32,它锚定到所有表单页边距。形式是最大化的

ImgView的位图不是固定的(它可以有不同的大小)

我试图用这个问题的代码在透明层上画一条线:

现在的问题是,使用精确的代码,我只能在左上角绘制,如下图所示:

如您所见,这些线只能在左上角绘制。 如果我试图给起点和终点增加一些价值,整个事情就会变得疯狂。因此,我必须找到一种方法,以这样的方式转换点,用户将能够只绘制中心矩形的内部(在图像中可见)

我没有主意了

请帮忙

这是整个单元:

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;