Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 06.07.2010, 15:37   #1
Alex Cones
Trust no one.
Старожил
 
Аватар для Alex Cones
 
Регистрация: 07.04.2009
Сообщений: 6,526
По умолчанию Недостаточно памяти для большого битмапа

Код:
procedure TForm1.Button1Click(Sender: TObject);
Var
 Z,Y,X : Integer;
 Bit, Bitl : TBitMap;
 JPG : TJpegImage;
 SX, SY : String;
begin
 For Z := 5 to 7 Do
  Begin
   Bit := TBitMap.Create;
   Bit.Width := Round(Exp(Z *ln(2))) * 256;
   Bit.Height := Round(Exp(Z *ln(2))) * 256;
   For Y := 0 to Round(Exp(Z *ln(2))) - 1 Do
    For X := 0 to Round(Exp(Z *ln(2))) - 1 Do
     Begin
      Label1.Caption := 'Z = ' + IntToStr(Z) + '. ' +
                        'Y = ' + IntToStr(Y) + '. ' +
                        'X = ' + IntToStr(X) + '.';
      Application.ProcessMessages;
      SX := IntToStr(X);
      While Length(SX) <> 4 Do SX := '0'+SX;
      SY := IntToStr(Y);
      While Length(SY) <> 4 Do SY := '0'+SY;
      JPG := TJpegImage.Create;
      JPG.LoadFromFile('D:\Map\' + InttoStr(Z) + '\'+ SX + SY + '.jpeg');
      Bitl := TBitMap.Create;
      Bitl.Assign(JPG);
      Bit.Canvas.Draw(X * 256, Y * 256, Bitl);
      Bitl.Free;
      JPG.Free;
     End;
   Bit.SaveToFile('D:/' + IntToStr(Z) + '.bmp');
   Bit.Free;
  End;
end;
Размеры на шагах:
5 = 8192 х 8192
6 = 16384 х 16384
7 = 32768 х 32768
Размеры bmp файла на выходе:
5 = 128 мб
6 = 256 мб
7 = 512 мб

Как собственно обойти ошибку?
SQUARY PROJECT - НАБОР БЕСПЛАТНЫХ ПРОГРАММ ДЛЯ РАБОЧЕГО СТОЛА.
МОЙ БЛОГ
GRAY FUR FRAMEWORK - УДОБНАЯ И БЫСТРАЯ РАЗРАБОТКА WINAPI ПРИЛОЖЕНИЙ
Alex Cones вне форума Ответить с цитированием
Старый 06.07.2010, 15:49   #2
raxp
Старожил
 
Регистрация: 29.09.2009
Сообщений: 9,713
По умолчанию

довольно странно, т.к. максимальный размер блока памяти в windows для tbitmap 2 гига, где-то еще утечка
Разработки и научно-технические публикации :: Видеоблог :: Твиттер
Radar systems engineer & Software developer of industrial automation
raxp вне форума Ответить с цитированием
Старый 06.07.2010, 15:51   #3
Alex Cones
Trust no one.
Старожил
 
Аватар для Alex Cones
 
Регистрация: 07.04.2009
Сообщений: 6,526
По умолчанию

Причем вылетает на первом же шаге на
Код:
   Bit.Height := Round(Exp(Z *ln(2))) * 256;
До этого было For Z := 1 to 4 Do отработало прекрасно.
_______________________________
Поставил размер файла подкачки по требованию системы. 5-й шаг отработался.

В паинте создал картинку размером 32 000 х 32 000 - тоже выдало "недостаточно памяти".
16 000 х 16 000 создался, но при сохранении выдал тот же недостаток.
SQUARY PROJECT - НАБОР БЕСПЛАТНЫХ ПРОГРАММ ДЛЯ РАБОЧЕГО СТОЛА.
МОЙ БЛОГ
GRAY FUR FRAMEWORK - УДОБНАЯ И БЫСТРАЯ РАЗРАБОТКА WINAPI ПРИЛОЖЕНИЙ

Последний раз редактировалось Alex Cones; 06.07.2010 в 16:03.
Alex Cones вне форума Ответить с цитированием
Старый 06.07.2010, 19:01   #4
mutabor
Телепат с дипломом
Старожил
 
Аватар для mutabor
 
Регистрация: 10.06.2007
Сообщений: 4,929
По умолчанию

А ну ка, считаем, если 24 битный (3 байта), то 32768 * 32768 * 3 = ровно 3 ГБ.
У тебя есть 3 ГБ свободной виртуальной памяти?

з.ы. Если хочешь непременно такой огромный битмап, пиши его сразу в файловый поток на диск, если у тебя NTFS, то можешь писать пока место не закончится
Если в Линуксе работаешь, то я не помню какие там ограничения на размер файла в файловых системах.
The future is not a tablet with a 9" screen no more than the future was a 9" black & white screen in a box. It’s the paradigm that survives. (Kroc Camen)
Проверь себя! Онлайн тестирование | Мой блог

Последний раз редактировалось mutabor; 06.07.2010 в 19:05.
mutabor вне форума Ответить с цитированием
Старый 06.07.2010, 19:14   #5
Alex Cones
Trust no one.
Старожил
 
Аватар для Alex Cones
 
Регистрация: 07.04.2009
Сообщений: 6,526
По умолчанию

Цитата:
Если хочешь непременно
Хочу.
Цитата:
пиши его сразу в файловый поток
А можете показать, как?
SQUARY PROJECT - НАБОР БЕСПЛАТНЫХ ПРОГРАММ ДЛЯ РАБОЧЕГО СТОЛА.
МОЙ БЛОГ
GRAY FUR FRAMEWORK - УДОБНАЯ И БЫСТРАЯ РАЗРАБОТКА WINAPI ПРИЛОЖЕНИЙ
Alex Cones вне форума Ответить с цитированием
Старый 06.07.2010, 19:55   #6
mutabor
Телепат с дипломом
Старожил
 
Аватар для mutabor
 
Регистрация: 10.06.2007
Сообщений: 4,929
По умолчанию

Придется отказаться от всяких оболочек в виде TBitmap, и создавать битмап ручками, и по мере создания сразу писать его на диск, а не в память. В Delphi есть удобная штука TFileStream, он вполне подходит для той части к-рая будет писать на диск. Я даже название для него придумал TStreamBitmap Кстати погугли это название, мало ли

p.s. Конечно ни о какой скорости речи быть не может, сам понимаешь, запись на диск и чтение операции не из самых быстрых.
The future is not a tablet with a 9" screen no more than the future was a 9" black & white screen in a box. It’s the paradigm that survives. (Kroc Camen)
Проверь себя! Онлайн тестирование | Мой блог
mutabor вне форума Ответить с цитированием
Старый 06.07.2010, 20:35   #7
Alex Cones
Trust no one.
Старожил
 
Аватар для Alex Cones
 
Регистрация: 07.04.2009
Сообщений: 6,526
По умолчанию

Хм... Пеинт не создает 16 000 х 16 000. Не возникнет ли ситуация, что я не смогу открыть созданный файл?
Может есть обходной путь?

Я выкачал карты яндекса и теперь делатю так, чтобы этими "кусочками" можно было пользоваться. Что посоветуете?
SQUARY PROJECT - НАБОР БЕСПЛАТНЫХ ПРОГРАММ ДЛЯ РАБОЧЕГО СТОЛА.
МОЙ БЛОГ
GRAY FUR FRAMEWORK - УДОБНАЯ И БЫСТРАЯ РАЗРАБОТКА WINAPI ПРИЛОЖЕНИЙ
Alex Cones вне форума Ответить с цитированием
Старый 06.07.2010, 21:13   #8
mutabor
Телепат с дипломом
Старожил
 
Аватар для mutabor
 
Регистрация: 10.06.2007
Сообщений: 4,929
По умолчанию

Я не знаю точно спецификации на виндовый битмап (был еще битмап для OS/2), есть ли ограничения на размеры и какие они. Знаю что есть разные версии битмапа, последняя кажется пятая, но очень смутно припоминаю. Все это можно глянуть где нибудь на MSDN я думаю.

Если ограничений нет, то созданный файл можно будет открыть, но... лет через десять, когда памяти у всех будет по 100 гигов А пока его можно будет открыть только вашим софтом (к-рый будет динамически подгружать из файла нужные куски).

Цитата:
Я выкачал карты яндекса и теперь делатю так, чтобы этими "кусочками" можно было пользоваться. Что посоветуете?
Следить за исп. памятью (во время разработки я имею ввиду), динамически подгружать по кускам с диска, это в любом случае быстрее, чем если у юзера память заканчивается (ну не купил он еще себе 2 гига, и файл подкачки небольшой у него, и вообще он не знает что это такое) и наступает такой тормоз (система начинает перераспределять память) что мало не покажется
Можно сделать умную систему, к-рая сперва проверит как дела с памятью обстоят, и затем будет в зависимости от этого регулировать свои аппетиты, а значит и скорость работы.

Оч. интересно, а в каком формате карты? Какой-то один город, или побольше?

p.s. Посмотрел сколько Дубль гис кушает (это десктоп программа, карта города в ней), не более 100 мб, независимо от масштаба. Я думаю там вектор, это все объясняет, я и забыл совсем, в растре никто карты не делает.
The future is not a tablet with a 9" screen no more than the future was a 9" black & white screen in a box. It’s the paradigm that survives. (Kroc Camen)
Проверь себя! Онлайн тестирование | Мой блог

Последний раз редактировалось mutabor; 06.07.2010 в 21:22.
mutabor вне форума Ответить с цитированием
Старый 06.07.2010, 22:11   #9
Alex Cones
Trust no one.
Старожил
 
Аватар для Alex Cones
 
Регистрация: 07.04.2009
Сообщений: 6,526
По умолчанию

На то, что стоит у юзверя лично мне в данном случае наплевать, поскольку этими картами буду пользоваться я и мой сотоварищ с памятью в 2 раза больше моей (у меня 2, у него 4).

Карты в таком масштабе - весь мир в размерах:
256 х 256 (сохранено)
512 х 512 (сохранено)
1024 х 1024 (сохранено)
2048 х 2048 (сохранено)
4096 х 4096 (сохранено)
8192 х 8192 (сохранено)
16384 х 16384 (пока в кусочках по 256 х 256)
32768 х 32768 (аналогично)
65536 х 65536 (аналогично. Основная цель - получить эту карту в юзабельном виде)

Цитата:
последняя кажется пятая
Код:
typedef struct { 
  DWORD        bV5Size; 
  LONG         bV5Width; 
  LONG         bV5Height; 
  WORD         bV5Planes; 
  WORD         bV5BitCount; 
  DWORD        bV5Compression; 
  DWORD        bV5SizeImage; 
  LONG         bV5XPelsPerMeter; 
  LONG         bV5YPelsPerMeter; 
  DWORD        bV5ClrUsed; 
  DWORD        bV5ClrImportant; 
  DWORD        bV5RedMask; 
  DWORD        bV5GreenMask; 
  DWORD        bV5BlueMask; 
  DWORD        bV5AlphaMask; 
  DWORD        bV5CSType; 
  CIEXYZTRIPLE bV5Endpoints; 
  DWORD        bV5GammaRed; 
  DWORD        bV5GammaGreen; 
  DWORD        bV5GammaBlue; 
  DWORD        bV5Intent; 
  DWORD        bV5ProfileData; 
  DWORD        bV5ProfileSize; 
  DWORD        bV5Reserved; 
} BITMAPV5HEADER, *PBITMAPV5HEADER;
SQUARY PROJECT - НАБОР БЕСПЛАТНЫХ ПРОГРАММ ДЛЯ РАБОЧЕГО СТОЛА.
МОЙ БЛОГ
GRAY FUR FRAMEWORK - УДОБНАЯ И БЫСТРАЯ РАЗРАБОТКА WINAPI ПРИЛОЖЕНИЙ
Alex Cones вне форума Ответить с цитированием
Старый 06.07.2010, 22:37   #10
mutabor
Телепат с дипломом
Старожил
 
Аватар для mutabor
 
Регистрация: 10.06.2007
Сообщений: 4,929
По умолчанию

В любом случае лучше вектор (хотя, смотря какая карта). А если растр, как например на том же гугле вид со спутника, то там тайлами сделано, подгружается нужный кусок, если перетянул карту дальше, тот убирается (или в кэш, но лучше убрать) и подгружается новый, при изменении масштаба либо генерируются на лету растры из какого-то одного, либо под каждый масштаб своя база.

Цитата:
Основная цель - получить эту карту в юзабельном виде
Технически это не проблема. Я выше уже писал как это сделать, основная идея - подгружать с диска нужные куски в память. И даже не обязательно иметь один огромный файл, вполне подойдет база из небольших, так даже удобнее, не придется класс специально писать для работы с этим огромным файлом, а вполне можно обычный битмап юзать.

65536 х 65536 это 12 гб в общем. Если разбить его штук на 50, то будет в самый раз.

Я бы написал такой класс, в к-ром есть метод Загрузить и параметры
TBitmap - битмап приемник
и координаты в каком-то виде
При вызове этой функции она высчитает в каком/каких файле/файлах находится нужный кусок, и загрузит этот файл/файлы, и нужное скопирует в битмап приемник, к-рый можно будет обычным способом отображать. При каждом более менее большом сдвиге карты придется вызывать все время этот метод, а иначе никак, 12 гб растра в память никак не загрузишь.
The future is not a tablet with a 9" screen no more than the future was a 9" black & white screen in a box. It’s the paradigm that survives. (Kroc Camen)
Проверь себя! Онлайн тестирование | Мой блог

Последний раз редактировалось mutabor; 06.07.2010 в 23:00.
mutabor вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
"Недостаточно памяти для обработки команды..." _-Re@l-_ Общие вопросы Delphi 4 19.06.2010 17:51
Недостаточно памяти для отображения Lukker Microsoft Office Word 4 11.04.2010 08:07
Недостаточно памяти для обработки команды TBitMap finder_sl Мультимедиа в Delphi 12 03.03.2010 20:40
Массив TBitmap, "Недостаточно памяти для обработки команды" Роман Радер Мультимедиа в Delphi 5 05.04.2009 18:14
недостаточно оперативной памяти для отображения информации VVlad69 Microsoft Office Access 0 02.04.2009 14:51