Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Media";
Текущий архив: 2005.08.21;
Скачать: [xml.tar.bz2];

Вниз

Как убрать тормоза при выводе битмапа?   Найти похожие ветки 

 
Alex Romasnkiy   (2005-04-06 02:05) [0]

Программа реализует что-то вроде навигации по карте города.
Квадраты карты хранятся в .gif файлах 1000х1000. В начале програмы я загружаю нужные мне квадраты в массив TBitmap-ов.
Навигация осуществляется методом drag&drop т.е. нажимаешь мышкой на карте ведешь в нужную сторону отпускаешь, карта соответсвенно перерисовывается в методе OnMouseMove при нажатой мышке, т.е. для каждой новой кординаты мышки.

А теперь проблема:
Если в массив загружать более 2 файлов, то непосредственно при навигации, появляются жуткие тормоза. Если один или 2 файла, то все в порядке, тормозов почти нет.

Подскажите, плиз, как можно избавиться от сабжа. DoubleBuffer у формы включен.


 
Defunct ©   (2005-04-06 02:26) [1]

Добавить памяти и поставить проц помощьнее, отказаться от gif, взять bitmap, оптимизировать программу.

> DoubleBuffer у формы включен.
Это тут вообще не причем


 
Alex Romasnkiy   (2005-04-06 02:28) [2]

Gif я загружаю только в начале программы, далее я работаю с Bitmap-ами.


 
Defunct ©   (2005-04-06 02:36) [3]

Bitmap 1000x1000 занимает 40Mb как-никак.

Сколько у Вас памяти на компьютере?


 
Defunct ©   (2005-04-06 02:36) [4]

Cоврал.. 4Mb..


 
Defunct ©   (2005-04-06 02:40) [5]

Зы, приведите кусок кода, в котором Вы строите отображаемую картинку в соответствии с заданными координатами. Думаю так будет проще обсуждать причину жутких тормозов.


 
Alex Romasnkiy   (2005-04-06 02:46) [6]

В начале программы загружаю все нужные квадраты в массив Cells типа CellMatrix

CellsMatrix=record
             Cell:TBitmap; // Битмап, в который загружаю картинку
             Ex:Boolean; // Признак загрузил ли картинку в эту ячейку
            end;

  for i:=0 to ni-1 do
    for j:=0 to ni-1 do
      if Cells[i,j].Ex then
        MapCells.Canvas.Draw(кордината_Х,кордината_Y,Cells[i,j].Cell)

MapCells - это Image, на который вывож карту.


 
Defunct ©   (2005-04-06 03:01) [7]

 for i:=0 to ni-1 do
   for j:=0 to ni-1 do
     if Cells[i,j].Ex then
       MapCells.Canvas.Draw(кордината_Х,кордината_Y,Cells[i,j].Cell)


Вот это и причина тормозов! Вы же выводите фактически все, что есть, а надо выводить только то, что видно в текущем окне обзора (окно обзора - это Ваш Image у которого кол-во точек гораздо меньше чем 1000x1000).

Делать нужно так:
Начальная инициализация:
1. Задать/Посчитать глобальные размерами Вашей карты (зависит от числа составляющих картинок).
2. Задать размеры окна обзора.
3. Установить начальную координату верхнего-левого угла окна обзора.
4. Задать относительную координату верхнего-левого угла каждой картинки.

При перерисовке:
1. Определять какие картинки попадают в область обзора.
2. Вырезать видимые (попадающие в окно обзора) кусочки из попадающих в область обзора Bitmap"ов. (CopyRect)

CellsMatrix=record
            Cell:TBitmap; // Битмап, в который загружаю картинку
            Ex:Boolean; // Признак загрузил ли картинку в эту ячейку
            X, Y : Integer; // Координата верхнего-левого угла картинки на общей карте
           end;


 
Alex Romasnkiy   (2005-04-06 03:18) [8]


> Вот это и причина тормозов! Вы же выводите фактически все,
> что есть, а надо выводить только то, что видно в текущем
> окне обзора


Не совсем так. Я привел упрощенный вариант вывода.
ni,nj-это количество квадратов по горизонтали ивертикали, которые помещаются именно в моем окне обзора. Поэтому я не вывожу все, что у меня есть.
Да, присутствует некотарая избыточность, когда крайние картинки  не полностью отображаются, но как мне кажется это не настолко критично, и к тому же я когда-то уже пробовал использовать copyrect, но с ним тормоза только увеличивались.


 
Defunct ©   (2005-04-06 04:09) [9]

Знаете, Вы правы насчет избыточности. Если делать как у Вас (не более 4-х картинок) то торможений-то и нет.

Попробовал написать небольшой тест. Карта 10x10 кусочки - из Bitmap"ов с PixelFormat = pf32bit, каждая картинка 1000x1000. Никаких торможений нет, но программа занимает 130 Mb памяти. Может все-таки у Вас памяти недостаточно?

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, ExtCtrls, StdCtrls;

type
 TForm1 = class(TForm)
   Image1: TImage;
   procedure FormCreate(Sender: TObject);
   procedure Image1MouseDown(Sender: TObject; Button: TMouseButton;
     Shift: TShiftState; X, Y: Integer);
   procedure Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
     Y: Integer);
   procedure Image1MouseUp(Sender: TObject; Button: TMouseButton;
     Shift: TShiftState; X, Y: Integer);
 private
   ViewPoint  : TPoint;
   MousePos   : TPoint;
   DirectionVector : TPoint;
   Relocating : Boolean;
 public
   procedure RedrawImage;
 end;

var
 Form1: TForm1;

implementation

uses Types;

{$R *.dfm}

type
  TMapCell = record
      Bmp  : TBitmap;
      X, Y : Integer;
  end;

  TMapRow = array of TMapCell;
  TMap = array of TMapRow;

var
  Map : TMap;
  ColCount : Integer = 10; // Размеры карты (колонок)x
  RowCount : Integer = 10; // (строк)

procedure TForm1.FormCreate(Sender: TObject);
var
 i, j : integer;
begin
 ViewPoint.X := 0;
 ViewPoint.Y := 0;

 SetLength( Map, ColCount );
 for i := 0 to High(Map) do
     SetLength( Map[i], RowCount );

 for i := 0 to High(Map) do
     for j := 0 to High(Map[i]) do
         begin
            Map[i][j].Bmp := TBitmap.Create;
            Map[i][j].Bmp.LoadFromFile( "C:\Herb.bmp" );
            // 32bit-цветный Bitmap 1000x1000
            Map[i][j].X := i * 1000;
            Map[i][j].Y := j * 1000;
         end;
 RedrawImage;

end;

procedure TForm1.RedrawImage;
var
 i, j : integer;
 P    : TPoint;
begin
 for i := 0 to High(Map) do
     for j := 0 to High(Map[i]) do
         begin
            P.X := Map[i][j].X - (ViewPoint.X + DirectionVector.X);
            P.Y := Map[i][j].Y - (ViewPoint.Y + DirectionVector.Y);
            if (1000 - Abs(P.X)) >= 0 then
               if (1000 - Abs(P.Y)) >= 0 then
                  Image1.Canvas.Draw( P.X, P.Y, Map[i][j].Bmp );
         end;
end;

procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
 Shift: TShiftState; X, Y: Integer);
begin
 MousePos := Mouse.CursorPos;
 DirectionVector.X := 0;
 DirectionVector.Y := 0;
 Relocating := True;
end;

procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
 Y: Integer);
begin
 if Relocating then
 begin
    DirectionVector.X := MousePos.X - Mouse.CursorPos.X;
    DirectionVector.Y := MousePos.Y - Mouse.CursorPos.Y;
    RedrawImage;
 end
end;

procedure TForm1.Image1MouseUp(Sender: TObject; Button: TMouseButton;
 Shift: TShiftState; X, Y: Integer);
begin
 ViewPoint.X := ViewPoint.X + DirectionVector.X;
 ViewPoint.Y := ViewPoint.Y + DirectionVector.Y;
 DirectionVector.X := 0;
 DirectionVector.Y := 0;
 Relocating := False;
 RedrawImage
end;

end.


 
Erik1 ©   (2005-04-06 11:32) [10]

А не проще ли воспользоватся готовыми компонентами? Для работы с картами в королевстве я нидел несколько неплохих статей на эту тему. http://www.vkasoft.narod.ru/index.htm
http://www.flex-graphics.com/ru/info.html
http://www.gisdelphi.com/index_r.htm


 
Alex Romanskiy ©   (2005-04-06 14:52) [11]


Defunct ©  

Большое спасибо вам, что потратили время,
но часть вопроса все-таки остается открытой. Если размеры IMage1 вашей программы не большие около 200*200, то тормоза действительно пропадают даже при загрузке 100 картинок, но стоит увеличить рамеры Image1 до 700*600, а где-то именно такие размеры не необходимы, то тормоза появляются опять. :(


Erik1 ©  

Конечно,с готовыми компонентами было-бы на много проще, но к сожалению, они все предназначены для работы с векторными катами, а у меня нет исходных данных для создания векторных карт.


 
Spider Man   (2005-04-06 18:48) [12]

Сам создай по растру. Можешь векторизировать объекты по имеющемуся растру, например при помощи Corel Trace, потом экспортировать в DXF, ну а из него можно импортировать в тот же DataMap


 
Sapersky   (2005-04-08 13:21) [13]

1) Если gif, то и битмапы использовать 8-битные.
2) Выкинуть Image (он, видимо, что-то там буферизует или конвертирует) и рисовать прямо на форму или PaintBox.
3) Думаю, DoubleBuffer в данном случае не нужен.


 
Alex Romasnkiy   (2005-04-12 00:53) [14]


> Sapersky


Именно пункт №2 и являлся причиной тормозов, спасибо, при замене Image на PaintBox все тормоза пропали.

А каким образом можно задать битность для битмапа и не будет ли глюков, если загружать разные картинкис разной палитрой?


 
Sapersky   (2005-04-12 12:35) [15]

А каким образом можно задать битность для битмапа

Bitmap.PixelFormat := ...
Глюков не будет - разве что при 8-битном режиме экрана.
Не знаю, что используется для преобразования из gif, но вообще по логике оно должно устанавливать 8-битный режим битмапа (проверить PixelFormat) - если уж в gif максимум 8 бит. Так что моё замечание относится скорее к примеру [9], где используется 32 бита.
Говорят, что ещё можно поставить PixelFormat := pfDevice (преобразование в DDB, который должен рисоваться быстрее) - но у меня в приведённом примере никакого ускорения от этого не получилось.



Страницы: 1 вся ветка

Форум: "Media";
Текущий архив: 2005.08.21;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.051 c
1-1122969042
vigo
2005-08-02 11:50
2005.08.21
Работа с строкой


11-1105726128
chum
2005-01-14 21:08
2005.08.21
Работа со строками


14-1122640053
NeMaster
2005-07-29 16:27
2005.08.21
как двигать мышь


1-1122724385
SergProger
2005-07-30 15:53
2005.08.21
Установочная прога


1-1122997110
sia
2005-08-02 19:38
2005.08.21
просмотр HTML





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский