慢图像缩放的数学 [英] Math for slow image zoom

查看:84
本文介绍了慢图像缩放的数学的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



因此,不要将PicRect的值设置为END VALUE

 code> PicRect.Left 
PicRect.right
PicRect.top
PicRect.bottom

如下面的代码所示,我需要一种方法来缓慢地到达那里,某种while循环,一次设置这些值,直到它达到结束值,但我是不是100%肯定这个数学如何运作。我的while循环尝试也不会做任何事情,但放大太远。这是程序。

 程序TZImage.MouseUp(Button:TMouseButton; Shift:TShiftState; 
X,Y:整数);
var coef:Double;
t:integer;
begin
如果FMouse = mNone然后退出;
如果x> ShowRect.Right然后x:= ShowRect.Right;
如果y> ShowRect.Bottom则y:= ShowRect.Bottom;
如果FMouse = mZoom然后开始//计算新的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;
//如果要通过相反的方向拖动来启用以下命令}
{如果Startx> x然后开始
DblClick;
退出;
end;}
如果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
else if(x - startx> y - starty)then
begin
while(x - startx> y - starty)do
begin
y:= y + 100;
starty:= starty - 100;
结束
结束


//这是设置缩放信息。这是
//我必须改变以缓慢获取PICRECT.Left / right / top / bottom
如果(PicRect.Right = PicRect.Left)
然后
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。最佳);
PicRect.Top:=Round(PicRect.Top+starty/coef);
PicRect.Bottom:= PicRect.Top + Round((y-starty)/ coef);
结束
如果FMouse = mDrag然后开始
FMouse:= mNone;
Canvas.Pen.Mode:= pmCopy;
Screen.Cursor:= crDefault;
结束
无效;
结束

我相信这可以在上面的代码中完成。但是也想添加这个帮助。

 键入
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)然后
begin
while(x - startx< y - starty)do
begin
x:= x + 100;
startx:= startx - 100;
结束
end
else if(x - startx> y - starty)then
/ *相似代码* /

请注意, x - start == y - starty 案例完全被忽视。我不知道这是否重要。



其次,这可能是没有循环的重写。我猜这里,需要一点测试,看看这是否正确,但这感觉就像正确的路径:

  foo:=(x  -  startx) - (y  -  starty)
if(foo> 200 || foo< -200)
bar = foo / 200#我假设整数截断
x + = bar * 100
startx + = bar * 100

我不是完全确定你为什么要将(x-startx) - (y-starty)在彼此之内达到200以内;可能还有一些更好的东西。



这部分代码有点混乱:

 code> if(PicRect.Right = PicRect.Left)
then
coef:= 100000
else
coef:= ShowRect.Right /(PicRect.Right-PicRect 。剩下);
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。最佳);
PicRect.Top:=Round(PicRect.Top+starty/coef);
PicRect.Bottom:= PicRect.Top + Round((y-starty)/ coef);
结束

c 应该被覆盖早些时候或者,您应该如何计算一个 coefx coefy ,然后选择(较大?较小?更接近100000?)值为 .Left .Right .Top .Bottom 计算?我不得不认为,这个代码更有可能导致你的内容尴尬的扩展,这可能会使用户和作者两者都很烦。



现在,为了解决您在这里的真实原因,您可能需要大幅度地更改某些。我觉得你的,而循环可能是为了做缩放,但是在 c $ c> coef 计算,所以我认为他们是为了别的东西。但是,一旦你弄清楚在哪里放置循环来计算从无缩放到最终缩放的范围内的不同的 coef 值,你还需要添加对重绘的调用显示 - 或者根据您的环境,可能需要添加一个定时器每50ms触发的一些回调代码,或者使用更新的 值。


I have an .bmp image with a comic book layout. Currently my code works like this. If I right click and hold down mouse button i can draw a marquee type box around one of the frames on the comic book page. When I release the button it will zoom into that frame. But its instant. And I would like for it to have an animation effect.

Thus instead of going and setting the values of PicRect to the "END VALUE"

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

as seen in code below, I need a way to slowly get there, Some kind of while loop that sets those values a little at a time till untill it gets to the "end value" But I am not 100% sure on how this math is working. Nor do any of my while loop tries do anything but zoom in way too far. This is the procedure.

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;

I believe this can be done in the code above. but also wanted to add this incase it helps.

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;

thanks for any help in getting this to work.

解决方案

I've got a few suggestions; I'm not sure that they'll be sufficient to solve your problem, but I hope it helps you get there.

First, your while loops are doing a fair amount of funny fiddling:

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 */

Note that x - start == y - starty case is being completely overlooked. I don't know if this matters.

Second, this could probably be re-written without a loop. I'm guessing here, it'd take a little testing to see if this is correct, but this feels like the right path:

foo := (x - startx) - (y - starty)
if (foo > 200 || foo < -200)
    bar = foo / 200  # I assume integer truncation
    x += bar * 100
    startx += bar * 100

I'm not entirely sure why you're trying to get (x-startx) - (y-starty) to within 200 of each other; there may be something better still.

This section of code is a little confusing:

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;

Is coef supposed to be overwritten from the earlier? Or, should you instead calculate a coefx and coefy and then pick the (larger? smaller? closer to 100000?) value to serve for both the .Left, .Right, .Top, and .Bottom calculations? I have to think that this code, as it stands, is more likely to lead to awkward stretching of your content in a way that will likely annoy users and authors both.

Now, to address the real reason why you're here, animating the zoom -- you'll probably need to drastically change something. I feel like your while loops were probably intended to do the zooming, but they come after the coef calculations, so I assumed they were meant for something else. But, once you do figure out where exactly to place the loop to calculate different coef values over a range from "no zoom" to "final zoom", you'll also need to add calls to repaint the display -- or, depending upon your environment, maybe need to add some callback code fired by a timer every 50 ms or something to repaint with updated coef values.

这篇关于慢图像缩放的数学的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆