Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Render QGraphicsEffect into pixmap?

Render QGraphicsEffect into pixmap?

Scheduled Pinned Locked Moved General and Desktop
10 Posts 4 Posters 10.5k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • B Offline
    B Offline
    bendtbendtsen
    wrote on last edited by
    #1

    Hello World!

    I have a scene with a lot of items, all can have a custom QGraphicsEffects added.
    Once an effect is rendered I would like to save the result, and add the resulting
    qPixmap to a qPixmapCache.

    I was hoping to use the paint() function in my custom effect class, and in this do something ala
    @
    QPixmap im(loading the actual image);
    QPainter p(&im);
    QGraphicsDropShadowEffect::draw(&p);
    im.save("ImageShadow.png","png");
    @
    BUT (and I tried a lot o variants).. yeah you know .. no.

    I know that scene->render() may give me a copy of the result, but the item and its effects may very well be occluded/overlapped/.. so the optimal solution would be to 'grap' it once when (OR while) rendered.

    Anyone who saved effects? OR rendered effects into Qimage/pixmap/..?

    A lovely one to you!
    /bb

    1 Reply Last reply
    0
    • ? This user is from outside of this forum
      ? This user is from outside of this forum
      Guest
      wrote on last edited by
      #2

      I've done it in the past by grabbing the widget

      QPixmap QPixmap::grabWidget ( QWidget * widget, const QRect & rectangle )

      I think you could specify the QRect to fit your entire scene. Have you given this a shot?

      1 Reply Last reply
      0
      • B Offline
        B Offline
        bendtbendtsen
        wrote on last edited by
        #3

        .. thanxx for the reply .. But as I understand this, it is basically the same as scene->render(..)? Using 'grabWidget' in a view/scene setup I have to do:

        pm = QPixmap::grabWidget(&view, x,y,w,h);

        But this is identical (or the result is) to scene.render(..), and my scene is stuffed with items, so this gives me the same 'overlapping' problems ..

        I could add a QLabel to my scene, and then use this as the widget for the 'grabWidget'. But how do I add my graphicsEffect to the widgets pixmap, and not the widget itself? .. hmm and I would really like to, not, include a QLabel in the scene ..

        1 Reply Last reply
        0
        • N Offline
          N Offline
          nightroad
          wrote on last edited by
          #4

          Hello i'm using QGraphicsEffect as a ThumbnailCollector here is my draw event,

          @
          void ThumbnailCollector::draw(QPainter *painter)
          {
          QPixmap pixmap = sourcePixmap(Qt::DeviceCoordinates);
          //pixmap will give to you your item its own pixmap data
          ...
          ...
          ...
          Q_EMIT thumbnailChanged(m_thumbnail);
          setEnabled(false);
          }
          @

          Hope this will help, but i have some flicking problems with that trying to solve that :s

          1 Reply Last reply
          0
          • P Offline
            P Offline
            PeterSvP
            wrote on last edited by
            #5

            QWidget::grab() is again regression for graphics effect, but graphics scene's render() call works like a charm without the need to create any widgets. Here is how:

            @ QImage applyEffectToImage(QImage src, QGraphicsEffect effect, int extent)
            {
            if(src.isNull()) return QImage(); //No need to do anything else!
            if(!effect) return src; //No need to do anything else!
            QGraphicsScene scene;
            QGraphicsPixmapItem item;
            item.setPixmap(QPixmap::fromImage(src));
            item.setGraphicsEffect(effect);
            scene.addItem(&item);
            QImage res(src.size()+QSize(extent
            2, extent2), QImage::Format_ARGB32);
            res.fill(Qt::transparent);
            QPainter ptr(&res);
            scene.render(&ptr, QRectF(), QRectF( -extent, -extent, src.width()+extent
            2, src.height()+extent*2 ) );
            return res;
            }@

            Them, using this function to is straightforward. Blur:

            @ QGraphicsBlurEffect *blur = new QGraphicsBlurEffect;
            blur->setBlurRadius(8);
            QImage source("://img1.png");
            QImage result = applyEffectToImage(source, blur);
            result.save("final.png");@

            Drop shadow:

            @ QGraphicsDropShadowEffect *e = new QGraphicsDropShadowEffect;
            e->setColor(QColor(40,40,40,245));
            e->setOffset(0,10);
            e->setBlurRadius(50);
            QImage p("://img3.png");
            QImage res = applyEffectToImage(p, e, 40);@

            And note the extent parameter, it adds extent number of pixels to all sides of the original image, especially useful for shadows and blurs to not be cut-off.

            1 Reply Last reply
            0
            • P Offline
              P Offline
              PeterSvP
              wrote on last edited by
              #6

              QWidget::grab() is again regression for graphics effect, but graphics scene's render() call works like a charm without the need to create any widgets. Here is how:

              @ QImage applyEffectToImage(QImage src, QGraphicsEffect effect, int extent)
              {
              if(src.isNull()) return QImage(); //No need to do anything else!
              if(!effect) return src; //No need to do anything else!
              QGraphicsScene scene;
              QGraphicsPixmapItem item;
              item.setPixmap(QPixmap::fromImage(src));
              item.setGraphicsEffect(effect);
              scene.addItem(&item);
              QImage res(src.size()+QSize(extent
              2, extent2), QImage::Format_ARGB32);
              res.fill(Qt::transparent);
              QPainter ptr(&res);
              scene.render(&ptr, QRectF(), QRectF( -extent, -extent, src.width()+extent
              2, src.height()+extent*2 ) );
              return res;
              }@

              Them, using this function to is straightforward. Blur:

              @ QGraphicsBlurEffect *blur = new QGraphicsBlurEffect;
              blur->setBlurRadius(8);
              QImage source("://img1.png");
              QImage result = applyEffectToImage(source, blur);
              result.save("final.png");@

              Drop shadow:

              @ QGraphicsDropShadowEffect *e = new QGraphicsDropShadowEffect;
              e->setColor(QColor(40,40,40,245));
              e->setOffset(0,10);
              e->setBlurRadius(50);
              QImage p("://img3.png");
              QImage res = applyEffectToImage(p, e, 40);@

              And note the extent parameter, it adds extent number of pixels to all sides of the original image, especially useful for shadows and blurs to not be cut-off.

              1 Reply Last reply
              0
              • M Offline
                M Offline
                midoos
                wrote on last edited by
                #7

                You should render it, to do that you should override the paint function
                try this class:
                DropShadow.h

                @
                #ifndef DROPSHADOW_H
                #define DROPSHADOW_H
                #include <QtGui>
                #include <QtCore>
                #include <QGraphicsView>
                #include <QGraphicsScene>
                #include <QGraphicsEffect>
                #include <QtQuick/QQuickPaintedItem>
                #include <QLabel>
                #include <QPainter>
                #include <QGraphicsProxyWidget>
                /*!

                • \brief The DropShadow class, it load an Image and apply to it a DropShadow effect
                  */
                  class DropShadow : public QQuickPaintedItem
                  {
                  Q_OBJECT
                  Q_PROPERTY(QString source READ getImageSource WRITE setImageSource)
                  Q_PROPERTY(QColor color READ getColor WRITE setColor)
                  Q_PROPERTY(int width READ getWidth WRITE setCustomWidth)
                  Q_PROPERTY(int height READ getHeight WRITE setCustomHeight)
                  Q_PROPERTY(double radius READ getBlurRadius WRITE setBlurRadius)
                  Q_PROPERTY(double horizontalOffset READ getXOffset WRITE setXOffset)
                  Q_PROPERTY(double verticalOffset READ getYOffset WRITE setYOffset)
                  public:
                  DropShadow(QQuickItem *parent = 0);
                  int getWidth();
                  int getHeight();
                  void setCustomWidth(int width);
                  void setCustomHeight(int height);
                  void setImageSource(QString myImage);
                  QString getImageSource() const;
                  QColor getColor() const;
                  void setColor(const QColor &color);
                  double getBlurRadius() const;
                  void setBlurRadius(const double blurRadius);
                  double getXOffset() const;
                  double getYOffset() const;
                  void setXOffset(double value);
                  void setYOffset(double value);
                  void paint(QPainter *painter);
                  ~DropShadow();
                  signals:
                  void sgnSourceImageChanged();

                public slots:
                void sltOnsourceChanged();
                private:
                QImage myImage;
                QString sourceImage;
                QColor m_color;
                double radius;
                QGraphicsDropShadowEffect
                pShadow;
                QGraphicsOpacityEffect* pOpacity;
                QGraphicsView view;
                QGraphicsScene *scene;
                int width;
                int height;
                QPixmap pixmap;
                QPainter * m_painter;
                double horizontalOffset;
                double verticalOffset;
                };
                #endif // DROPSHADOW_H
                @

                dropShadow.cpp

                @
                #include "dropshadow.h"
                DropShadow::DropShadow(QQuickItem *parent) :
                QQuickPaintedItem(parent)
                {

                connect(this,SIGNAL(sgnSourceImageChanged()),this,SLOT(sltOnsourceChanged()));
                myImage = new QImage;
                pShadow = new QGraphicsDropShadowEffect;
                m_color = Qt::blue;
                width = 0;
                height = 0;
                radius = 1.0;
                horizontalOffset = 8.0;
                verticalOffset = 8.0;
                scene = new QGraphicsScene;
                view.setScene(scene);
                

                }
                int DropShadow::getWidth()
                {
                return width;
                }
                int DropShadow::getHeight()
                {
                return height;
                }
                void DropShadow::setCustomWidth(int value)
                {
                width = value;
                qDebug()<<"DropShadow::setCustomWidth("<<value<<")";
                }
                void DropShadow::setCustomHeight(int value)
                {
                height = value;
                qDebug()<<"DropShadow::setCustomHeight("<<value<<")";
                }
                QColor DropShadow::getColor() const
                {
                return m_color;
                }
                void DropShadow::setColor(const QColor &color)
                {
                m_color = color;
                }
                double DropShadow::getBlurRadius() const
                {
                return radius;
                }
                double DropShadow::getXOffset() const
                {
                return horizontalOffset;
                }
                double DropShadow::getYOffset() const
                {
                return verticalOffset;
                }
                void DropShadow::setXOffset(double value)
                {
                horizontalOffset = value;
                }
                void DropShadow::setYOffset(double value)
                {
                verticalOffset = value;
                }
                void DropShadow::setBlurRadius(const double blurRadius)
                {
                radius = blurRadius;
                }
                void DropShadow::setImageSource(QString image)
                {
                sourceImage = image;
                sgnSourceImageChanged();
                }
                QString DropShadow::getImageSource() const
                {
                return sourceImage;
                }
                void DropShadow::sltOnsourceChanged()
                {
                myImage->load(sourceImage);
                if(width == 0)
                {
                width = myImage->width();
                }
                if(height == 0)
                {
                height = myImage->height();
                }
                this->setWidth(width);
                this->setHeight(height);
                pixmap = QPixmap::fromImage( myImage->scaled(width,height,Qt::IgnoreAspectRatio,Qt::SmoothTransformation));
                }
                void DropShadow::paint(QPainter *painter)
                {
                view.setScene(scene);
                scene->setSceneRect(QRect(0,0,800,480));
                pShadow->setColor(QColor(m_color));
                pShadow->setBlurRadius(radius);
                pShadow->setXOffset(horizontalOffset);
                pShadow->setYOffset(verticalOffset);
                QGraphicsPixmapItem *p = view.scene()->addPixmap(pixmap);
                p->setGraphicsEffect(pShadow);
                view.render(painter,QRect(0,0,800,480),QRect(0,0,800,480));
                }
                DropShadow::~DropShadow()
                {
                delete myImage;
                delete pShadow;
                delete scene;
                }
                @

                [edit: added missing coding tags @ SGaist]

                1 Reply Last reply
                0
                • M Offline
                  M Offline
                  midoos
                  wrote on last edited by
                  #8

                  You should render it, to do that you should override the paint function
                  try this class:
                  DropShadow.h

                  @
                  #ifndef DROPSHADOW_H
                  #define DROPSHADOW_H
                  #include <QtGui>
                  #include <QtCore>
                  #include <QGraphicsView>
                  #include <QGraphicsScene>
                  #include <QGraphicsEffect>
                  #include <QtQuick/QQuickPaintedItem>
                  #include <QLabel>
                  #include <QPainter>
                  #include <QGraphicsProxyWidget>
                  /*!

                  • \brief The DropShadow class, it load an Image and apply to it a DropShadow effect
                    */
                    class DropShadow : public QQuickPaintedItem
                    {
                    Q_OBJECT
                    Q_PROPERTY(QString source READ getImageSource WRITE setImageSource)
                    Q_PROPERTY(QColor color READ getColor WRITE setColor)
                    Q_PROPERTY(int width READ getWidth WRITE setCustomWidth)
                    Q_PROPERTY(int height READ getHeight WRITE setCustomHeight)
                    Q_PROPERTY(double radius READ getBlurRadius WRITE setBlurRadius)
                    Q_PROPERTY(double horizontalOffset READ getXOffset WRITE setXOffset)
                    Q_PROPERTY(double verticalOffset READ getYOffset WRITE setYOffset)
                    public:
                    DropShadow(QQuickItem *parent = 0);
                    int getWidth();
                    int getHeight();
                    void setCustomWidth(int width);
                    void setCustomHeight(int height);
                    void setImageSource(QString myImage);
                    QString getImageSource() const;
                    QColor getColor() const;
                    void setColor(const QColor &color);
                    double getBlurRadius() const;
                    void setBlurRadius(const double blurRadius);
                    double getXOffset() const;
                    double getYOffset() const;
                    void setXOffset(double value);
                    void setYOffset(double value);
                    void paint(QPainter *painter);
                    ~DropShadow();
                    signals:
                    void sgnSourceImageChanged();

                  public slots:
                  void sltOnsourceChanged();
                  private:
                  QImage myImage;
                  QString sourceImage;
                  QColor m_color;
                  double radius;
                  QGraphicsDropShadowEffect
                  pShadow;
                  QGraphicsOpacityEffect* pOpacity;
                  QGraphicsView view;
                  QGraphicsScene *scene;
                  int width;
                  int height;
                  QPixmap pixmap;
                  QPainter * m_painter;
                  double horizontalOffset;
                  double verticalOffset;
                  };
                  #endif // DROPSHADOW_H
                  @

                  dropShadow.cpp

                  @
                  #include "dropshadow.h"
                  DropShadow::DropShadow(QQuickItem *parent) :
                  QQuickPaintedItem(parent)
                  {

                  connect(this,SIGNAL(sgnSourceImageChanged()),this,SLOT(sltOnsourceChanged()));
                  myImage = new QImage;
                  pShadow = new QGraphicsDropShadowEffect;
                  m_color = Qt::blue;
                  width = 0;
                  height = 0;
                  radius = 1.0;
                  horizontalOffset = 8.0;
                  verticalOffset = 8.0;
                  scene = new QGraphicsScene;
                  view.setScene(scene);
                  

                  }
                  int DropShadow::getWidth()
                  {
                  return width;
                  }
                  int DropShadow::getHeight()
                  {
                  return height;
                  }
                  void DropShadow::setCustomWidth(int value)
                  {
                  width = value;
                  qDebug()<<"DropShadow::setCustomWidth("<<value<<")";
                  }
                  void DropShadow::setCustomHeight(int value)
                  {
                  height = value;
                  qDebug()<<"DropShadow::setCustomHeight("<<value<<")";
                  }
                  QColor DropShadow::getColor() const
                  {
                  return m_color;
                  }
                  void DropShadow::setColor(const QColor &color)
                  {
                  m_color = color;
                  }
                  double DropShadow::getBlurRadius() const
                  {
                  return radius;
                  }
                  double DropShadow::getXOffset() const
                  {
                  return horizontalOffset;
                  }
                  double DropShadow::getYOffset() const
                  {
                  return verticalOffset;
                  }
                  void DropShadow::setXOffset(double value)
                  {
                  horizontalOffset = value;
                  }
                  void DropShadow::setYOffset(double value)
                  {
                  verticalOffset = value;
                  }
                  void DropShadow::setBlurRadius(const double blurRadius)
                  {
                  radius = blurRadius;
                  }
                  void DropShadow::setImageSource(QString image)
                  {
                  sourceImage = image;
                  sgnSourceImageChanged();
                  }
                  QString DropShadow::getImageSource() const
                  {
                  return sourceImage;
                  }
                  void DropShadow::sltOnsourceChanged()
                  {
                  myImage->load(sourceImage);
                  if(width == 0)
                  {
                  width = myImage->width();
                  }
                  if(height == 0)
                  {
                  height = myImage->height();
                  }
                  this->setWidth(width);
                  this->setHeight(height);
                  pixmap = QPixmap::fromImage( myImage->scaled(width,height,Qt::IgnoreAspectRatio,Qt::SmoothTransformation));
                  }
                  void DropShadow::paint(QPainter *painter)
                  {
                  view.setScene(scene);
                  scene->setSceneRect(QRect(0,0,800,480));
                  pShadow->setColor(QColor(m_color));
                  pShadow->setBlurRadius(radius);
                  pShadow->setXOffset(horizontalOffset);
                  pShadow->setYOffset(verticalOffset);
                  QGraphicsPixmapItem *p = view.scene()->addPixmap(pixmap);
                  p->setGraphicsEffect(pShadow);
                  view.render(painter,QRect(0,0,800,480),QRect(0,0,800,480));
                  }
                  DropShadow::~DropShadow()
                  {
                  delete myImage;
                  delete pShadow;
                  delete scene;
                  }
                  @

                  [edit: added missing coding tags @ SGaist]

                  1 Reply Last reply
                  0
                  • M Offline
                    M Offline
                    midoos
                    wrote on last edited by
                    #9

                    this is a link to my project , hope it could help you :
                    https://github.com/alhajjar/QmlEffects

                    1 Reply Last reply
                    0
                    • M Offline
                      M Offline
                      midoos
                      wrote on last edited by
                      #10

                      this is a link to my project , hope it could help you :
                      https://github.com/alhajjar/QmlEffects

                      1 Reply Last reply
                      0

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved