delphi 图片预览1(使用delphi自带interactiveGestures)

此功能模仿微信朋友圈查看图片交互设计,预览图片的放大缩小左移右移。

还有很多缺陷,比如图片切换没有动画效果,2个月前写的,好多不记得了。

而且delphi自带手势滑动的快慢是有区别的,StandardGestures和interactiveGestures有描述。

 

 

 

 

手势都是窗体的。

 

 

 

unit UPreviewImage;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.TabControl,
  DRFormClass,System.Generics.Collections,DataRec,FMX.Objects,MSFileCLass,
  FMX.Gestures,System.Math;

type
  TFrmPreviewImage = class(TForm)
    TabEnlargeImage: TTabControl;
    GestureManager1: TGestureManager;
    procedure TabEnlargeImageMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Single);
    procedure TabEnlargeImageGesture(Sender: TObject;
      const EventInfo: TGestureEventInfo; var Handled: Boolean);
    procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Single);
    procedure FormGesture(Sender: TObject; const EventInfo: TGestureEventInfo;
       var Handled: Boolean);
  private
  FSendData           : TDictionary<integer, TSelectPictureInfo> ;
  FNumber             : integer;
  FMSCarrierObject_ID : string;
  FType_ID            : string;
  FIsDown             : boolean ;
  FTmpDownPos         : TPointF ;

  FLastPosition       : TPointF;
  FLastDIstance       : integer ;
  FOriginalWidth      : Single ;
  FOriginalHeight     : Single ;
  FOriginalX          : single ;
  FOriginalY          : Single ;
  FZoomWidth          : Single ;
  FZoomHeight         : Single ;

  LImage: TImage;
  Ratio:single;
  NowWidth:Single ;
  NowHeight:Single ;
  ZoomState:Boolean;
  PanState:Boolean;
  procedure FormMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Single);
  procedure FormClose(Sender:Tobject);
    { Private declarations }
  public
   class procedure ShowFrm(ASendData:TDictionary<integer, TSelectPictureInfo>;ANumber:
            integer;AMSCarrierObject_ID:string='';AType_ID:string=''); //缩略图字典;第几张图;原图载体id;原图类型id
   procedure PreviewImage;

    { Public declarations }
  end;

var
  FrmPreviewImage: TFrmPreviewImage;

implementation

{$R *.fmx}

{ TForm1 }


procedure TFrmPreviewImage.FormClose(Sender: Tobject);
begin
  TDRForm.Create(self).Release;
end;

procedure TFrmPreviewImage.FormGesture(Sender: TObject;
  const EventInfo: TGestureEventInfo; var Handled: Boolean);
var
  LObj: IControl;
  LImageCenter: TPointF;
  Tan :single;
  A,B :single;
begin
   INHERITED;

  if EventInfo.GestureID = igiZoom then//放大缩小手势
  begin
    ZoomState:=true;
    LObj := Self.ObjectAtPoint(ClientToScreen(EventInfo.Location));
    if LObj is TImage then
    begin
      if (not(TInteractiveGestureFlag.gfBegin in EventInfo.Flags)) and
        (not(TInteractiveGestureFlag.gfEnd in EventInfo.Flags)) then
      begin
        { zoom the image }
        LImage := TImage(LObj.GetObject);
        LImageCenter := LImage.Position.Point + PointF(LImage.Width / 2,
          LImage.Height / 2);
       A:=LImage.Width;

        if LImage.Width<FOriginalWidth then
        begin
        LImage.Width := LImage.Width +  (power(2,(EventInfo.Distance - FLastDistance)/10)-1)*10; // 控制u图片缩小速度和大小,滑的越大变化越小,后面变化无限小
        LImage.Height := LImage.Height + (power(2,(EventInfo.Distance - FLastDistance)/10)-1)*10;//
        end
        else
        begin
        LImage.Width := LImage.Width +  2*(EventInfo.Distance - FLastDistance);
        LImage.Height := LImage.Height + 2*(EventInfo.Distance - FLastDistance);
        end;
        LImage.Position.X := LImageCenter.X - LImage.Width / 2;
        LImage.Position.Y := LImageCenter.Y - LImage.Height / 2;
//        LImage.Position.Y :=(1-LImage.Width/NowWidth)*EventInfo.Location.Y -LImage.Position.y ;
//        LImage.Position.x :=(1-LImage.Width/NowWidth)*EventInfo.Location.x -LImage.Position.x ;
//        LImage.Position.Y :=(1-LImage.Width/a)*(EventInfo.Location.Y-LImage.Position.y)-LImage.Position.y  ;
//        LImage.Position.x :=(1-LImage.Width/a)*(EventInfo.Location.x-LImage.Position.X)-LImage.Position.X  ;
       // showmessage(EventInfo.Location.x.ToString+','+LImage.Position.x.ToString);
        FZoomWidth := LImage.Width ;
        FZoomheight := LImage.height ;

      end;
      FLastDistance := EventInfo.Distance;
    end;
    exit;
  end;

  //平移
  if EventInfo.GestureID = igiPan then
  begin
      PanState:=true;
      LObj := Self.ObjectAtPoint(ClientToScreen(EventInfo.Location));
        if LObj is TImage then
        begin
          A:=LImage.Height;
          if not(TInteractiveGestureFlag.gfBegin in EventInfo.Flags) then
          begin
            LImage := TImage(LObj.GetObject);
           // if LImage.Width>self.Width then
           if True then
            begin
           // (power(2,(EventInfo.Location.X - FLastPosition.X)/10)-1)*10
           //showmessage(EventInfo.Location.X.ToString  +','+FLastPosition.X.ToString);
               if (0.66*self.Width-LImage.Width<LImage.Position.x)  and (LImage.Position.x<0.33*self.Width)  then
               begin
                  LImage.Position.X := LImage.Position.X +( EventInfo.Location.X - FLastPosition.X);
             //  end
             //  else
             //   if LImage.Position.x>=0 then
              //  begin
               // showmessage((1/(power((EventInfo.Location.X - FLastPosition.X),2)+1)).tostring;//尝试控制速度
              //  showmessage((EventInfo.Location.X - FLastPosition.X).ToString);
               //   LImage.Position.X := LImage.Position.X +1/(power(2,((EventInfo.Location.X - FLastPosition.X)/10)-1)*10);
                 // showmessage((1/(power(2,(EventInfo.Location.X - FLastPosition.X))+1)).tostring);
                end
               else
               if LImage.Position.x>0.33*self.Width then                 //右移滑动图片
               begin
                  if TabEnlargeImage.ActiveTab<>TabEnlargeImage.Tabs[0] then
                  begin
                     //TabControl1.ActiveTab:=TabControl1.Tabs[TabControl1.TabIndex-1];
                     TabEnlargeImage.SetActiveTabWithTransition(TabEnlargeImage.Tabs[TabEnlargeImage.Tabindex-1],TTabTransition.Slide,
                           TTabTransitionDirection.Reversed);
                     handled:=true;

                  end;
               end
              else
              if 0.66*self.Width-LImage.Width>LImage.Position.x then       //左移滑动图片
              begin
                  if TabEnlargeImage.ActiveTab<>TabEnlargeImage.Tabs[TabEnlargeImage.tabcount-1] then
                  begin
                     //TabControl1.ActiveTab:=TabControl1.Tabs[TabControl1.TabIndex+1];
                     TabEnlargeImage.SetActiveTabWithTransition(TabEnlargeImage.Tabs[TabEnlargeImage.Tabindex+1],TTabTransition.Slide ,
                           TTabTransitionDirection.Normal);
                      handled:=true;

                  end;
              end;
            end;
          end;
              //Set the Y coordinate.
            if (LImage.Width*Ratio)>self.Height then
            begin
              // if (0.66*self.Height -LImage.Height <LImage.Position.y) and (LImage.Position.Y<0.33*self.Height) then
                  LImage.Position.Y := LImage.Position.Y + (EventInfo.Location.Y - FLastPosition.Y);
            end;
          end;
          FZoomWidth := LImage.Width ;
          FZoomheight := LImage.height ;
          FLastPosition := EventInfo.Location;
          exit;
        end;

    case EventInfo.GestureID  of
    sgiLeft:
      begin
          if TabEnlargeImage.ActiveTab<>TabEnlargeImage.Tabs[TabEnlargeImage.tabcount-1] then
          begin
             //TabControl1.ActiveTab:=TabControl1.Tabs[TabControl1.TabIndex+1];
             TabEnlargeImage.SetActiveTabWithTransition(TabEnlargeImage.Tabs[TabEnlargeImage.Tabindex+1],TTabTransition.Slide ,
                   TTabTransitionDirection.Normal);
              handled:=true;
          end;
      end;
    sgiRight:
      begin
          if TabEnlargeImage.ActiveTab<>TabEnlargeImage.Tabs[0] then
          begin
             //TabControl1.ActiveTab:=TabControl1.Tabs[TabControl1.TabIndex-1];
             TabEnlargeImage.SetActiveTabWithTransition(TabEnlargeImage.Tabs[TabEnlargeImage.Tabindex-1],TTabTransition.Slide,
                   TTabTransitionDirection.Reversed);
             handled:=true;
          end;
      end;
    end;
   end;


procedure TFrmPreviewImage.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Single);
begin
//
end;

procedure TFrmPreviewImage.FormMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Single);
begin
  inherited;
//  if Sender is Timage then
     if FIsDown then
        begin
           FIsDown := false;
           if FTmpDownPos.X = x then
           TDRForm.Create(self).Release ;
        end;

       if LImage.Position.X > 0 then         //让图片弹回左边框
       begin
         LImage.Position.X := 0;
       end;
       if LImage.Position.X-self.Width+LImage.Width <0 then  //让图片弹回右边框
       begin
         LImage.Position.X :=self.Width-LImage.Width;
       end;
       if (LImage.Width*Ratio)>self.Height then          //图片bitmap超过屏幕高上下滑
       begin
          if (LImage.Height-Ratio*LImage.Width)/2+LImage.Position.y>0   then    //上边框
          begin
             LImage.Position.y := -(LImage.Height-Ratio*LImage.Width)/2;
          end;
          if LImage.Position.y+(LImage.Height-(LImage.Height-Ratio*LImage.Width)/2)<self.Height then  //下边框
          begin
             LImage.Position.y :=self.Height -(LImage.Height-(LImage.Height-Ratio*LImage.Width)/2);
          end;
       end
       else
       if (LImage.Width*Ratio)<self.Height then
       begin
           LImage.Position.y := -(LImage.Height-FOriginalHeight)/2;
       end;

      if FZoomWidth<FOriginalWidth then        //缩的太小就返回原来大小
      begin
        LImage.Position.X := FOriginalX;
        LImage.Position.Y := FOriginalY ;
        LImage.Width      := FOriginalWidth ;
        LImage.Height     := FOriginalHeight ;
      end;
      if FZoomWidth>3.1*FOriginalWidth then           //最大放大3倍
      begin
        LImage.Width      := 3*FOriginalWidth ;
        LImage.Height     := 3*FOriginalHeight ;
        LImage.Position.X :=FOriginalX-(LImage.Width-FOriginalWidth)/2;
        LImage.Position.y :=FOriginaly-(LImage.Height-FOriginalHeight)/2;
      end;
      FZoomWidth:=LImage.Width;
     // showmessage(LImage.Height.ToString+','+LImage.Bitmap.Height.ToString+','+Ratio.ToString);
     NowWidth:=LImage.Width;
     NowHeight:=LImage.Height;
     ZoomState:=false;

   if PanState=true then
   begin
//         if  LImage.Width<=self.Width then
//      begin
//
//              if TabEnlargeImage.ActiveTab<>TabEnlargeImage.Tabs[TabEnlargeImage.tabcount-1] then
//              begin
//
//                 //TabControl1.ActiveTab:=TabControl1.Tabs[TabControl1.TabIndex+1];
//                 TabEnlargeImage.SetActiveTabWithTransition(TabEnlargeImage.Tabs[TabEnlargeImage.Tabindex+1],TTabTransition.Slide ,
//                       TTabTransitionDirection.Normal);
//
//              end;
//              if TabEnlargeImage.ActiveTab<>TabEnlargeImage.Tabs[0] then
//              begin
//                 //TabControl1.ActiveTab:=TabControl1.Tabs[TabControl1.TabIndex-1];
//                 TabEnlargeImage.SetActiveTabWithTransition(TabEnlargeImage.Tabs[TabEnlargeImage.Tabindex-1],TTabTransition.Slide,
//                       TTabTransitionDirection.Reversed);
//
//              end;
//        end;
   end;
end;

procedure TFrmPreviewImage.PreviewImage;
var
  Bitmaplist: Tlist<FMX.Graphics.TBitmap>;
  GuIDlist  : Tstringlist;
  Number    : string;
  AFrame    : TFrame ;
  AItem     : TTabItem;
  AImage    :  TImage;
  i         : integer;
  ATag      : integer ;
  Err       : Boolean;
  MSCarrierObject_ID,Type_ID,errmsg:string;
  ADataInfo : TSelectPictureInfo ;
begin
      if TabEnlargeImage.TabCount >0  then
    begin

       for I :=0  to TabEnlargeImage.TabCount - 1 do
       begin
           TabEnlargeImage.Delete(0);
       end;
    end;

  Bitmaplist:= Tlist<FMX.Graphics.TBitmap>.create;
  GuIDlist  :=Tstringlist.Create;
    for I := 0 to FSendData.Count-1 do
    begin
       for ADataInfo in FSendData.Values  do
      begin
        if ADataInfo.IndexTag=I then
           BitmapList.Add(ADataInfo.Bitmap);
      end;
    end;

//  AStr := copy(AStr,1,length(AStr)-1);
//  Err       :=TBitmapManager.DownLoadMultipleBitMap(MSCarrierObject_ID,
//                  Type_ID,BitmapList,GuIDlist,errmsg);
    begin
      for I := 0 to Bitmaplist.Count - 1 do
      begin

          AItem        := TTabItem.Create(nil) ;
          AItem.Text   :='';
          AItem.Name   := 'TabItem'+inttostr(i+1);
          AItem.Parent := TabEnlargeImage ;
          AItem.Width  := self.Width ;
          AItem.HitTest:=true;

          AImage       :=TImage.Create(nil);
          AImage.Align :=TAlignLayOut.Center;
          AImage.Parent:=AItem;
          AImage.Parent:=AItem;
          AImage.Width:=self.Width;
          aimage.Height:=self.Height;
          AImage.MarginWrapMode:=TImageWrapMode.Stretch;
          AImage.Bitmap.Assign(Bitmaplist[i]);
          AImage.HitTest:=true;
         // AImage.Touch.GestureManager:=GestureManager2;
         // AImage.Touch.InteractiveGestures:=[TInteractiveGesture.Zoom,TInteractiveGesture.Pan,TInteractiveGesture.Rotate,
         //  TInteractiveGesture.TwoFingerTap,TInteractiveGesture.PressAndTap,TInteractiveGesture.LongTap,TInteractiveGesture.DoubleTap];
         // AImage.OnGesture:= FormGesture;
          AImage.OnMouseUp:= FormMouseUp;
          Aimage.OnMouseDown:=TabEnlargeImageMouseDown;
          //Aimage.OnClick:=FormClose;

          FOriginalWidth  := AImage.Width ;
          FOriginalHeight := AImage.Height ;
          NowWidth := AImage.Width ;
          NowHeight := AImage.Height ;
          FOriginalX      := AImage.Position.X ;
          FOriginalY      := AImage.Position.Y ;
          //Ratio:= AImage.Bitmap.Height/AImage.Height;
          //image放大后,bitmap放大比例跟image不一样,只能让bitmap显示宽等于屏宽 ,放大后Ratio*image.width=bitmap.height.
          Ratio:= AImage.Bitmap.Height/AImage.Bitmap.Width;
          LImage:= AImage;
      end;
      TabEnlargeImage.ActiveTab := TabEnlargeImage.Tabs[FNumber] ;
end;
end;

class procedure TFrmPreviewImage.ShowFrm(ASendData:TDictionary<integer, TSelectPictureInfo>;ANumber:
            integer;AMSCarrierObject_ID:string='';AType_ID:string='');   //缩略图字典;第几张图;原图载体id;原图类型id
var
  DrFrmFind: TFrmPreviewImage;
begin
  DrFrmFind := (TDRForm.Create(TFrmPreviewImage).TCCF as TFrmPreviewImage);
  with DrFrmFind do
  begin
    FSendData           := TDictionary<integer, TSelectPictureInfo>.Create ;
    FSendData           := ASendData;
    FNumber             := ANumber;
    FMSCarrierObject_ID := AMSCarrierObject_ID;
    FType_ID            := AType_ID;
    show;
    PreviewImage;
  end;
end;
procedure TFrmPreviewImage.TabEnlargeImageGesture(Sender: TObject;
  const EventInfo: TGestureEventInfo; var Handled: Boolean);
begin
  case EventInfo.GestureID  of
    sgiLeft:
      begin
          if TabEnlargeImage.ActiveTab<>TabEnlargeImage.Tabs[TabEnlargeImage.tabcount-1] then
          begin
             //TabControl1.ActiveTab:=TabControl1.Tabs[TabControl1.TabIndex+1];
             TabEnlargeImage.SetActiveTabWithTransition(TabEnlargeImage.Tabs[TabEnlargeImage.Tabindex+1],TTabTransition.Slide ,
                   TTabTransitionDirection.Normal);
              handled:=true;
          end;
      end;
    sgiRight:
      begin
          if TabEnlargeImage.ActiveTab<>TabEnlargeImage.Tabs[0] then
          begin
             //TabControl1.ActiveTab:=TabControl1.Tabs[TabControl1.TabIndex-1];
             TabEnlargeImage.SetActiveTabWithTransition(TabEnlargeImage.Tabs[TabEnlargeImage.Tabindex-1],TTabTransition.Slide,
                   TTabTransitionDirection.Reversed);
             handled:=true;
          end;
      end;

    end;
end;

procedure TFrmPreviewImage.TabEnlargeImageMouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Single);
begin
  inherited;
  FTmpDownPos := TPointF.Create(x,y);       //
  FIsDown := true ;
end;


end.

转载于:https://www.cnblogs.com/fidorido/p/6295863.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值