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. How to draw a border around a pixmap derived from png
Forum Updated to NodeBB v4.3 + New Features

How to draw a border around a pixmap derived from png

Scheduled Pinned Locked Moved Solved General and Desktop
15 Posts 5 Posters 4.0k Views 3 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.
  • H Offline
    H Offline
    Hristo Konstantinov
    wrote on last edited by Hristo Konstantinov
    #1

    Hello everyone. I have a QGraphicsItem. It receives an already processed pixmap with irregular shape and draws it. The pixmap is constructed from a png and the colour of the pixmap is changed via composition source in by the painter of the class, which processes the pixmap. Is there anyway for this class to also draw an outline(a border) around the edges of the pixmap?
    I'm aware that QGraphicsPixmapItem has some kind of mask, but I am not sure constructinig it with the pixmap as an argument and then doing some unknown magic will work. Ideally I want to get a QPainterPath which represents the outlines of the shape of the pixmap and then tell the painter to draw it with a pen in any color or size. What is the correct way to do this? Which classes and methods should I use?

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

      Wouldn't using QPainter to draw on your pixmap be enough ?

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      H 1 Reply Last reply
      0
      • SGaistS SGaist

        Hi,

        Wouldn't using QPainter to draw on your pixmap be enough ?

        H Offline
        H Offline
        Hristo Konstantinov
        wrote on last edited by Hristo Konstantinov
        #3

        Of course, but how to tell QPainter to outline the pixmap around its borders?

        1 Reply Last reply
        0
        • H Offline
          H Offline
          Hristo Konstantinov
          wrote on last edited by
          #4

          This is my progress so far:

          QPixmap CustomQGraphicsScene::getPixmap(bool outline)
          {
          	QPixmap px("test.png");
          
          	QPainter painter(&px);
          	painter.setRenderHint(QPainter::Antialiasing, true);
          	painter.setBrush(Qt::green);
          	painter.setCompositionMode(QPainter::CompositionMode_SourceIn);
          	painter.fillRect(0, 0, px.width(), px.height(), Qt::green);
          
          	if (!outline) return px;
          
          	//constructing temp object only to get QPainterPath
          	QGraphicsPixmapItem temp_pixmap_item(px); 
          	temp_pixmap_item.setShapeMode(QGraphicsPixmapItem::MaskShape);
          	auto path = temp_pixmap_item.shape();
          
          	QPen pen(Qt::red, 50, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
          	painter.setPen(pen);
          	painter.drawPath(path);
          
          	return px;
          }
          

          I kinda get the result I wanted, but I have to create a QGraphicsPixmapItem, only to calculate the QPainterPath by calling the shape() function. Is there a different and faster way to get the shape without constructing a whole QGraphicsItem object?

          1 Reply Last reply
          0
          • SGaistS Offline
            SGaistS Offline
            SGaist
            Lifetime Qt Champion
            wrote on last edited by
            #5

            Why not have custom QGraphicsPixmapItem that does the border drawing ?

            Interested in AI ? www.idiap.ch
            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

            1 Reply Last reply
            0
            • H Offline
              H Offline
              Hristo Konstantinov
              wrote on last edited by Hristo Konstantinov
              #6

              Unfortunately It's a little more complicated than that :/ I have a custom qgraphicsitem, which recieves an already processed pixmap which is made of a png spritesheet. Depending on the user actions, the different textures are cut, formatted with certain color and outline and then positioned in certain places of the pixmap. Since it's a very complicated process, it is done outside of the scene, and when assembled the pixmap is sent to the QGraphicsItem in the scene and displayed by it in its paint function. Here are some screenshots to get what I mean:

              the sprite sheet of the current tooth:
              18.png

              how does it look painted with the current tooth status:
              tq.png

              kshegunovK 1 Reply Last reply
              0
              • H Hristo Konstantinov

                Unfortunately It's a little more complicated than that :/ I have a custom qgraphicsitem, which recieves an already processed pixmap which is made of a png spritesheet. Depending on the user actions, the different textures are cut, formatted with certain color and outline and then positioned in certain places of the pixmap. Since it's a very complicated process, it is done outside of the scene, and when assembled the pixmap is sent to the QGraphicsItem in the scene and displayed by it in its paint function. Here are some screenshots to get what I mean:

                the sprite sheet of the current tooth:
                18.png

                how does it look painted with the current tooth status:
                tq.png

                kshegunovK Offline
                kshegunovK Offline
                kshegunov
                Moderators
                wrote on last edited by
                #7

                Is there alpha in that pixmap? What I'd do is to underpaint a dilated version of the image, basically I'd run a filter on it once and save the result. Then underpaint the "shadow"/"outline" in the graphics item. Ideally this could be put in the actual sprite, though, couldn't it?

                Read and abide by the Qt Code of Conduct

                H 1 Reply Last reply
                0
                • kshegunovK kshegunov

                  Is there alpha in that pixmap? What I'd do is to underpaint a dilated version of the image, basically I'd run a filter on it once and save the result. Then underpaint the "shadow"/"outline" in the graphics item. Ideally this could be put in the actual sprite, though, couldn't it?

                  H Offline
                  H Offline
                  Hristo Konstantinov
                  wrote on last edited by
                  #8

                  Yes, at the beginning the border was hardpainted in the sprite. But then a problem arised - in some cases the outline should be red, but the inside color should be changed from blue to green so I scrapped that idea. The pixmap has a transparent fill, so probably it has alpha. Can you give me some simple code example of what filter are you talking about?

                  kshegunovK 1 Reply Last reply
                  0
                  • H Hristo Konstantinov

                    Yes, at the beginning the border was hardpainted in the sprite. But then a problem arised - in some cases the outline should be red, but the inside color should be changed from blue to green so I scrapped that idea. The pixmap has a transparent fill, so probably it has alpha. Can you give me some simple code example of what filter are you talking about?

                    kshegunovK Offline
                    kshegunovK Offline
                    kshegunov
                    Moderators
                    wrote on last edited by kshegunov
                    #9

                    @Hristo-Konstantinov said in How to draw a border around a pixmap derived from png:

                    Yes, at the beginning the border was hardpainted in the sprite. But then a problem arised - in some cases the outline should be red, but the inside color should be changed from blue to green so I scrapped that idea.

                    What inside color? I think I'm missing something.

                    The pixmap has a transparent fill, so probably it has alpha.

                    Yes, the transparency is "alpha" (i.e. the alpha channel).

                    Can you give me some simple code example of what filter are you talking about?

                    Not off hand, but I can point you to some resources I think.

                    This is "dilate": https://en.wikipedia.org/wiki/Dilation_(morphology)
                    and "erode": https://en.wikipedia.org/wiki/Erosion_(morphology)

                    Ignore the math, the basic idea is similar to the median filter (the three are the same class of non-linear filters). Basically it goes like this:

                    • Take a window of say 3 by 3 pixels that you move over the image, the center pixel of the window is the pixel position in which you're going to write the filtered value in the resulting image.
                    • So the 9 pixels you have in the window you process in some fashion, for the median filter - take the median, for the dilate filter take the supremum (i.e. the maximum), for the erode - the infimum (i.e. the minimum). Now by value here I mean the alpha channel specifically. While you go you set the RGB to black/red/green w/e and you process the transparency - basically making the (visible) figure larger.
                    • Write the RGBA to the corresponding pixel in the resulting image.

                    Here's a toy project I'd made to illustrate color reduction in images. It's not what you want directly, but you can source some ideas on how to process images in Qt.

                    (And by images I mean QImage, because QPixmap is truly abysmal for pixel-by-pixel operations).

                    Read and abide by the Qt Code of Conduct

                    1 Reply Last reply
                    3
                    • H Offline
                      H Offline
                      Hristo Konstantinov
                      wrote on last edited by Hristo Konstantinov
                      #10

                      Thanks for the detailed answer! Definitely will check those out tomorrow.
                      I meant outline, not border. At first I drew the teeth surfaces in photoshop with red outline and blue inner part, and if I needed an outline, I just painted the sprite untouched. But then it became necessary in some cases for the inner part to be green (blue is filling, green is filling made by the user, red outline means filling with caries underneath), so I had to find a way to do all the painting runtime, while using only the alpha of the png. Anyway, the code I pasted above works for now. Again - many thanks for the guidance!

                      kshegunovK 1 Reply Last reply
                      0
                      • H Hristo Konstantinov

                        Thanks for the detailed answer! Definitely will check those out tomorrow.
                        I meant outline, not border. At first I drew the teeth surfaces in photoshop with red outline and blue inner part, and if I needed an outline, I just painted the sprite untouched. But then it became necessary in some cases for the inner part to be green (blue is filling, green is filling made by the user, red outline means filling with caries underneath), so I had to find a way to do all the painting runtime, while using only the alpha of the png. Anyway, the code I pasted above works for now. Again - many thanks for the guidance!

                        kshegunovK Offline
                        kshegunovK Offline
                        kshegunov
                        Moderators
                        wrote on last edited by kshegunov
                        #11

                        I was bored while I was chugging my coffee, so I made this micro-demonstration:

                        https://bitbucket.org/kshegunov/dilate/src/master/

                        I think this is what you wanted to achieve. Enjoy!

                        Read and abide by the Qt Code of Conduct

                        mrjjM A 2 Replies Last reply
                        3
                        • kshegunovK kshegunov

                          I was bored while I was chugging my coffee, so I made this micro-demonstration:

                          https://bitbucket.org/kshegunov/dilate/src/master/

                          I think this is what you wanted to achieve. Enjoy!

                          mrjjM Offline
                          mrjjM Offline
                          mrjj
                          Lifetime Qt Champion
                          wrote on last edited by
                          #12

                          @kshegunov

                          alt text

                          That's a pretty outline ! Good coffee :)

                          kshegunovK 1 Reply Last reply
                          0
                          • mrjjM mrjj

                            @kshegunov

                            alt text

                            That's a pretty outline ! Good coffee :)

                            kshegunovK Offline
                            kshegunovK Offline
                            kshegunov
                            Moderators
                            wrote on last edited by
                            #13

                            @mrjj said in How to draw a border around a pixmap derived from png:

                            Good coffee :)

                            You know the meme ;)

                            Read and abide by the Qt Code of Conduct

                            1 Reply Last reply
                            1
                            • kshegunovK kshegunov

                              I was bored while I was chugging my coffee, so I made this micro-demonstration:

                              https://bitbucket.org/kshegunov/dilate/src/master/

                              I think this is what you wanted to achieve. Enjoy!

                              A Offline
                              A Offline
                              Albertino
                              wrote on last edited by
                              #14

                              @kshegunov great work!

                              Only a small change needed in maxAlpha function:

                              maxI = std::min(x + window + 1, image.width())
                              maxJ = std::min(y + window + 1, image.height())
                              

                              Otherwise (without the +1) there is a missing left pixel

                              kshegunovK 1 Reply Last reply
                              2
                              • A Albertino

                                @kshegunov great work!

                                Only a small change needed in maxAlpha function:

                                maxI = std::min(x + window + 1, image.width())
                                maxJ = std::min(y + window + 1, image.height())
                                

                                Otherwise (without the +1) there is a missing left pixel

                                kshegunovK Offline
                                kshegunovK Offline
                                kshegunov
                                Moderators
                                wrote on last edited by
                                #15

                                Yes indeed. I completely missed that rightmost image pixel.
                                Do you mind opening a pull request so I can merge this in the repo?

                                Read and abide by the Qt Code of Conduct

                                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