一幅很大的图片,3000*2200的。在delphi中实现平滑移动
具体效果类似acdsee看大图片的时候,也可以用手去平滑移动的。要求图片不闪烁。重分奖励。求高手赐教。
PS:我试过用双缓冲doublebuffer,但是好像没什么用

解决方案 »

  1.   

    我使用的sqlserver存的图片,也就是说图片存在数据库里,这样好象不能只读取指定方向上的n行数据吧?
      

  2.   

    我以前用多线程也不行,后来一只莱鸟居然用一个TTimer控件简单地实现了!!!大家可试试。
      

  3.   

    我给个思路,你根据鼠标或滚动条的位置,响应的减去加上图片的大小和你的窗口的大小,然后,用BITBLT函数根据坐标点画图。
      

  4.   

    给你一个例子:
    Scrollbox上放一个Image
    Image的AutoSize为true.
    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
      ExtCtrls;type
      TForm1 = class(TForm)
        ScrollBox1: TScrollBox;
        Image1: TImage;
        procedure Image1MouseDown(Sender: TObject; Button: TMouseButton;
          Shift: TShiftState; X, Y: Integer);
        procedure Image1MouseUp(Sender: TObject; Button: TMouseButton;
          Shift: TShiftState; X, Y: Integer);
        procedure Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
          Y: Integer);
      private
        { Private declarations }
      public
        { Public declarations }
        OriginPoint: TPoint;
        gMouseDownMark: Boolean;
      end;var
      Form1: TForm1;implementation{$R *.DFM}procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
        gMouseDownMark := true;
        OriginPoint.x := x;
        OriginPoint.y := y;
    end;procedure TForm1.Image1MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
        gMouseDownMark := false;
    end;procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    var
      TmpX, TmpY: integer;
    begin
        if gMouseDownMark  then begin
            TmpX := x - OriginPoint.x;
            TmpY := x - OriginPoint.y;
            ScrollBox1.HorzScrollBar.Position := TmpX;
            ScrollBox1.VertScrollBar.Position := TmpY;        
        end;
    end;end.
      

  5.   

    在开发多媒体应用中,经常会遇到需要在有限区域内显示大图像的情况,有不少文章对此提出过解决方法,如通过调用Windows的API函数,直接读写内存等。这些方法有某些优点,但实现起来较为复杂,且易出错。笔者在实践中通过仔细摸索,利用Delphi的强大的面向对象可视化开发环境开发了一种交互式图像漫游方法。 
      Delphi中,鼠标的消息响应是通过元件的OnMouseDown、OnMouseU p和OnMouseMove事件实现的,通过对此三个事件编程,可控制图像在有限区域内移动。考虑到所移动的图像的边界应总在该区域外,因此图像的左上角坐标应小于该区域对应坐标,图像右下角坐标应大于该区域对应坐标(除非图像大小比该区域小)。图1  具体方法是:  1、新建一工程Project1,在Form1中依次放入Panel1、Panel2和I mage1元件,注意Pa nel2和Image1分别在Panel1和Panel2上,再将一La bel1元件加入Panel2中,调整Panel1尺寸为适当大小,并修改各元件属性为:
    元件
    属性名
    属性值
    Panel1
    BevelInner:
    bvRaised
    BevelOuter: bvNone
    BorderStyle: bsSingle
    Panel2
    Align:
    alClient
    Image1
    AutoSize:
    True
    Picture:
    ”Apple.bmp”
    Label1
    Align:
    alClient
    Transparent : True   注意:此处Label1的作用不是显示字符,而是利用它响应鼠标消息 ,如果不用Label1而直接利用Image1的鼠标事件响应,则会由于其OnMo useDown事件的激活与Image1的自身坐标移动事件冲突而使图像发生闪烁甚至不能移动。  2、在implementation后加入变量声明:
    origin:Tpoint;
    image_left:integer;
    image_top:integer;
    visa1:Tpoint; (鼠标当前位置相对图像右下角的坐标)
    visa2:Tpoint; (鼠标当前位置相对图像左上角的坐标)
    canmove:boolean;    编写Label1鼠标响应事件:
    procedure TForm1.Label1MouseDown(Sender: TObject; Button
    : TMouseButton;S hift: TShiftState; X, Y: Integer);
    begin
    if Button=mbLeft then
    begin
    origin.x:=X;
    origin.y:=Y;
    image_left:=image1.left;
    image_top:=image1.top;
    visa1.x:=X-(image1.width-panel2.width+image1.left);
    visa1.y:=Y-(image1.height-panel2.height+image1.top);
    visa2.x:=X-image1.left;
    visa2.y:=Y-image1.top;
    canmove:=true;
    end;
    end;
    procedure TForm1.Label1MouseMove(Sender: TObject; Shift:
    TShiftState; X, Y: Integer);
    begin
    if canmove then
    begin
    if X< visa1.x then X:=visa1.x;
    if X>visa2.x then X:=visa2.x;
    if Y< visa1.y then Y:=visa1.y;
    if Y>visa2.y then Y:=visa2.y;
    image1.left:=image_left+(X-origin.x);
    image1.top:=image_top+(Y-origin.y);
    end;
    end;
    procedure TForm1.Label1MouseUp(Sender: TObject; Button: 
    TMouseButton;Shi ft: TShiftState; X, Y: Integer);
    begin
    canmove:=false;
    end; 
      

  6.   

    unit D17;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, ExtCtrls, StdCtrls, jpeg;type
      TForm1 = class(TForm)
        Panel1: TPanel;
        Panel2: TPanel;
        Label1: TLabel;
        Image1: TImage;
        Button1: TButton;
        procedure Label1MouseDown(Sender: TObject; Button: TMouseButton;
          Shift: TShiftState; X, Y: Integer);
        procedure Label1MouseMove(Sender: TObject; Shift: TShiftState; X,
          Y: Integer);
        procedure Label1MouseUp(Sender: TObject; Button: TMouseButton;
          Shift: TShiftState; X, Y: Integer);
        procedure Button1Click(Sender: TObject);
        procedure FormCreate(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;
      origin:TPoint;
      image_left,image_top:integer;
      visa1,visa2:TPoint;
      canmove:boolean;implementation{$R *.dfm}procedure TForm1.Label1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
      if Button=mbLeft then
      begin
        Origin.X:=X;
        Origin.Y:=Y;
        image_left:=image1.Left;
        image_top:=image1.Top;
        visa1.X:=X-(image1.Width-panel2.Width+image1.Left);
        visa1.Y:=Y-(image1.Height-panel2.Height+image1.Top);
        visa2.X:=X-image1.Left;
        visa2.Y:=Y-image1.Top;
        canmove:=true;
      end;
    end;procedure TForm1.Label1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    begin
      if canmove then
      begin
        if X<visa1.X then X:=visa1.X;
        if X>visa2.X then X:=visa2.X;
        if Y<visa1.Y then Y:=visa1.Y;
        if Y>visa2.Y then Y:=visa2.Y;
        image1.Left:=image_left+(X-origin.X);
        image1.Top:=image_top+(Y-origin.Y);
      end;
    end;procedure TForm1.Label1MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
      canmove:=false;
    end;procedure TForm1.Button1Click(Sender: TObject);
    begin
      close;
    end;procedure TForm1.FormCreate(Sender: TObject);
    begin
      //panel2.DoubleBuffered:=true;
      Image1.Stretch:=true;
    end;end.