Russian Qt Forum

Qt => Общие вопросы => Тема начата: lit-uriy от Февраль 11, 2010, 15:21



Название: Сохраниение качества SVG-картинки
Отправлено: lit-uriy от Февраль 11, 2010, 15:21
Во многие виджеты можно воткнуть картинку, явно в документации не говориться о том, что можно использовать и SVG. Хотя есть какие-то размытые оговорки о модуле SVG.
В частности поместить картинку можно на кнопку или на метку.
Однако если я изменю размер носителя, например, метки. То SVG-картинка ведёт себя также, как если бы она была растровым рисунком.
Я не могу понять как влиять на SVG. Как сделать так, чтобы сначала задаться желаемым размером и затем бы она превратилась в растр? Иначе качество сильно страдает.
Таже проблема и при использовании QGraphicsPixmapItem
Код
C++ (Qt)
QGraphicsPixmapItem* pPixmapItem1 = new QGraphicsPixmapItem("./misc/onSwitch.svg");


Название: Re: Сохраниение качества SVG-картинки
Отправлено: Rcus от Февраль 11, 2010, 17:35
А у меня такая строка не компилится
Код:
main@krchome:/tmp/sample$ make
g++ -c -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4 -I. -I. -o main.o main.cpp
main.cpp: In function ‘int main(int, char**)’:
main.cpp:5: error: no matching function for call to ‘QGraphicsPixmapItem::QGraphicsPixmapItem(const char [13])’
/usr/include/qt4/QtGui/qgraphicsitem.h:924: note: candidates are: QGraphicsPixmapItem::QGraphicsPixmapItem(const QGraphicsPixmapItem&)
/usr/include/qt4/QtGui/qgraphicsitem.h:885: note:                 QGraphicsPixmapItem::QGraphicsPixmapItem(const QPixmap&, QGraphicsItem*, QGraphicsScene*)
/usr/include/qt4/QtGui/qgraphicsitem.h:879: note:                 QGraphicsPixmapItem::QGraphicsPixmapItem(QGraphicsItem*, QGraphicsScene*)
make: *** [main.o] Error 1
main@krchome:/tmp/sample$ g++ --version
g++ (Ubuntu 4.4.3-2ubuntu1) 4.4.3
Хотя если предположить что компилятор будет искать конструкторы преобразования то подозреваю что вызовется QString -> QPixmap -> QGraphicsPixmapItem.

Про установку SVG на виджеты не знаю, есть QSvgIconEngine для QIcon, но он должен работать так если не нашел QPixmap запрошенного размера в кеше то растеризует заново.


Название: Re: Сохраниение качества SVG-картинки
Отправлено: lit-uriy от Февраль 11, 2010, 18:57
>>А у меня такая строка не компилится
QT += svg
???


Название: Re: Сохраниение качества SVG-картинки
Отправлено: lit-uriy от Февраль 11, 2010, 19:00
Можешь попробовать в Дизайнере в метку запихнуть SVG-рисунок. А потом изменять размер метки (при включенном растяжении содержимого). Рисунок будет иметь только умалчиваемый для данного SVG размер, а дальше масштабируется уже растровый, со всеми вытекающими последствиями


Название: Re: Сохраниение качества SVG-картинки
Отправлено: BRE от Февраль 11, 2010, 19:11
Юра, посмотри на класс QSvgWidget и его реализацию.


Название: Re: Сохраниение качества SVG-картинки
Отправлено: Rcus от Февраль 11, 2010, 19:13
>>А у меня такая строка не компилится
QT += svg
???
И как это поможет? Полный текст main.cpp:
Код
C++ (Qt)
#include <QGraphicsPixmapItem>
 
int main(int, char**)
{
   QGraphicsPixmapItem *item = new QGraphicsPixmapItem("./sample.svg");
   Q_UNUSED(item);
}
 
Можешь попробовать в Дизайнере в метку запихнуть SVG-рисунок. А потом изменять размер метки (при включенном растяжении содержимого). Рисунок будет иметь только умалчиваемый для данного SVG размер, а дальше масштабируется уже растровый, со всеми вытекающими последствиями
И uic сгенерит примерно следующий код.
Код
C++ (Qt)
label->setPixmap(QPixmap(QString::fromUtf8("../../usr/share/icons/hicolor/scalable/actions/jockey-certified.svg")));
Упражнение по исполнению кода в уме выполняется достаточно легко и объясняет суть явления.


Название: Re: Сохраниение качества SVG-картинки
Отправлено: lit-uriy от Февраль 11, 2010, 20:04
прошу прощения, вместо сырой строки с именем файла, должно быть:
QPixmap("./misc/onSwitch.svg")

>>объясняет суть явления
Суть явления я и так понял, я не понял:
"Как сделать так, чтобы сначала задаться желаемым размером и затем бы она превратилась в растр?"


Название: Re: Сохраниение качества SVG-картинки
Отправлено: lit-uriy от Февраль 11, 2010, 20:08
BRE, реализацию именно этого класса я не смотрел, я смотрел QPixmap, но там у маня мозги закипели. Сильно навёрнуто.

Но и туда попробую залезть.

В идеале яб хотел примерно следующее:
Код
C++ (Qt)
QSvgImage svg("./misc/onSwitch.svg");
svg.resize(100, 100, Qt::KeepAspectRatio);
label->setPixmap(svg.pixmap());
QGraphicsPixmapItem *item = new QGraphicsPixmapItem(svg.pixmap());


Название: Re: Сохраниение качества SVG-картинки
Отправлено: Rcus от Февраль 11, 2010, 20:17
А чем вам не нравится QIcon("somefile.svg").pixmap(w,h) ?


Название: Re: Сохраниение качества SVG-картинки
Отправлено: SABROG от Февраль 11, 2010, 20:21
Что если попробовать QGraphicsSvgItem? А для QGraphicsPixmapItem попробовать вызвать:

Код
C++ (Qt)
item->setCacheMode(QGraphicsItem::NoCache);
 

Как вариант, переопределить QGraphicsItem::paint() и вызывать QSvgRenderer()


Название: Re: Сохраниение качества SVG-картинки
Отправлено: lit-uriy от Февраль 11, 2010, 20:40
>>А чем вам не нравится QIcon("somefile.svg").pixmap(w,h) ?
Надо попробовать, будет ли при этом качество хорошее. НО есть минус, мне нужно будет всякий раз проверять текущий размер объекта в который помещена SVG'шка.

>>Что если попробовать QGraphicsSvgItem?
Тоже вариант, изначально я грузил разного формата картинки и стремился использовать один и тот же класс. И предполагал, что QPixmap сам в состоянии разруливать мастабирование SVG'шек


Название: Re: Сохраниение качества SVG-картинки
Отправлено: SABROG от Февраль 11, 2010, 20:55
Судя по всему качество SVG картинки зависит от размера QPixmap'a, а этот размер не меняется при изменении размера QGraphicsItem. Можно попробовать изначально поставить размер QPixmap'a не 100x100, а больше в несколько раз чем QGraphicsItem. И не давать пользователям менять размер итема на сцене больше чем этот.


Название: Re: Сохраниение качества SVG-картинки
Отправлено: lit-uriy от Февраль 11, 2010, 21:03
попробовал для QGraphicsSvgItem, Да качество такое какого хотелось.
НО выделение (прямоугольной области) и перемещение элементов, стало сильно тормозить.
По экспериментировал с режимом кэширования:
NoCache - качество картинки хорошее, тормозит
DeviceCoordinateCache - качество картинки хорошее, тормозит
ItemCoordinateCache - качество, как и при масштабировании растра, летает

Собственно и в  Асистенте о последнем режиме написано, что качество падает.


Название: Re: Сохраниение качества SVG-картинки
Отправлено: BRE от Февраль 11, 2010, 21:13
Отслеживай изменение размера картинки и перерендеривай (или перерендерь :) ) ее на QPixmap. Думаю будет и скорость, и качество.


Название: Re: Сохраниение качества SVG-картинки
Отправлено: SABROG от Февраль 11, 2010, 21:25
Отслеживай изменение размера картинки и перерендеривай (или перерендерь :) ) ее на QPixmap. Думаю будет и скорость, и качество.

Я думал об этом, но мне кажется рендерер будет подтормаживать. Хотя попробовать стоит.

Что если пойти другим путем. Если задействовать QPixmapCache, но сначала определить сколько картинок и какого размера он будет содержать. Нужно найти в каких диапозонах изменения размера итема растровая картинка не будет сильно резать глаза при трансформации, при достижении этой границы уже генерировать следующий кэш. Предположим меняем размеры итема с 0x0 до 50x50 - одна картинка, 51x51 до 100x100 - вторая, 101x101 - 200x200 - третья. И при запросе нового размера итема выбираем нужный пиксмап из кэша.


Название: Re: Сохраниение качества SVG-картинки
Отправлено: lit-uriy от Февраль 11, 2010, 21:38
Пока у меня задача относительно простая и на тормоза могу забить:
В приложении пользователь не имеет возможность изменять содержимое сцены. Но пользователь может изменять размер окна, я для этих целей предусмотрел кнопку "подогнать в размер окна". Правда эта функция как-то криво работает, но это отдельная тема.

А вот в будущем мне нужно будет дать возможность пользователю рисовать самостоятельно, эдакое подобие редактора схем.