Russian Qt Forum

Qt => 2D и 3D графика => Тема начата: sk8ter от Март 08, 2009, 17:22



Название: QGraphicsView, QGraphicsScene для отображения огромного файла (2хОЗУ)
Отправлено: sk8ter от Март 08, 2009, 17:22
Общая задача: Есть графический файл *.bmp с разрешением примерно (40 000 х 30 000 точек), ясно что в ОЗУ не запихнешь, его нужно отобразить с возможностью перемещения БЕЗ каких либо тормозов.
Для того, чтобы отобразить такое большое изображение ясно что надо читать его с диска, для этого создаю свою структуру данных (т.е. свой файл, с которым буду работать). В эти подробности вникать не стоит, важно то, что могу из него прочитать заданный квадрат, разрешением (допустим) 500х500 пикселей в матрицу такого же размера (RGBTRIPLE mas[divide][divide];   //divide = 500).
Есть массив, каждый елемент которого указывает на соответствующую загруженную матрицу (указатели в матрице постоянно меняются при перемещении - загружаются новые блоки, а старые стираются) (Считываются только нужные блоки).
Сам вопрос: Как сделать чтобы при перемещении изображения полосами прокрутки или мышью, актуальные массивы отображались на экране?



Название: Re: QGraphicsView, QGraphicsScene для отображения огромного файла (2хОЗУ)
Отправлено: BRE от Март 08, 2009, 18:03
Такой вопрос, как работают тайловые (tile) карты в 2D играх ты представляшь?
Такие вещи легко обьяснить с листом бумаги и карандашом, а так писанины очень много может получиться.


Название: Re: QGraphicsView, QGraphicsScene для отображения огромного файла (2хОЗУ)
Отправлено: sk8ter от Март 08, 2009, 18:24
нет, к сожалению не представляю..., спс - обращу на них внимание...
Согласен что с листом бумаги объясняется за 2 мин, но ... это не листок бумаги


Название: Re: QGraphicsView, QGraphicsScene для отображения огромного файла (2хОЗУ)
Отправлено: BRE от Март 08, 2009, 18:53
Размер карты в точках mapSize = 40000x30000
Размер тайла tileSize = 500x500
Вся карта 80x60 тайлов

Для отображения части карты на экране вводим понятия - окно-просмотра (viewport), для простоты - 1000x1000 точки или 2x2 тайла.
Это окно, как бы накладывается на карту и его можно по ней двигать.
Делаем переменную posViewport, которая показывает положение viewport в точках.
Когда posViewport == [0, 0], это значит окно-просмотра находиться в верхнем левом углу карты.
Конечные координаты на которые можно сдвинуть это окно [39000,29000].

Теперь нам нужно понять какие тайлы сейчас видны на экране.
viewTile.x = posViewport.x / tileSize.x;
viewTile.y = posViewport.y / tileSize.y;

Пример:
posViewport = 1024,370;
scrollTile.x = 2;
scrollTile.y = 0;

Значит нам нужны тайлы (т.к. на viewport помещается только два тайла):
0 1 2 3 4 5 6 7 8 ...
1    * *
2    * *
3
4
5

Но, нам нужно еще сделать скролинг по-пиксельно, поэтому в память загружаем еще по одному ряду и столбцу тайлов.
0 1 2 3 4 5 6 7 8 ...
1    * *  +
2    * *  +
3    + + +
4
5

Для получения сдвига в точках уже относительно тайлов, делаем:
scrollPixel.x = posViewport.x % tileSize.x;
scrollPixel.y = posViewport.y % tileSize.y;
Для нашего примера:
scrollPixel = [ 24, 370 ]

Пока так, а то может я непонятно объясняю.  ;)


Название: Re: QGraphicsView, QGraphicsScene для отображения огромного файла (2хОЗУ)
Отправлено: sk8ter от Март 08, 2009, 19:08
Почему же не понятно, пока все понятно!
Интересный вариант ;)
а можно так сделать, чтобы в памяти с каждой стороны было еще допустим по 2 тайла? чтобы если переташить совсем немного к жесткому диску заново не обращаться?


Название: Re: QGraphicsView, QGraphicsScene для отображения огромного файла (2хОЗУ)
Отправлено: BRE от Март 08, 2009, 19:16
Почему же не понятно, пока все понятно!
Интересный вариант ;)
а можно так сделать, чтобы в памяти с каждой стороны было еще допустим по 2 тайла? чтобы если переташить совсем немного к жесткому диску заново не обращаться?
Почему нет, это тебе решать...
Теперь к QGraphics:
Делаем сцену размером 40000x30000, на ней один к одному размещаем объекты tile, каждый из которых будет знать какую часть карты он должен выводить, но сами картинки еще не загружаем.
И теперь в зависимости от текущего сдвига определяем какие тайлы в данный момент видны в viewport и соответствующим тайлам говорим (+их сосетям) говорим загрузить картинки из файла. После изменения текущего сдивга viewport, определяем какие теперь тайлы видны и невидимых говорим удалить картинки из памяти.

Можно динамически создавать необходимые тайлы и размещать их на сцене. Вообщем много чего можно сделать.  :)


Название: Re: QGraphicsView, QGraphicsScene для отображения огромного файла (2хОЗУ)
Отправлено: sk8ter от Март 08, 2009, 19:38
спс, уже пробую...      Ты не вкурсе, почему этих тайлов в qt4 нет? Это немного настораживает.
если будут другие варинты - внимательно выслушаю.


Название: Re: QGraphicsView, QGraphicsScene для отображения огромного файла (2хОЗУ)
Отправлено: BRE от Март 08, 2009, 19:40
спс, уже пробую...      Ты не вкурсе, почему этих тайлов в qt4 нет? Это немного настораживает.

Код
C++ (Qt)
class Tile : public QGraphicsItem
{
...
};
 


Название: Re: QGraphicsView, QGraphicsScene для отображения огромного файла (2хОЗУ)
Отправлено: sk8ter от Март 08, 2009, 19:51
похоже все намного проще чем я думал )


Название: Re: QGraphicsView, QGraphicsScene для отображения огромного файла (2хОЗУ)
Отправлено: sk8ter от Март 09, 2009, 21:52
Кстати, если комуто надо - могу после того как сделаю выложить исходники!!!


Название: Re: QGraphicsView, QGraphicsScene для отображения огромного файла (2хОЗУ)
Отправлено: sk8ter от Март 14, 2009, 21:05
Делал по разному...  много способов пробовал, вот один из способов:
При нажатии на кнопку, поидее память должна освободится, но .....  увы...

main.cpp
Код:
#include <QtGui>
#include <iostream.h>
#include "MyView.h"


int main(int argc, char** argv)
{
    QApplication   app(argc, argv);
    QGraphicsScene scene(QRectF(0, 0, 30000, 30000));
    MyView * pView      = new MyView(&scene);
    QWidget w;
    QPushButton *btn = new QPushButton("Button", pView);
    QHBoxLayout *lay = new QHBoxLayout;
    QObject::connect(btn, SIGNAL(clicked()), pView, SLOT(pressBotton()));

    std::cout<<"run\n";
    pView->init();
    //pView->show();

    lay->addWidget(btn);
    lay->addWidget(pView);

    w.setLayout(lay);
    w.show();
 
    return app.exec();
}

tile.h
Код:
#ifndef TILE_H
#define TILE_H

#include <QtGui>

class Tile
{
private:
    int x;
    int y;
    QGraphicsRectItem * rect;
public:
    Tile(int pos_x, int pos_y, QGraphicsRectItem * qGraphicsRectItem)
    {
        x = pos_x;
        y = pos_y;
        rect = qGraphicsRectItem;
    }
    int pos_x()
    { return x; }
    int pos_y()
    { return y; }
    QGraphicsRectItem* item()
    { return rect; }
};

#endif // TILE_H

MyView.h
Код:
#ifndef _MyView_h_
#define _MyView_h_

#include <QGraphicsView>
#include <windows.h>
#include "tile.h"


class MyView: public QGraphicsView {
    Q_OBJECT
public:
    MyView(QGraphicsScene* pScene, QWidget* pwgt = 0)
        : QGraphicsView(pScene, pwgt)
    {
        resize(1000, 800);
        setDragMode(QGraphicsView::ScrollHandDrag);
    }

private:
    static const int divide = 500;
    RGBTRIPLE mas[divide][divide];
    tagBITMAPFILEHEADER stHead;
    tagBITMAPINFOHEADER stInfoHead;
    FILE *pInFile2;
    QList<Tile *> tileList;

public slots:
    void pressBotton();

private slots:
    void scrollBars();

public:
    void moved(int verticalScrollBar, int horizontalScrollBar);
    void init();
    Tile * showRect(int x, int y);
};

#endif  //_MyView_h_

MyView.cpp
Код:
#include "MyView.h"
#include "tile.h"
#include <QtGui>
#include <iostream>
using namespace std;


void MyView::scrollBars()
{
    moved(this->verticalScrollBar()->value(), this->horizontalScrollBar()->value());
}

void MyView::moved(int verticalScrollBar, int horizontalScrollBar)
{
    static int qw = 1;
    if (qw == 1)
    {
        qw--;
        return;
    }

    // Сохраняем
    static int xx = 0, yy = 0;


    //Теперь нам нужно понять какие тайлы сейчас видны на экране.
    int viewTile_x = horizontalScrollBar / divide;
    int viewTile_y = verticalScrollBar / divide;
    int colTile_x = ((this->rect().height() + (verticalScrollBar % divide)) / divide) + 1;
    int colTile_y = ((this->rect().width() + (horizontalScrollBar % divide)) / divide) + 1;
    cout<<"\nhor: "<< viewTile_x <<" "<<colTile_x;
    cout<<"\nver: "<< viewTile_y <<" "<<colTile_y;


    std::cout<< "\nvert x hor: " << verticalScrollBar << " x " << horizontalScrollBar;
    if ((abs(xx - viewTile_x) + abs(yy - viewTile_y)) < 1)
        return;


    // Отображение
    for (int y = viewTile_y; y < viewTile_y + colTile_y; y++)
        for (int x = viewTile_x; x < viewTile_x + colTile_x + 1; x++)
        {
            tileList.append(showRect(x, y));
        }

    xx = viewTile_x;
    yy = viewTile_y;
}


void MyView::init()
{
    connect(this->horizontalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(scrollBars()));
    connect(this->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(scrollBars()));

    // Чтение изображения из файла
    FILE *pInFile;
    if ((pInFile = fopen("1.bmp", "rb")) != NULL)
    {
        // Чтение заголовков
        fread(&stHead, sizeof(tagBITMAPFILEHEADER), 1, pInFile);
        fread(&stInfoHead, sizeof(tagBITMAPINFOHEADER), 1, pInFile);
        fclose(pInFile);
        cout<<"file readed\n";
    }

    cout<<"\nWidth: "<<stInfoHead.biWidth;
    cout<<"\nHeight: "<<stInfoHead.biHeight;


    // Преобразование файла в свою структуру данных
    if ((pInFile2 = fopen("1.slko", "rb")) == NULL)
    {
        RGBTRIPLE ** BitMap = new RGBTRIPLE *[divide];
        FILE *pInFile1 = fopen("1.slko", "wb");

        for(int i = 0; i < divide; i++)
        {
            BitMap[i] = new RGBTRIPLE[stInfoHead.biWidth];
        }
        cout<<"\nkontrol point 1\n";
        for(int col_h = stInfoHead.biHeight / divide; col_h > 0 ; col_h--)
        {
            for (int i = 0; i < divide; i++)
            {
                fseek(pInFile, (stHead.bfOffBits + ((stInfoHead.biWidth * 3) * ((divide * col_h) - i))), SEEK_SET);
                fread(BitMap[i], sizeof(RGBTRIPLE), stInfoHead.biWidth, pInFile);
            }
            cout<<"kontrol point 2\n";

            // Осталось разбить матрицу (500 х stInfoHead.biWidth) на квадраты
            for (int y = 0; y < stInfoHead.biWidth / divide; y++)
            {
                for (int j = 0; j < divide; j++)
                {
                    for (int k = 0; k < divide; k++)
                    {
                        mas[j][k] = BitMap[j][y * divide + k];
                    }
                }
                fwrite(mas, sizeof(RGBTRIPLE), divide*divide, pInFile1);
            }
        }
        cout<<"kontrol point";
        fclose(pInFile1);
        pInFile2 = fopen("1.slko", "rb");
    }
}


Tile * MyView::showRect(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);
    for(int i = 0; i < divide; i++)
        for(int j = 0; j < divide; j++)
        {
            QRgb rgb = qRgb(mas[i][j].rgbtRed, mas[i][j].rgbtGreen, mas[i][j].rgbtBlue);
            img->setPixel(j, i, rgb);
        }
    QGraphicsRectItem * item = new QGraphicsRectItem(x * divide, y * divide, divide, divide, 0, this->scene());
    //item->setPen(Qt::NoPen);
    item->setBrush(QPixmap::fromImage(*img));
    Tile *tile = new Tile(x, y, item);

    return tile;

    //this->scene()->itemAt(x * divide, y * divide)->~QGraphicsItem();
    //return this->scene()->addRect(x * divide, y * divide, divide, divide, Qt::NoPen, QBrush(QPixmap::fromImage(*img)));
}


void MyView::pressBotton()
{
    cout<<"\nPress";

    cout<<"\ntile count: "<<tileList.count();
    QList<QGraphicsItem *> oldList;
    oldList = this->scene()->items();
    cout<<"\noldList: "<<oldList.count();

    for (int i = 0; i < tileList.count(); ++i)
    {
        cout<<'\n'<<tileList[i]->pos_x();
        tileList[i]->item()->~QGraphicsRectItem();
        tileList.removeAt(i);
    }
}


Название: Re: QGraphicsView, QGraphicsScene для отображения огромного файла (2хОЗУ)
Отправлено: Rcus от Март 14, 2009, 21:29
/*:D*/
new QGraphicsRectItem...
удалять надо через delete, а еще для удаления всех объектов в контейнере указателей есть qDeleteAll, а еще есть
Цитировать
void QGraphicsScene::clear ()   [slot]

Removes and deletes all items from the scene, but otherwise leaves the state of the scene unchanged.
и создавать QGraphicsRectItem можно через
Цитировать
QGraphicsRectItem * addRect ( const QRectF & rect, const QPen & pen = QPen(), const QBrush & brush = QBrush() )
запись с указанием сцены последним параметром вообще недокументирована,
Код:
    QGraphicsItem(QGraphicsItem *parent = 0
#ifndef Q_QDOC
                  // obsolete argument
                  , QGraphicsScene *scene = 0
#endif
        );


Название: Re: QGraphicsView, QGraphicsScene для отображения огромного файла (2хОЗУ)
Отправлено: sk8ter от Март 14, 2009, 21:54
Даже если сделать так, в Диспетчере задач память не уменьшится...
Уже не знаю что делать....   в итоге она закончится и программа вылетит...

Код:
void MyView::pressBotton()
{
    cout<<"\nPress";

    cout<<"\ntile count: "<<tileList.count();
    cout<<"\noldList: "<<this->scene()->items().count();

    tileList.clear();
    this->scene()->clear();
}


Название: Re: QGraphicsView, QGraphicsScene для отображения огромного файла (2хОЗУ)
Отправлено: Rcus от Март 14, 2009, 22:02
Диспетчер задач никогда не пытался заменить средства по анализу утечек памяти. Можно что-то компилируемое посмотреть? А то я не вижу как удаляются QImage и Tile.


Название: Re: QGraphicsView, QGraphicsScene для отображения огромного файла (2хОЗУ)
Отправлено: sk8ter от Март 14, 2009, 22:26
Я все тексты выложил и все должно компилироваться.
Вот:(http://pic.ipicture.ru/uploads/090314/Lvq20Ewrbc.jpg)

Только что обнаружил такую фишку:
в развернутом состоянии, когда прокручиваешь изображение прога весит > 20 Мб, и растет при загрузке новых тайлов, в свернутом состоянии прога весит 1.5 Мб, , потом обратно разворачиваешь - опять растет с 20 и дальше...
Что за бред :)

Цитировать
А то я не вижу как удаляются QImage и Tile.
Они и не удаляются, я не знаю ка это сделать ;)


Название: Re: QGraphicsView, QGraphicsScene для отображения огромного файла (2хОЗУ)
Отправлено: Khs от Март 14, 2009, 22:33
боюсь предположить что там на картинке)))


Название: Re: QGraphicsView, QGraphicsScene для отображения огромного файла (2хОЗУ)
Отправлено: sk8ter от Март 14, 2009, 22:38
Это курсовая работа )) Картинку взял произвольную, чтобы как можно меньше было монотонных объектов ))


Название: Re: QGraphicsView, QGraphicsScene для отображения огромного файла (2хОЗУ)
Отправлено: BRE от Март 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), что они должны делать думаю понятно из названия.


Название: Re: QGraphicsView, QGraphicsScene для отображения огромного файла (2хОЗУ)
Отправлено: sk8ter от Март 14, 2009, 22:53
Сейчас все исправлю ;)   Спс за урок!
Но вот про методы (boundingRect и paint) не понял...
их надо переопределить в классе Tile?


Название: Re: QGraphicsView, QGraphicsScene для отображения огромного файла (2хОЗУ)
Отправлено: BRE от Март 14, 2009, 22:55
Сейчас все исправлю ;)   Спс за урок!
Но вот про методы (boundingRect и paint) не понял...
их надо переопределить в классе Tile?
Ага, иначе не получиться создавать объекты Tile.


Название: Re: QGraphicsView, QGraphicsScene для отображения огромного файла (2хОЗУ)
Отправлено: SABROG от Апрель 16, 2009, 08:54
Куда-то автор темы пропал, очень уж интересно развитие событий. Удалось память то освободить?

Скомпилил прогу по выложенным исходникам, сконвертил .jpg файл на 8 мегов в .bmp на 38 мегов, переименовал в 1.bmp, но на экране как был черный квадрат малевича так и остался. И наличие и присутствие файла на эту черноту не влияет.


Название: Re: QGraphicsView, QGraphicsScene для отображения огромного файла (2хОЗУ)
Отправлено: sk8ter от Апрель 20, 2009, 22:19
Проблемы с памятью уже давно решены )))
Скоро буду реализовывать масштабирование...


Название: Re: QGraphicsView, QGraphicsScene для отображения огромного файла (2хОЗУ)
Отправлено: sk8ter от Апрель 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)


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

Еще насчет скроллинга QGraphicsView. Мне кажется лучше не использовать реальный скроллинг через scrollbar'ы. Просто установить какой-нибудь QGraphicsItem в размеры нужного окна и делать ему скроллинг на попытки его перетащить в его paint().


Название: Re: QGraphicsView, QGraphicsScene для отображения огромного файла (2хОЗУ)
Отправлено: sk8ter от Апрель 21, 2009, 10:25
Значит остается только попробовать QImage::loadFromData, т.к. я и работаю только с bmp.
Хотя в QImageReader есть такая штука как:
bool jumpToImage ( int imageNumber )
bool jumpToNextImage ()
но только они не хотят работать... надо разобраться как они считывают с одного файла несколько QImage..

Могу и не использовать реальный скролл, вам кажется что от этого скорость повысится?


Название: Re: QGraphicsView, QGraphicsScene для отображения огромного файла (2хОЗУ)
Отправлено: SABROG от Апрель 21, 2009, 11:23
jumpToImage и т.п., к сожалению работают только с анимацией (gif,mng?). Если даже пользовать через них, то большую картинку придется предварительно порезать на квадратики и сгенерить эту анимацию, где каждый фрейм будет этим квадратиком. Опять же придется искать программы или библиотеки, которые смогут сделать эту нарезку не загружая картинку целиком.

Цитировать
Могу и не использовать реальный скролл, вам кажется что от этого скорость повысится?
Скорее всего только в том случае, если окно будет небольшого размера, а размер тайла и окна будут иметь один размер. Плюс должны быть подгружены еще 8 невидимых соседних тайлов.


Название: Re: QGraphicsView, QGraphicsScene для отображения огромного файла (2хОЗУ)
Отправлено: sk8ter от Апрель 21, 2009, 20:22
значит оставлю как есть, скорости и так хватает при отрисовке )))
Попробую только с QImage::loadFromData, может выйдет быстрее... загрузка в QImage


Название: Re: QGraphicsView, QGraphicsScene для отображения огромного файла (2хОЗУ)
Отправлено: SABROG от Апрель 21, 2009, 22:41
Для теста тупо порезал через Total Commander .jpg файл в случайном месте (но явно после хедера). QLabel его свободно открывает. Единственно размер как бы прежний остается из-за чего в удаленном месте просто серые пиксили. Если как-нибудь узнать размеры хедеров, то файлы можно резать на лету. Правда никогда не знаешь какой кусок урезал большой или маленький :)


Название: Re: QGraphicsView, QGraphicsScene для отображения огромного файла (2хОЗУ)
Отправлено: sk8ter от Апрель 24, 2009, 08:38
Попробую... а что за тулса резала? ))


Название: Re: QGraphicsView, QGraphicsScene для отображения огромного файла (2хОЗУ)
Отправлено: SABROG от Апрель 24, 2009, 17:11
В Total Commander есть функция Split, а в HIEW функция Trunc.


Название: Re: QGraphicsView, QGraphicsScene для отображения огромного файла (2хОЗУ)
Отправлено: sk8ter от Май 05, 2009, 17:51
В Total Commander есть функция Split, а в HIEW функция Trunc.
А у меня что-то не выходит...

Подскажите как можно быстро загрузить в QImage данные из RGBTRIBLE, которая находится в оперативке...

Или же формировать один файл, с которого можно читать заданный Image...


Название: Re: QGraphicsView, QGraphicsScene для отображения огромного файла (2хОЗУ)
Отправлено: sk8ter от Май 11, 2009, 19:09
Всем спасибо, все готово, в том числе и зуммирование!!!    На днях сдаю курсовую :)


Название: Re: QGraphicsView, QGraphicsScene для отображения огромного файла (2хОЗУ)
Отправлено: break от Май 17, 2009, 03:41
Вопрос к знатокам - а правильно ли изначально использоватьо огромный файл картинки? (возможно буду решать подобную задачу - только не курсовую а программу для людей)

Если предположить что решаемаяч задача - карта местности - может эти тайлы (изображение подложки карты) должны были отдельно на диске лежать tile01.jpg, tile02.jpg

И вообще всякие фотошопы как с файлом 40000 на 30000 справляются?


Название: Re: QGraphicsView, QGraphicsScene для отображения огромного файла (2хОЗУ)
Отправлено: transto от Август 04, 2009, 03:13
Всем спасибо, все готово, в том числе и зуммирование!!!

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




Название: Re: QGraphicsView, QGraphicsScene для отображения огромного файла (2хОЗУ)
Отправлено: sk8ter от Август 10, 2009, 16:29

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


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


Название: Re: QGraphicsView, QGraphicsScene для отображения огромного файла (2хОЗУ)
Отправлено: sk8ter от Август 10, 2009, 16:35
Вопрос к знатокам - а правильно ли изначально использоватьо огромный файл картинки? (возможно буду решать подобную задачу - только не курсовую а программу для людей)

Если предположить что решаемаяч задача - карта местности - может эти тайлы (изображение подложки карты) должны были отдельно на диске лежать tile01.jpg, tile02.jpg

И вообще всякие фотошопы как с файлом 40000 на 30000 справляются?

мой одногрупник скачал на Java движок GoogleEarth и немного его модернизировал... так что было на диске множество файлов и нужные подгружались автоматически, он же и разбивал большой рисунок на мелкие...

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

А вот насчет фотошопа - он походу конвертирует файл в свою структуру данных (для ускорения работы) и с ним работает.


Название: Re: QGraphicsView, QGraphicsScene для отображения огромного файла (2хОЗУ)
Отправлено: Igors от Август 10, 2009, 19:10
Добрый день
И вообще всякие фотошопы как с файлом 40000 на 30000 справляются?
Базовая техника одна. Никто не держит изображение в RAM целиком. Файл распаковывается во временный файл (или в общий swap файл) "по страницам" (по tile, по квадратикам - называйте как хотите). В памяти хранится "карта" страниц

struct CImagePage {
  CImagePage * mPrev;  // prev page in list
  CImagePage * mNext;  // next page in list
  long long mFilePos;      // file position
  void * mPixels;           // pixels or NULL for purged page
  bool  mDirty;              // page has been modofied
  ...
};

Загруженные страницы хранятся в списке 1, не загруженные - в списке 2. Если затребованная страница не загружена, она
загружается и переносится в голову списка 1. Если длина списка 1 превышает заданную, страница в хвосте списка 1 выгружается и переносится в список 2 . Счетчик "не больше N страниц в памяти" определяет скорость/расход памяти   


Название: Re: QGraphicsView, QGraphicsScene для отображения огромного файла (2хОЗУ)
Отправлено: break от Август 10, 2009, 21:49
Цитировать
мой одногрупник скачал на Java движок GoogleEarth и немного его модернизировал...[/
quote]

где такое скачать можно?


Название: Re: QGraphicsView, QGraphicsScene для отображения огромного файла (2хОЗУ)
Отправлено: Сергей(ser) от Декабрь 14, 2010, 16:27
Всем спасибо, все готово, в том числе и зуммирование!!!    На днях сдаю курсовую :)


sk8ter !!!! выложи исходники plz...


Название: Re: QGraphicsView, QGraphicsScene для отображения огромного файла (2хОЗУ)
Отправлено: slim от Январь 06, 2011, 19:39
советую посмотреть на такую штуку http://ru.wikipedia.org/wiki/%D0%9C%D0%B5%D0%B3%D0%B0%D1%82%D0%B5%D0%BA%D1%81%D1%82%D1%83%D1%80%D0%B0