Russian Qt Forum
Сентябрь 30, 2024, 12:35 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 [2] 3   Вниз
  Печать  
Автор Тема: QGraphicsView, QGraphicsScene для отображения огромного файла (2хОЗУ)  (Прочитано 31328 раз)
Khs
Гость
« Ответ #15 : Март 14, 2009, 22:33 »

боюсь предположить что там на картинке)))
Записан
sk8ter
Гость
« Ответ #16 : Март 14, 2009, 22:38 »

Это курсовая работа )) Картинку взял произвольную, чтобы как можно меньше было монотонных объектов ))
Записан
BRE
Гость
« Ответ #17 : Март 14, 2009, 22:41 »

На твоем месте я бы все проектировал иначе.
MyView должен только рисовать, не про какие файлы он знать не должен.

Делаешь класс MapImage, который занимается большим файлом. В нем делаешь функцию:
QImage *MapImage::getTile( int x, int y ) const
которая возвращает тебе указатель на загруженную картинку тайла.

Код
C++ (Qt)
class Tile : public QGraphicsItem
{
public:
   Tile( const MapImage *mapImage, int x, int y )
   void    load();
   void    unload();
 
private:
   MapImage *m_mapImage;
   QImage    *m_img;
   int             m_x;
   int             m_y;
};
 
void Tile::load()
{
   m_img = m_mapImage->getTile( m_x, m_y );
   update();
}
 
void Tile::unload()
{
   delete m_img;
   m_img = 0;
}
 
Нужно еще определить необходимые виртуальные методы (boundingRect и paint), что они должны делать думаю понятно из названия.
Записан
sk8ter
Гость
« Ответ #18 : Март 14, 2009, 22:53 »

Сейчас все исправлю Подмигивающий   Спс за урок!
Но вот про методы (boundingRect и paint) не понял...
их надо переопределить в классе Tile?
Записан
BRE
Гость
« Ответ #19 : Март 14, 2009, 22:55 »

Сейчас все исправлю Подмигивающий   Спс за урок!
Но вот про методы (boundingRect и paint) не понял...
их надо переопределить в классе Tile?
Ага, иначе не получиться создавать объекты Tile.
Записан
SABROG
Гость
« Ответ #20 : Апрель 16, 2009, 08:54 »

Куда-то автор темы пропал, очень уж интересно развитие событий. Удалось память то освободить?

Скомпилил прогу по выложенным исходникам, сконвертил .jpg файл на 8 мегов в .bmp на 38 мегов, переименовал в 1.bmp, но на экране как был черный квадрат малевича так и остался. И наличие и присутствие файла на эту черноту не влияет.
« Последнее редактирование: Апрель 16, 2009, 12:17 от SABROG » Записан
sk8ter
Гость
« Ответ #21 : Апрель 20, 2009, 22:19 »

Проблемы с памятью уже давно решены )))
Скоро буду реализовывать масштабирование...
Записан
sk8ter
Гость
« Ответ #22 : Апрель 20, 2009, 22:42 »

есть функция, которая возвращает нужный квадрат, только при перетаскивании такого изображения оно подтормаживает, это в общем-то не принципиально, но все же...
В С# есть такая классная штука как сериализация, хотелось бы из файла сразу выдергивать QImage, а не кажный раз при загрузке квадрата попиксельно заполнять его, ну или чтобы заполнение работало побыстрее...

Код
C++ (Qt)
QImage * MapImage::getTile(int x, int y)
{
   // Возвращает один квадрат
   int kolW = stInfoHead.biWidth / divide;
   fseek(pInFile2, (divide * divide * 3 * (y * kolW + x)), SEEK_SET);
   fread(mas, sizeof(RGBTRIPLE), divide*divide, pInFile2);
   QImage *img = new QImage(divide, divide, QImage::Format_RGB32);
   QRgb rgb;
   for(int i = 0; i < divide; i++)
       for(int j = 0; j < divide; j++)
       {
           rgb = qRgb(mas[i][j].rgbtRed, mas[i][j].rgbtGreen, mas[i][j].rgbtBlue);
           img->setPixel(j, i, rgb);         [color=red] // Вот тут тратится больше всего машинного времени[/color]
       }
   return img;
}

divide - размер квадрата  = 500  (500х500)
« Последнее редактирование: Апрель 20, 2009, 23:13 от pastor » Записан
SABROG
Гость
« Ответ #23 : Апрель 21, 2009, 08:52 »

В С# есть такая классная штука как сериализация, хотелось бы из файла сразу выдергивать QImage, а не кажный раз при загрузке квадрата попиксельно заполнять его, ну или чтобы заполнение работало побыстрее...
В принципе я поискал на тему сериализации/стриминга изображений с помощью методов Qt и пришел к плачевному выводу, что все картинки загружаются в ОЗУ полностью. Задал вопрос об этом на форуме QtCentre и wasyota мне ответил, что надо писать свой плагин, причем делать это надо для всех известных форматов, с нуля. Есть еще вариант с QImage::loadFromData, но он годится, скорее всего, только для bmp, т.к. надо генерить хедер формата и пихать нужный закодированный кусок пикселей в буффер. Как вариант - разбивать картинку другими программами.
Пытался использовать ImageMagick. Собрал его с помощью MinGW, но при запуске своей программы, с подлинкованными dll'ками ImageMagick, идет вылет с исключением. Еще вижу такой вариант - тупо скопировать плагины всех форматов и отредактировать их в новые плагины таким образом, чтобы метод QImageReader::setClipRect возвращал картинку без полной её загрузки в ОЗУ.

Еще насчет скроллинга QGraphicsView. Мне кажется лучше не использовать реальный скроллинг через scrollbar'ы. Просто установить какой-нибудь QGraphicsItem в размеры нужного окна и делать ему скроллинг на попытки его перетащить в его paint().
Записан
sk8ter
Гость
« Ответ #24 : Апрель 21, 2009, 10:25 »

Значит остается только попробовать QImage::loadFromData, т.к. я и работаю только с bmp.
Хотя в QImageReader есть такая штука как:
bool jumpToImage ( int imageNumber )
bool jumpToNextImage ()
но только они не хотят работать... надо разобраться как они считывают с одного файла несколько QImage..

Могу и не использовать реальный скролл, вам кажется что от этого скорость повысится?
Записан
SABROG
Гость
« Ответ #25 : Апрель 21, 2009, 11:23 »

jumpToImage и т.п., к сожалению работают только с анимацией (gif,mng?). Если даже пользовать через них, то большую картинку придется предварительно порезать на квадратики и сгенерить эту анимацию, где каждый фрейм будет этим квадратиком. Опять же придется искать программы или библиотеки, которые смогут сделать эту нарезку не загружая картинку целиком.

Цитировать
Могу и не использовать реальный скролл, вам кажется что от этого скорость повысится?
Скорее всего только в том случае, если окно будет небольшого размера, а размер тайла и окна будут иметь один размер. Плюс должны быть подгружены еще 8 невидимых соседних тайлов.
Записан
sk8ter
Гость
« Ответ #26 : Апрель 21, 2009, 20:22 »

значит оставлю как есть, скорости и так хватает при отрисовке )))
Попробую только с QImage::loadFromData, может выйдет быстрее... загрузка в QImage
Записан
SABROG
Гость
« Ответ #27 : Апрель 21, 2009, 22:41 »

Для теста тупо порезал через Total Commander .jpg файл в случайном месте (но явно после хедера). QLabel его свободно открывает. Единственно размер как бы прежний остается из-за чего в удаленном месте просто серые пиксили. Если как-нибудь узнать размеры хедеров, то файлы можно резать на лету. Правда никогда не знаешь какой кусок урезал большой или маленький Улыбающийся
Записан
sk8ter
Гость
« Ответ #28 : Апрель 24, 2009, 08:38 »

Попробую... а что за тулса резала? ))
Записан
SABROG
Гость
« Ответ #29 : Апрель 24, 2009, 17:11 »

В Total Commander есть функция Split, а в HIEW функция Trunc.
Записан
Страниц: 1 [2] 3   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.132 секунд. Запросов: 21.