Russian Qt Forum

Qt => 2D и 3D графика => Тема начата: define от Июль 18, 2011, 12:40



Название: вопрос по QImage
Отправлено: define от Июль 18, 2011, 12:40
Добрый день,
подскажите пожалуйста, как можно разбить изображение в QImage на несколько QRect?
Например левая половина изображения в одном прямоугольнике, а другая соответственно во втором.
Спасибо.


Название: Re: вопрос по QImage
Отправлено: Пантер от Июль 18, 2011, 12:41
QImage QImage::copy ( const QRect & rectangle = QRect() ) const


Название: Re: вопрос по QImage
Отправлено: define от Июль 18, 2011, 13:44
QImage QImage::copy ( const QRect & rectangle = QRect() ) const

ага, так, а если сделать немного иначе.
Предположим у меня есть путь к изображению. Как подгрузить по отдельности эти 2 прямоугольника?
(те не загружать QImage целиком и не разбивать его)


Название: Re: вопрос по QImage
Отправлено: Fess от Июль 18, 2011, 13:52
Никак.
Если не хотите писать свой MyImage, который умеет грузить изображения по кускам (не читая весь файл). Не удивлюсь, если некоторые форматы вообще нельзя будет загрузить таким образом.


Название: Re: вопрос по QImage
Отправлено: define от Июль 18, 2011, 14:08
а если прочитать по байтам, а потом
QImage fromData ( const QByteArray & data, const char * format = 0 )
так не получится?


Название: Re: вопрос по QImage
Отправлено: Fess от Июль 18, 2011, 19:38
Вот я вам и говорю. Нужно смотреть формат файла, вручную считывать нужные фрагменты, а они будут идти скорее всего с каким-то шагом.
Скармливать все полученное QImage и пр.
Куда уж лучше - прочитал изображение - взял фрагмент - используй.
Или у вас оч. большие изображения и ограничения по производительности?
Попробуйте описать задачу. Может достаточно просто вынести загрузку в отдельный поток? Или кешировать фрагменты?


Название: Re: вопрос по QImage
Отправлено: Igors от Июль 18, 2011, 19:56
Никак.
Если не хотите писать свой MyImage, который умеет грузить изображения по кускам (не читая весь файл). Не удивлюсь, если некоторые форматы вообще нельзя будет загрузить таким образом.
Формат который умеет грузить "по прямоугольникам" - мне такой вообще неизвестен. Многие позволяют грузить по строкам - но там разбираться с каждым себе дороже

(те не загружать QImage целиком и не разбивать его)
Именно так. Сначала загрузить весь файл, нарезать его на нужные прямоугольники, сохранить их во временных файлах и с ними уже манипулировать.

Edit: в принципе это стандартная техника подкачки больших изображений постранично


Название: Re: вопрос по QImage
Отправлено: define от Июль 18, 2011, 19:57
Задача состоит в отображении огромного изображения. Причем необходимо выводить "промежуточные" результаты.
(те если грузим одно большое изображение, то сначала отображается половина, а затем и все изображение(по сути по мере загрузки)). Загрузку я выполняю в отдельном потоке:
Код:
void ShowImage::run()
{
    //для уничтожения потока
    setTerminationEnabled(true);

    AdvImage tmp = list->at(pos);

    QImage image(tmp.getPath());//tmp.getPath() - путь к изображению

    int temp_h = image.size().height();
    int temp_w = image.size().width();

    if(temp_w>temp_h)//сравнение ширины и высоты изображения
    {
        temp_h=_h;
        _h=_w;
        _w=temp_h;
    }

    image = image.scaled(_w,_h);

    label->setPixmap(QPixmap::fromImage(image));}
была ещё мысль использовать QImageReader, а именно метод setQuality. Попробовал и вне зависимости от значения изображение грузилось в одном и том же качестве.
Код:
QImageReader reader;
    reader.setQuality(20);
    reader.setFileName(tmp.getPath());
    QImage image = reader.read();
Как-то вот так. В чем проблема с setQuality и что можете сказать насчет разбиения изображения. Спасибо.


Название: Re: вопрос по QImage
Отправлено: define от Июль 18, 2011, 21:10
Сначала загрузить весь файл
Ох и долго же этот может выполняться :(


Название: Re: вопрос по QImage
Отправлено: Ubuntu_linux от Июль 18, 2011, 22:41
Никак.
Если не хотите писать свой MyImage, который умеет грузить изображения по кускам (не читая весь файл). Не удивлюсь, если некоторые форматы вообще нельзя будет загрузить таким образом.
А вот и не правда! Достаточно прочитать асистент по QImageReader
который может загружать изображение в нужном размере и также
загрузить нужную область изображения. Удачи!


Название: Re: вопрос по QImage
Отправлено: define от Июль 18, 2011, 22:46
А вот и не правда! Достаточно прочитать асистент по QImageReader
который может загружать изображение в нужном размере и также
загрузить нужную область изображения. Удачи!
рабочий или хоть какой пример можно? Заранее благодарю.


Название: Re: вопрос по QImage
Отправлено: Igors от Июль 19, 2011, 11:50
Достаточно прочитать асистент по QImageReader
который может загружать изображение в нужном размере и также
загрузить нужную область изображения.
Ладно, давайте почитаем. Пишут
Цитировать
QImageIOHandler::ClipRect   1   The clip rect, or ROI (Region Of Interest). A handler that supports this option is expected to only read the provided QRect area from the original image in read(), before any other transformation is applied.
Но только если reader (конкретного формата) поддерживает такую возможность. Смотрим напр для PNG
Код
C++ (Qt)
bool QPngHandler::supportsOption(ImageOption option) const
{
   return option == Gamma
       || option == Description
       || option == ImageFormat
       || option == Quality
       || option == Size;
}
 
Не вижу здесь ClipRect, значит с PNG эта радость недоступна.  Смотрим для JPG - тоже нет. Для др. форматов - опять нет. Или я ошибаюсь?


Название: Re: вопрос по QImage
Отправлено: GreatSnake от Июль 19, 2011, 12:21
Для др. форматов - опять нет. Или я ошибаюсь?
Судя по исходникам только в svg)


Название: Re: вопрос по QImage
Отправлено: Ubuntu_linux от Июль 19, 2011, 14:31
Достаточно прочитать асистент по QImageReader
который может загружать изображение в нужном размере и также
загрузить нужную область изображения.
Ладно, давайте почитаем. Пишут
Цитировать
QImageIOHandler::ClipRect   1   The clip rect, or ROI (Region Of Interest). A handler that supports this option is expected to only read the provided QRect area from the original image in read(), before any other transformation is applied.
Но только если reader (конкретного формата) поддерживает такую возможность. Смотрим напр для PNG
Код
C++ (Qt)
bool QPngHandler::supportsOption(ImageOption option) const
{
   return option == Gamma
       || option == Description
       || option == ImageFormat
       || option == Quality
       || option == Size;
}
 
Не вижу здесь ClipRect, значит с PNG эта радость недоступна.  Смотрим для JPG - тоже нет. Для др. форматов - опять нет. Или я ошибаюсь?
А вот и не правда! Надо било просто попробивать и все стало бы на
свои места. Все нормально работает с jpg и png.

QImageReader *reader=new QImageReader("file name");
reader->setClipRect(QRect(0,0,100,300));
ui->label_pix->setPixmap(QPixmap::fromImage(reader->read()));

Вот такие дела, прикиньте...


Название: Re: вопрос по QImage
Отправлено: BRE от Июль 19, 2011, 14:35
Ubuntu_linux, а точно что реадер не загружает всю картинку в память, а потом вырезает нужный кусок?


Название: Re: вопрос по QImage
Отправлено: Ubuntu_linux от Июль 19, 2011, 15:08
Ubuntu_linux, а точно что реадер не загружает всю картинку в память, а потом вырезает нужный кусок?
Точно, так и написано.


Название: Re: вопрос по QImage
Отправлено: Igors от Июль 19, 2011, 16:12
Судя по исходникам только в svg)
Даже если предположить что define устраивают только svg файлы - все равно не подходит  :)

А вот и не правда! Надо било просто попробивать и все стало бы на
свои места. Все нормально работает с jpg и png.

QImageReader *reader=new QImageReader("file name");
reader->setClipRect(QRect(0,0,100,300));
ui->label_pix->setPixmap(QPixmap::fromImage(reader->read()));

Вот такие дела, прикиньте...
С этим никто не спорит, но это достигается чтением всего файла - а потом вырезанием куска. Что легче сделать самому.


Название: Re: вопрос по QImage
Отправлено: define от Июль 19, 2011, 16:56
Из темы пока понятно, что подгружать изображение формата не svg кусками не представляется реальным.
Как ещё можно ускорить загрузку большого изображения? Возможно ли при загрузке изображения как-то ухудшить его качество?


Название: Re: вопрос по QImage
Отправлено: ufna от Июль 19, 2011, 17:22
почему? просто надо заюзать другие либы или читать напрямую формат файла.


Название: Re: вопрос по QImage
Отправлено: define от Июль 19, 2011, 17:37
Сейчас вот пытаюсь вникнуть в jpeglib, немного ранее смотрел FreeImage.  Можете посоветовать какую-нибудь относительную простую библиотеку, для работы с .jpeg(а если и с другими форматами, то вообще шикарно) в Qt?


Название: Re: вопрос по QImage
Отправлено: Igors от Июль 19, 2011, 23:45
Сейчас вот пытаюсь вникнуть в jpeglib, немного ранее смотрел FreeImage.  Можете посоветовать какую-нибудь относительную простую библиотеку, для работы с .jpeg(а если и с другими форматами, то вообще шикарно) в Qt?
Я бы не спешил привлекать еще одну библиотеку только для того чтобы продемонстрировать ход загрузки изображения. Как минимум придется перебрасывать пиксели из формата той либы в QImage - уже недешево. Сначала неплохо бы изучить что с памятью процесса (физической и виртуальной) до и после загрузки имеджа. Статистика размера изображения,  байт на пиксель и примерного времени загрузки также не помешают.


Название: Re: вопрос по QImage
Отправлено: Fess от Июль 20, 2011, 06:07
В QtSolutions был плагин для поддержки JPEG 2000
Википедия заявляет, что стандарт поддерживает такую фичу, как "Random code-stream access and processing". Хотя не уверен, что Qt плагин это тоже умеет.
В любом случае посмотреть стоит..