Форум: "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.034 c