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?
Forum Updated to NodeBB v4.3 + New Features

Render QGraphicsEffect into pixmap?

Scheduled Pinned Locked Moved General and Desktop
10 Posts 4 Posters 10.2k 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