代码之家  ›  专栏  ›  技术社区  ›  dummzeuch Stijn Sanders

使用Stretch将像素置于鼠标下方。比例和中心都设置为真

  •  0
  • dummzeuch Stijn Sanders  · 技术社区  · 4 年前

    我有一张写着蒂马吉的表格。该TImage设置为Align=alClient、Stretch=True、PROPICTIONAL=True和Center=True。

    在运行时,我将位图加载到该图像中。它的显示比原来的尺寸小一点,但没有失真,正如我所预料的那样。

    现在我想在按下鼠标按钮时得到鼠标下像素的坐标。这是分配给im_输入的代码。OnMouseDown:

    procedure Tf_ColorAdjustment.im_InputMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
      im_Input.Picture.Bitmap.Canvas.Pixels[X - 1, Y - 1] := clYellow;
      im_Input.Picture.Bitmap.Canvas.Pixels[X - 1, Y] := clYellow;
      im_Input.Picture.Bitmap.Canvas.Pixels[X - 1, Y + 1] := clYellow;
      im_Input.Picture.Bitmap.Canvas.Pixels[X, Y - 1] := clYellow;
      im_Input.Picture.Bitmap.Canvas.Pixels[X, Y] := clYellow;
      im_Input.Picture.Bitmap.Canvas.Pixels[X, Y + 1] := clYellow;
      im_Input.Picture.Bitmap.Canvas.Pixels[X + 1, Y - 1] := clYellow;
      im_Input.Picture.Bitmap.Canvas.Pixels[X + 1, Y] := clYellow;
      im_Input.Picture.Bitmap.Canvas.Pixels[X + 1, Y + 1] := clYellow;
    end;
    

    (这只是测试代码,看看鼠标点击的结果。我知道使用Pixels属性非常慢,但这是使受影响的像素可见的最简单方法。)

    如果所有这些标志都设置为false,这将很好,但因为位图会缩小以匹配窗口,所以像素会向左和向上移动。

    我知道我需要调整坐标,但我该怎么做呢?有RTL/VCL支持吗?有点像是一种计算时间的方法(我找不到,但可能是我忽略了它)。还是我真的需要自己编程计算?

    (我不敢相信谷歌没有找到现成的解决方案。这肯定是几十年来经常遇到的问题。)

    0 回复  |  直到 4 年前
        1
  •  4
  •   Andreas Rejbrand    4 年前

    你只需要几个减法和除法:

    function TForm1.ClientToBitmap(const P: TPoint): TPoint;
    var
      cW, cH: Integer;       // width and height of control
      bW, bH: Integer;       // width and height of bitmap
      Origin: TPointF;       // top-left pixel of bitmap in the control
      ZoomW, ZoomH: Double;  // required zoom factor to make bitmap fit horisontally or vertically
      Zoom: Double;          // zoom factor
    begin
    
      cW := Image1.Width;
      cH := Image1.Height;
      bW := Image1.Picture.Bitmap.Width;
      bH := Image1.Picture.Bitmap.Height;
    
      ZoomW := cW/bW;
      ZoomH := cH/bH;
      Zoom := Min(ZoomW, ZoomH);
    
      Origin.X := (cW - bW*Zoom) / 2;
      Origin.Y := (cH - bH*Zoom) / 2;
    
      Result.X := Round((P.X - Origin.X) / Zoom);
      Result.Y := Round((P.Y - Origin.Y) / Zoom);
    
    end;
    

    现在:

    procedure TForm1.Image1MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
      with ClientToBitmap(Point(X, Y)) do
      begin
        Image1.Picture.Bitmap.Canvas.Pixels[X - 1, Y - 1] := clBlack;
        Image1.Picture.Bitmap.Canvas.Pixels[X - 1, Y] := clBlack;
        Image1.Picture.Bitmap.Canvas.Pixels[X - 1, Y + 1] := clBlack;
        Image1.Picture.Bitmap.Canvas.Pixels[X, Y - 1] := clBlack;
        Image1.Picture.Bitmap.Canvas.Pixels[X, Y] := clBlack;
        Image1.Picture.Bitmap.Canvas.Pixels[X, Y + 1] := clBlack;
        Image1.Picture.Bitmap.Canvas.Pixels[X + 1, Y - 1] := clBlack;
        Image1.Picture.Bitmap.Canvas.Pixels[X + 1, Y] := clBlack;
        Image1.Picture.Bitmap.Canvas.Pixels[X + 1, Y + 1] := clBlack;
      end;
    end;