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. QImage \ QPixmal loses alpha color when drawing
QtWS25 Last Chance

QImage \ QPixmal loses alpha color when drawing

Scheduled Pinned Locked Moved General and Desktop
8 Posts 4 Posters 4.5k Views
  • 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.
  • P Offline
    P Offline
    Pisyandry
    wrote on last edited by Pisyandry
    #1

    Qt 5.7, Clang, OSX

    I have png image with QImage::Format_ARGB32 filled with color ARGB(0, 255, 255, 255).

    When I draw the image to another image with same format, color of alpha pixels loses. All ARGB(0, 255, 255, 255) pixels converts to ARGB(0, 0, 0, 0).

    Following code loses color of alpha-pixels:

    QImage sourceImage("image.png");
    QImage destImage(sourceImage.width(), sourceImage.height(), sourceImage.format());
    QPainter painter(&destImage);
    
    painter.setCompositionMode(QPainter::CompositionMode_Source);
    painter.drawImage(0, 0, sourceImage);
    painter.end();
    

    Scaling image loses color of alpha-pixels too:

    QImage destImage = sourceImage:scaled(sourceImage.width() / 2, sourceImage.height() / 2);
    

    But following code save pixels color:

    QImage sourceImage("image.png");
    QImage destImage(sourceImage.width(), sourceImage.height(), sourceImage.format());
    for(int x = 0; x < sourceImage.width(); x++)
    {
    	for(int y = 0; y < sourceImage.height(); y++)
    	{
    		destImage.setPixelColor(x, y, sourceImage.pixelColor(x, y));
    	}
    }
    

    So, it's synthetic example. In real task I have image with white text rendering in OpenGL application. In that case I get black pixels artifacts around my white text because GL can mix color of pixel with neighbor pixels.

    Summary:
    I need two things: smooth scale image and draw it to another image without losing rgb color of transparent pixels.

    1 Reply Last reply
    0
    • Hamed.MasafiH Offline
      Hamed.MasafiH Offline
      Hamed.Masafi
      wrote on last edited by
      #2
      This post is deleted!
      1 Reply Last reply
      0
      • kshegunovK Offline
        kshegunovK Offline
        kshegunov
        Moderators
        wrote on last edited by
        #3

        Works normally on my machine (Debian). Here's the code I used:

        #include <QApplication>
        #include <QPainter>
        #include <QImage>
        #include <QTimer>
        #include <QLabel>
        
        int main(int argc, char ** argv)
        {
            QApplication app(argc, argv);
        
            QLabel view;
            QTimer::singleShot(0, [&view] () -> void  {
                QImage sourceImage("butterfly2.png");
                QImage destImage(sourceImage.width(), sourceImage.height(), sourceImage.format());
        
                QPainter painter(&destImage);
                painter.fillRect(destImage.rect(), Qt::magenta);
        
                painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
                painter.drawImage(0, 0, sourceImage);
        
                view.setPixmap(QPixmap::fromImage(destImage));
                view.show();
            });
        
            return QApplication::exec();
        }
        

        I also fetched this image for my test run. (QPainter::CompositionMode_Source also works as expected for me)

        Read and abide by the Qt Code of Conduct

        1 Reply Last reply
        1
        • P Offline
          P Offline
          Pisyandry
          wrote on last edited by Pisyandry
          #4

          Thank your for answer, but I means different case.

          Please try this image. Just load it to QImage and draw to another QImage with same format(ARGB32). Next, render it without blending. (Best way is render it using OpenGL with glDisable(GL_BLEND) ).

          This is correct result
          White butterfly on white background. Pixels of transparent area of source image were white but with zero alpha and after splitting alpha channel pixels become opaque white. It's correct.

          This is incorrect result
          White butterfly on black background. Pixels of transparent area of source image were white with zero alpha channel. But after QPainter::drawImage pixels become black with zero alpha channel. So, after splitting alpha channel pixels become opaque black. It's incorrect.

          kshegunovK 1 Reply Last reply
          0
          • G Offline
            G Offline
            Gerd
            wrote on last edited by
            #5

            Hi,
            Image-drawing and also scaling is always done by some kind of alpha-blending, so if you use full transparent pixels in drawing they will always end in qRgba(0,0,0,0).

            What you can do:
            If you need a copy of the source.image, use image.copy() instead of drawing the src-image into a new one of the same size and format,

            If you need to scale such an image you have to invert the pixels before and after the scaling. The scaled Image will be in QImage::Format_ARGB32_Premultiplied, so it has to be converted to QImage::Format_ARGB32.
            If you want to draw such an Image into an exsiting image both, the src and the destination image, needs to be in QImage::Format_ARGB32 and both needs to be inverted.
            Example for scaling:

            QImage sourceImage("butterfly3.png");
            QImage destImage;
            sourceImage.invertPixels(QImage::InvertRgba);
            destImage = sourceImage.scaled(sourceImage.width()/2, sourceImage.height()/2, Qt::IgnoreAspectRatio, Qt::SmoothTransformation).convertToFormat(QImage::Format_ARGB32);
            
            sourceImage.invertPixels(QImage::InvertRgba);
            destImage.invertPixels(QImage::InvertRgba);
            destImage.save("out.png", "PNG");
            
            

            Hope that helps
            Regards
            Gerd

            1 Reply Last reply
            2
            • P Offline
              P Offline
              Pisyandry
              wrote on last edited by
              #6

              Hi, thank you for answer, but it work only for white images. Now drawing loses color of full opaque pixels instead of transparent pixels (I.e. all image areas with opaque pixels become white)

              1 Reply Last reply
              0
              • P Pisyandry

                Thank your for answer, but I means different case.

                Please try this image. Just load it to QImage and draw to another QImage with same format(ARGB32). Next, render it without blending. (Best way is render it using OpenGL with glDisable(GL_BLEND) ).

                This is correct result
                White butterfly on white background. Pixels of transparent area of source image were white but with zero alpha and after splitting alpha channel pixels become opaque white. It's correct.

                This is incorrect result
                White butterfly on black background. Pixels of transparent area of source image were white with zero alpha channel. But after QPainter::drawImage pixels become black with zero alpha channel. So, after splitting alpha channel pixels become opaque black. It's incorrect.

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

                @Pisyandry said in QImage \ QPixmal loses alpha color when drawing:

                Please try this image. Just load it to QImage and draw to another QImage with same format(ARGB32). Next, render it without blending. (Best way is render it using OpenGL with glDisable(GL_BLEND) ).

                This is what I do in my example. One image is drawn to another and is then rendered to the screen. With the suggested image I still get correct behavior.

                Best way is render it using OpenGL with glDisable(GL_BLEND)

                I don't understand what raw GL calls are doing here, or how they relate to the issue at all.

                White butterfly on black background. Pixels of transparent area of source image were white with zero alpha channel. But after QPainter::drawImage pixels become black with zero alpha channel.

                ???!?

                So, after splitting alpha channel pixels become opaque black. It's incorrect.

                What is this splitting you're talking about, I don't get what you're trying to accomplish and I don't understand how are you obtaining these images.

                Read and abide by the Qt Code of Conduct

                1 Reply Last reply
                0
                • G Offline
                  G Offline
                  Gerd
                  wrote on last edited by
                  #8

                  Hi,
                  according to your description and your example i thought you where talking about black/white images.
                  However, even if i think it's not a good idea to deal with "the color of transparent pixels" you can try this:

                  QImage sourceImage("butterfly3.png");
                  QImage destImage;
                  destImage = sourceImage.scaled(sourceImage.width()/2, sourceImage.height()/2, Qt::IgnoreAspectRatio, Qt::SmoothTransformation).convertToFormat(QImage::Format_ARGB32);
                  quint32 *dst = (quint32*)destImage.bits();
                  for (int i = 0; i < destImage.byteCount() / 4; i++, dst++)
                     if (*dst == 0x00000000)
                        *dst = 0x00ffffff;
                  destImage.save("out.png", "PNG");
                  
                  

                  Regards
                  Gerd

                  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