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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: QGraphics размытие  (Прочитано 8977 раз)
ecspertiza
Супер
******
Offline Offline

Сообщений: 1053


С уважением, мастер конфетного цеха!


Просмотр профиля
« : Июль 30, 2012, 12:28 »

Есть задача сделать размытие выделенной области. Стало быть у меня есть QGraphicsView я для него задал background, стало быть помещаю на сцену QGraphicsItem для него задаю эффект setGraphicsEffect(new QGraphicsBlurEffect) , но размытие есть только на самом итеме, а хотелось бы что бы эффект был применен ко всему что есть под итемом размытия. Как это можно реализовать ? Есть конечно вариант, мол сграбливать изображение которое под итемом, но он может перемещать и изменять свои размеры, боюсь это может на скорости сильно сказаться, поэтому хотелось бы какой нибудь вариант покрасивее.
Записан
ecspertiza
Супер
******
Offline Offline

Сообщений: 1053


С уважением, мастер конфетного цеха!


Просмотр профиля
« Ответ #1 : Июль 31, 2012, 13:42 »

Так и думал что будут с этим сложности Улыбающийся Может есть вариант как можно просто размыть часть сцены ?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #2 : Июль 31, 2012, 16:30 »

Ну размывать сцену мне кажется "не очень хорошо", напр может быть др айтем который пострадает безвинно. Может быть просто увеличить айтем (или добавить ему спец бордюр) чтобы "компенсировать" эффект и добиться лучшего вида. Вообще скриншот показывающий проблему здесь был бы к месту. 
Записан
ecspertiza
Супер
******
Offline Offline

Сообщений: 1053


С уважением, мастер конфетного цеха!


Просмотр профиля
« Ответ #3 : Июль 31, 2012, 18:40 »

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

Вложил скрин, на нем видно что есть сцена с background, на ней итем у которого задан эффект размытия 

Код:
setGraphicsEffect(new QGraphicsBlurEffect);

получается так что размывается только итем. Есть идея, при рисовании итемов на сцене кешировать рисунок в фции paint. Затем при рисовании размытия, проверять на пересекающиеся итемы, получать от них координаты пересечения ,а так же из кеша выдирать рисунок, и рисовать его на итеме размытия. Но есть подозрение что это не путь джедая.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #4 : Июль 31, 2012, 19:06 »

получается так что размывается только итем. Есть идея, при рисовании итемов на сцене кешировать рисунок в фции paint. Затем при рисовании размытия, проверять на пересекающиеся итемы, получать от них координаты пересечения ,а так же из кеша выдирать рисунок, и рисовать его на итеме размытия. Но есть подозрение что это не путь джедая.
Выглядит сложновато/геморройно. Вы можете направить весь вывод сначала в QImage а потом уже на экран? Координаты где блюрить знаете? Если да то остальное (заблюрить в QImage) - ну на полчаса работы максимум   
Записан
ecspertiza
Супер
******
Offline Offline

Сообщений: 1053


С уважением, мастер конфетного цеха!


Просмотр профиля
« Ответ #5 : Июль 31, 2012, 20:04 »

Боюсь направить весь вывод в QImage не прокатит, так было в старой версии программы, и отказались от этого в пользу итемов и сцены, что бы можно было управлять итемами. Ну например ресайзить, перемещать, ворочать.

А координаты знаю, они равны координатам итема размытия.
Алгоритм размытия тож есть от старой версии проги остался.

Я просто почему то думал что есть простой путь, мол там свойство задали и эффект будет распространяться на все что под итемом.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Июль 31, 2012, 20:26 »

Боюсь направить весь вывод в QImage не прокатит, так было в старой версии программы, и отказались от этого в пользу итемов и сцены, что бы можно было управлять итемами. Ну например ресайзить, перемещать, ворочать.
Не верится что "не прокатит", ведь, грубо говоря, сцена - виджет, а значит рендерить ее в QImage можно, и управлению айтемами это никак не противоречит. А что делать если напр сцена - всего лишь один "слой" который комбинируется еще со многими? Должно быть

Я просто почему то думал что есть простой путь, мол там свойство задали и эффект будет распространяться на все что под итемом.
Да, Qt плюшки конечно очень вкусные и с огромным удовольствием поедаются. Но что будет с человеком если он жрет только плюшки? Так что "не совсем простой" путь полезнее  Улыбающийся
Записан
ecspertiza
Супер
******
Offline Offline

Сообщений: 1053


С уважением, мастер конфетного цеха!


Просмотр профиля
« Ответ #7 : Июль 31, 2012, 20:46 »

Не верится что "не прокатит", ведь, грубо говоря, сцена - виджет, а значит рендерить ее в QImage можно, и управлению айтемами это никак не противоречит. А что делать если напр сцена - всего лишь один "слой" который комбинируется еще со многими? Должно быть

Ну то есть как не прокатит, прокатит конечно. Но я тогда не совсем представляю архитектуру приложения. Вот допустим пользователю нужно нарисовать квадрат, затем он понял что нарисовал его не там и его нужно переместить. Как я вижу это при работе с QImage сначала мы создаем итем квадрат и пользователь его двигает или ресайзит, все хорошо, пользователь закончил рисование, и мы этот квадрат нарисовали в QImage который в свою очередь отрендерили на сцене. Все хорошо. Но пользователь понял что ему просто жизненно необходимо переместить квадрат, он на него кликает и должен тянуть его куда то дальше, как быть в этом случае не совсем понятно ведь QImage то уже отрисован. Возможно просто я не всю задачу обрисовал Улыбающийся должно получиться что то вроде examples/graphicsview/diagramscene только будут другие элементы, но то что все что создано на сцене можно будет таскать это точно.
Записан
lighting
Гость
« Ответ #8 : Август 01, 2012, 10:04 »

Как я вижу это при работе с QImage сначала мы создаем итем квадрат и пользователь его двигает или ресайзит, все хорошо, пользователь закончил рисование, и мы этот квадрат нарисовали в QImage который в свою очередь отрендерили на сцене. Все хорошо. Но пользователь понял что ему просто жизненно необходимо переместить квадрат, он на него кликает и должен тянуть его куда то дальше, как быть в этом случае не совсем понятно ведь QImage то уже отрисован.
Так вы не просто отрисовывайте в QImage квадрат а сохраните его в списке объектов (координаты, z, цвет) и каждый раз  отрисовывайте его заново если он изменился. Правда в таком случае это уже будет свой педальный GraphicsView и я не уверен что целесообразно будет такой велосипед строить, все от конкретной задачи зависит.
Записан
ecspertiza
Супер
******
Offline Offline

Сообщений: 1053


С уважением, мастер конфетного цеха!


Просмотр профиля
« Ответ #9 : Август 01, 2012, 10:33 »

по сути в таком случае нужно свой граф фреймворк писать Улыбающийся даже не знаю что проще выйдет, искать все пересечения, или эту тему с QImage. Мне же еще придется как то определять в зависимости от координат и z на какой объект кликнули и какой потянули. Кажется что тема с кешированием выглядит попроще Улыбающийся
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #10 : Август 01, 2012, 11:00 »

Ну то есть как не прокатит, прокатит конечно. Но я тогда не совсем представляю архитектуру приложения. Вот допустим пользователю нужно нарисовать квадрат, затем он понял что нарисовал его не там и его нужно переместить. Как я вижу это при работе с QImage сначала мы создаем итем квадрат и пользователь его двигает или ресайзит, все хорошо, пользователь закончил рисование, и мы этот квадрат нарисовали в QImage который в свою очередь отрендерили на сцене.
Я имел ввиду перехватить вывод всей сцены. Т.е. пусть двигает что и как хочет, все равно в конце концов paintEvent придет, вот там и блюрить.
Записан
ecspertiza
Супер
******
Offline Offline

Сообщений: 1053


С уважением, мастер конфетного цеха!


Просмотр профиля
« Ответ #11 : Август 01, 2012, 11:15 »

Всмысле в painEvent получаем координаты всех итемов размытия и там уже делаем само размытие В замешательстве
Нужно попробовать, звучит хорошо, спасибо Улыбающийся
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #12 : Август 01, 2012, 14:18 »

Попробуй это:

Код
C++ (Qt)
Q_GUI_EXPORT void qt_blurImage( QPainter* p, QImage& blurImage, qreal radius, bool quality, bool alphaOnly, int transposed = 0 );
 
class BlurRectItem : public QGraphicsRectItem
{
public:
BlurRectItem( const QRectF& rect )
: QGraphicsRectItem( rect )
, radius_( 5 )
, in_grab_( false )
{
setZValue( 10000 );
setFlag( ItemIsMovable );
setCursor( Qt::OpenHandCursor );
}
void paint( QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget = 0 )
{
if( in_grab_ )
return;
in_grab_ = true;
QImage img( rect().size().toSize(), QImage::Format_RGB32 );
QPainter p( &img );
p.eraseRect( rect() );
p.setRenderHint( QPainter::Antialiasing );
scene()->render( &p, QRectF(), sceneBoundingRect() );
p.end();
in_grab_ = false;
painter->save();
qt_blurImage( painter, img, radius_, true, false );
painter->restore();
painter->drawRect( rect() );
}
qreal blurRadius() const { return radius_; }
void setBlurRadius( qreal r ) { radius_ = r; }
 
private:
bool in_grab_;
qreal radius_;
};
 

Просто создаёшь на сцене BlurRectItem и не используешь QGraphicsBlurEffect.
« Последнее редактирование: Август 01, 2012, 14:26 от GreatSnake » Записан

Qt 5.11/4.8.7 (X11/Win)
ecspertiza
Супер
******
Offline Offline

Сообщений: 1053


С уважением, мастер конфетного цеха!


Просмотр профиля
« Ответ #13 : Август 01, 2012, 15:00 »

GreatSnake, спасибо , только нашел решение с render, зашел на форум отписать ,а тут твой ответ Улыбающийся

Вообщем как всегда все оказалось просто, можно получить часть сцены прямо в итеме используя при этом ф-цию render(), она от рисует в QPainter фрагмент который в нее будет передан
Записан
ecspertiza
Супер
******
Offline Offline

Сообщений: 1053


С уважением, мастер конфетного цеха!


Просмотр профиля
« Ответ #14 : Август 01, 2012, 15:10 »

А про

Код:
Q_GUI_EXPORT void qt_blurImage( QPainter* p, QImage& blurImage, qreal radius, bool quality, bool alphaOnly, int transposed = 0 );

я не знал, использовал свою похожую функцию, буду знать про такую фичу, спасибо Улыбающийся
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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