Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Графика и игры
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 04.10.2012, 17:08
Sv-academy Sv-academy вне форума
Прохожий
 
Регистрация: 04.10.2012
Сообщения: 2
Репутация: 10
По умолчанию Очень нужна помощь с масштабированием изображений в Delphi XE2

Ребята, помогите кто может. Есть картинка разрешением 13177*7417. Так как разрешение достаточно высокое, то вывод картинки в Image1 осуществляю по частям из буфера. В свойствах Image1 в графе WrapMode стоит iwTile, то есть выводится только часть картинки, и перетаскивания картинки мышью происходит гладко без рывков, но стоит изменить масштаб как тут же начинает рубится, даже если вернул картинку в исходный масштаб все равно перетаскивания получаются рваными. Я не могу понять почему, помогите кто может!! Код программы представлен ниже.
Код:
unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.Objects, FMX.Edit;

type
  TForm1 = class(TForm)
    Panel1: TPanel;
    Image1: TImage;
    Edit1: TEdit;
    Button1: TButton;
    procedure Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Single);
    procedure Image1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Single);
    procedure FormCreate(Sender: TObject);
    procedure Image1MouseWheel(Sender: TObject; Shift: TShiftState;
      WheelDelta: Integer; var Handled: Boolean);

  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  Buff,Buff2,Buff3:TBitmap;
  i,j,G:integer;
  pos,delta:TPoint;
  Rt1:array[0..100,0..100] of TRectF;
  Rt2:array[0..100,0..100] of TRectF;

implementation

{$R *.fmx}



procedure TForm1.FormCreate(Sender: TObject);
begin
   Image1.Bitmap.LoadFromFile('c:\RRV\Temp\2\42.png');
   Buff2:=TBitmap.Create(Round(Image1.Width),Round(Image1.Height));
   Buff2.LoadFromFile('c:\RRV\Temp\2\42.png');
   G:=15;
//делим загруженную в буфер картинку на G частей
 for i := 0 to G do
    begin
      for j := 0 to G do
        begin
          Rt1[i,j].Right:=Buff2.Width/G+(Buff2.Width/G)*j;
          Rt1[i,j].Left:=(Buff2.Width/G)*j;
          Rt1[i,j].Bottom:=(Buff2.Height/G)*i+Buff2.Height/G;
          Rt1[i,j].Top:=(Buff2.Height/G)*i;
        end;
    end;
 for i := 0 to G do
   begin
     for j := 0 to G do
       begin
         Rt2[i,j].Right:=Buff2.Width/G+(Buff2.Width/G)*j;
         Rt2[i,j].Left:=(Buff2.Width/G)*j;
         Rt2[i,j].Bottom:=(Buff2.Height/G)*i+Buff2.Height/G;
         Rt2[i,j].Top:=(Buff2.Height/G)*i;
       end;
   end;
end;
 //получаем координаты курсора при нажатии
procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Single);
begin
  pos:=Point(Round(x),Round(y));
end;
//двигаем картинку
procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Single);
begin
  if SSLeft in Shift then
    begin
      delta:=point(Round(x)-pos.X,Round(y)-pos.Y);
      for i := 0 to G do
        for j := 0 to G do
          begin
            Rt2[i,j].Left:=Rt2[i,j].Left+Round(delta.X);
            Rt2[i,j].Right:=Rt2[i,j].Right+Round(delta.X);
            Rt2[i,j].Top:=Rt2[i,j].Top+Round(delta.Y);
            Rt2[i,j].Bottom:=Rt2[i,j].Bottom+Round(delta.Y);
          end;

      for i := 0 to G do
        for j := 0 to G do
          if ((Rt2[i,j].Left+Round(delta.X))<Image1.Width) and ((Rt2[i,j].Right+Round(delta.X))>0) and
             ((Rt2[i,j].Top+Round(delta.Y))<Image1.Height) and ((Rt2[i,j].Bottom+Round(delta.Y))>0) then
             begin
               with Image1.Bitmap do
                 begin
                   Canvas.BeginScene;
                   try
                   Canvas.DrawBitmap(Buff2,Rt1[i,j],Rt2[i,j],1,True);
                   Canvas.EndScene;
                   finally
                   BitmapChanged
                   end;
                 end;
             end;
    end;
   pos.X:=pos.X+delta.X;
   pos.Y:=pos.Y+delta.Y;
end;
//делаем масштаб
procedure TForm1.Image1MouseWheel(Sender: TObject; Shift: TShiftState;
  WheelDelta: Integer; var Handled: Boolean);
  const
  ZoomFactor: array[Boolean] of Single = (0.9, 1.1);
begin
 for i := 0 to G do
   for j := 0 to G do
     begin
       Rt2[i,j].Left:=Rt2[i,j].Left*ZoomFactor[WheelDelta > 0];
       Rt2[i,j].Right:=Rt2[i,j].Right*ZoomFactor[WheelDelta > 0];
       Rt2[i,j].Top:=Rt2[i,j].Top*ZoomFactor[WheelDelta > 0];
       Rt2[i,j].Bottom:=Rt2[i,j].Bottom*ZoomFactor[WheelDelta > 0];
     end;
   for i := 0 to G do
     for j := 0 to G do
       if (Rt2[i,j].Left<Image1.Width) and (Rt2[i,j].Right>0) and
          (Rt2[i,j].Top<Image1.Height) and (Rt2[i,j].Bottom>0) then
           begin
             with Image1.Bitmap do
               begin
                 Canvas.BeginScene;
                 try
                 Canvas.DrawBitmap(Buff2,Rt1[i,j],Rt2[i,j],1,True);
                 Canvas.EndScene;
                 finally
                 BitmapChanged
                 end;
               end;
           end;
end;

end.  
Ответить с цитированием
  #2  
Старый 04.10.2012, 17:33
Аватар для Klyaksa
Klyaksa Klyaksa вне форума
Новичок
 
Регистрация: 07.01.2012
Сообщения: 90
Репутация: 10
По умолчанию

Тебе нужен общий буфер который не будет изменять свои размеры. А от этого буфера уже масштабируешь в image1.
Ответить с цитированием
  #3  
Старый 05.10.2012, 08:32
Sv-academy Sv-academy вне форума
Прохожий
 
Регистрация: 04.10.2012
Сообщения: 2
Репутация: 10
По умолчанию

Так я ведь в своем буфере никакие размеры не меняю, я меняю размер или местоположение целевого прямоугольника Rt2 в который будет выводится участок картинки в Image1 из исходной области Rt1. Rt1 и Rt2 используются только при рисовании в Image1 и на буфер никак не влияют?
Ответить с цитированием
  #4  
Старый 07.10.2012, 23:29
Аватар для Klyaksa
Klyaksa Klyaksa вне форума
Новичок
 
Регистрация: 07.01.2012
Сообщения: 90
Репутация: 10
По умолчанию Очень нужна помощь с масштабированием изображений в Delphi XE2

Попробуй сделать так
Код:
Canvas.DrawBitmap(Buff2,Rt2[i,j],Rt1[i,j],1,True);

Последний раз редактировалось Klyaksa, 08.10.2012 в 00:51.
Ответить с цитированием
  #5  
Старый 08.10.2012, 10:01
icWasya icWasya вне форума
Местный
 
Регистрация: 09.11.2010
Сообщения: 499
Репутация: 10
По умолчанию

Ну для начала - вынести Canvas.BeginScene и Canvas.EndScene за цикл отрисовки.
Во вторых, сделай DoubleBuffered:=True;
в третьих - у меня нет XE, но на шестёрке проявляется заметное торможение при уменьшении масштаба. Похоже, что при этом просто приходится обрабатывать больше кусков исходного изображения.
Как вариант - попробуй сделать несколько уменьшеных копий исходного изображения с разной степенью уменьшения, и при заметном изменении масштаба переключаться на них.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 21:08.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter