我有一个带有漫画版布局的.bmp图像。目前,我的代码是这样的。如果我右键单击并按住鼠标按钮,我可以在漫画书页面上的一个框架周围绘制一个字幕框。当我释放按钮时,它将放大到该框架。但是瞬间。我希望它具有动画效果。

因此,无需将PicRect的值设置为“END VALUE”

PicRect.Left
PicRect.right
PicRect.top
PicRect.bottom

如下面的代码所示,我需要一种缓慢到达那里的方法,某种while循环可以一次将这些值设置一次,直到达到“最终值”为止,但是我不确定100%如何计算出该数学值正在工作中。我的任何while循环尝试都没有做任何事情,只是将其放大得太远。这是过程。
procedure TZImage.MouseUp(Button: TMouseButton; Shift: TShiftState;
                      X, Y: Integer);
    var coef:Double;
    t:integer;
begin
   if FMouse=mNone then Exit;
   if x>ShowRect.Right then x:=ShowRect.Right;
   if y>ShowRect.Bottom then y:=ShowRect.Bottom;
   if FMouse=mZoom then begin  //calculate new PicRect
     t:=startx;
     startx:=Min(startx,x);
     x:=Max(t,x);
     t:=starty;
     starty:=Min(starty,y);
     y:=Max(t,y);
     FMouse:=mNone;
     MouseCapture:=False;
//enable the following if you want to zoom-out by dragging in the opposite direction}
    {     if Startx>x then begin
            DblClick;
            Exit;
         end;}
         if Abs(x-startx)<5 then Exit;
         if (x - startx < y - starty) then
         begin
           while (x - startx < y - starty) do
           begin
              x := x + 100;
              startx := startx - 100;
           end;
         end
         else if (x - startx > y - starty) then
         begin
            while (x - startx > y - starty) do
            begin
                y := y + 100;
                starty := starty - 100;
            end;
         end;


    //This is were it sets the zoom info. This is were
    //I have to change to slowly get the PICRECT.Left/right/top/bottom
         if (PicRect.Right=PicRect.Left)
         then
            coef := 100000
         else
            coef:=ShowRect.Right/(PicRect.Right-PicRect.Left);
         PicRect.Left:=Round(PicRect.Left+startx/coef);
         PicRect.Right:=PicRect.Left+Round((x-startx)/coef);
         if (PicRect.Bottom=PicRect.Top)
         then
            coef := 100000
         else
            coef:=ShowRect.Bottom/(PicRect.Bottom-PicRect.Top);
         PicRect.Top:=Round(PicRect.Top+starty/coef);
         PicRect.Bottom:=PicRect.Top+Round((y-starty)/coef);
       end;
       if FMouse=mDrag then begin
         FMouse:=mNone;
         Canvas.Pen.Mode:=pmCopy;
         Screen.Cursor:=crDefault;
       end;
       Invalidate;
    end;

我相信可以在上面的代码中完成此操作。但也想添加它以防万一。
type
    TZImage = class(TGraphicControl)
  private
    FBitmap        : TBitmap;
    PicRect        : TRect;
    ShowRect       : TRect;
    FShowBorder    : boolean;
    FBorderWidth   : integer;
    FForceRepaint  : boolean;
    FMouse         : (mNone, mDrag, mZoom);
    FProportional  : boolean;
    FDblClkEnable  : boolean;
    startx, starty,
    oldx, oldy     : integer;

感谢您为使此工作正常进行的任何帮助。

最佳答案

我有一些建议。我不确定它们是否足以解决您的问题,但希望它能帮助您实现目标。

首先,您的while循环正在做很多有趣的事情:

if (x - startx < y - starty) then
     begin
       while (x - startx < y - starty) do
       begin
          x := x + 100;
          startx := startx - 100;
       end;
     end
else if (x - startx > y - starty) then
     /* similar code */

注意x - start == y - starty的大小写被完全忽略了。我不知道这是否重要。

其次,这可能没有循环就可以重写。我在这里猜测,需要做一些测试才能确定这是否正确,但这听起来像是正确的道路:
foo := (x - startx) - (y - starty)
if (foo > 200 || foo < -200)
    bar = foo / 200  # I assume integer truncation
    x += bar * 100
    startx += bar * 100

我不完全确定为什么您要使(x-startx) - (y-starty)彼此之间的距离不超过200;也许还有更好的东西。

这部分代码有点令人困惑:
if (PicRect.Right=PicRect.Left)
     then
        coef := 100000
     else
        coef:=ShowRect.Right/(PicRect.Right-PicRect.Left);
     PicRect.Left:=Round(PicRect.Left+startx/coef);
     PicRect.Right:=PicRect.Left+Round((x-startx)/coef);
     if (PicRect.Bottom=PicRect.Top)
     then
        coef := 100000
     else
        coef:=ShowRect.Bottom/(PicRect.Bottom-PicRect.Top);
     PicRect.Top:=Round(PicRect.Top+starty/coef);
     PicRect.Bottom:=PicRect.Top+Round((y-starty)/coef);
   end;

是否应该从更早的版本覆盖coef?或者,您应该代替计算coefxcoefy,然后选择(更大?更小?接近100000?)值来同时为.Left.Right.Top.Bottom计算服务吗?我必须认为,此代码按其现状,更可能导致您的内容难以以某种方式引起用户和作者双方的尴尬拉伸(stretch)。

现在,要为您出现在动画中的真正原因进行动画处理,您可能需要彻底更改某些内容。我觉得您的while循环可能是要进行缩放的,但它们是在coef计算之后进行的,因此我认为它们是用于其他用途的。但是,一旦确定了要在从“无缩放”到“最终缩放”的范围内计算不同coef值的循环的确切位置,您还需要添加调用以重绘显示内容-或取决于您的环境,可能需要添加一些每50毫秒由计时器触发的回调代码,或使用更新的coef值重新绘制的内容。

关于delphi - 慢速图像缩放的数学运算,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10964902/

10-10 10:25