Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

transparency for an image?



  • I have spent about an hour and a half trying to work with masks, whether it be under the QPixmap, QImage, or QColor classes and haven't gotten anywhere. So, I decided to try to just manipulate the individual pixels one by one as a last resort.

    The objective is to extract the rgb from each pixel, then set that pixel to the same rgb values, but use a different alpha value. So essentially, just make the 50x50 section of the image more see-through or opaque.

    My image is just a red circle. When I run this block of code, this is what it looks like: http://imgur.com/Rrn5sSn It's successfully attempting to manipulate the 50x50 pixel box of the image I'm wanting to modify, it's just not modifying them correctly.

    	QImage p2("myBG.png");
    	QColor apixel;
    	QRgb value;
    	for(int i=1; i<50; i++){
    		for(int j=1; j<50; j++){
    			apixel = p2.pixel(i,j);
    			value = qRgba(apixel.red(), apixel.green(), apixel.blue(), 200);
    			p2.setPixel(i, j, value);
    		}
    	}
    

    The end goal is for this silly red circle to be a button (with a much cleaner looking graphic) where it fades in a little when you hover over it and fades out when you un-hover it.

    Side note: I'd rather manage the animation myself using time() or something rather than use the animation machine stuff. I don't like that code at all and refuse to use it just so you know.



  • I use the following code to create a transparent image , give it a try

     QPixmap temp(mainPixmap.size());
        temp.fill(Qt::transparent);
    
        QPainter p(&temp);
        p.setCompositionMode(QPainter::CompositionMode_Source);
        p.drawPixmap(0, 0, mainPixmap);
        p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
        p.fillRect(temp.rect(), QColor(0, 0, 0, 200));   
        p.end();
    
        mainPixmap = temp;
    


  • This works great. It must be something to do with the composition modes. I will read the docs on those. Thanks for the quick reply. Very much appreciated.



  • @Darkware
    If you still want to chance alpha by modifying pixel by pixel, you might try it that way:

    QImage image = ...;
    for ( int y = image.height(); y--; ) {
    	QRgb *rgbLine = (QRgb*)image.scanLine(y);
    	for ( int x = image.width(); x--; ) {
    		int red = qRed(*rgbLine);
    		int green = qGreen(*rgbLine);
    		int blue = qBlue(*rgbLine);
    		int alpha = qAlpha(*rgbLine)
    
    		// modify your values here
    
    		*rgbLine = qRgba(red, green, blue, alpha);
    		++rgbLine;
    	}
    }
    


  • So I have one more question regarding this image code. The code works if it's all within main(), but the moment I try to separate the pixmap loading code from main() by putting it into a function and just calling that function, it ceases to work.

    The strangest thing is that I can get the graphics to appear if I put a QMessageBox in the function, but you can only see the graphics as long as the QMessageBox is there. Once you close out of it, the graphics disappear.

    Where am I doing wrong?

    #include <QtCore>
    #include <QtWidgets>
    #include <QApplication>
    
    void startscreen(QGraphicsScene *scene);
    
    int main(int argc, char **argv)
    {
    	QApplication app(argc, argv);
    
    	//make the scene
    	QGraphicsScene* scene = new QGraphicsScene;
    	scene->setBackgroundBrush(Qt::white);
    
    	//make the view for the scene
    	QGraphicsView window(scene);
    	window.setFrameStyle(0);
    	window.setAlignment(Qt::AlignLeft | Qt::AlignTop);
    	window.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    	window.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    	window.resize(300, 300);
    	window.show();
    
    	//load graphics
    	startscreen(scene); //If you take this function out and
    					//just put the graphics code here
    					//instead of calling them through
    					//a function, the graphics load.
    					//Through this function, they don't
    					//though.
    
    	return app.exec();
    }
    
    void startscreen(QGraphicsScene *scene)
    {
    	//Make a QPixmap from "myBG.png"
    	//and make it more transparent with a QPainter
    	QPixmap p9("myBG.png");
    	QPixmap temp(p9.size());
    	temp.fill(Qt::transparent);
    	QPainter p(&temp);
    	p.setCompositionMode(QPainter::CompositionMode_Source);
    	p.drawPixmap(0, 0, p9);
    	p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
    	p.fillRect(temp.rect(), QColor(0, 0, 0, 50));
    	p.end();
    	p9 = temp;
    
    	//Make a QGraphicsPixmapItem from p9 above
    	//so it can be added to the scene.
    	QGraphicsPixmapItem gfxPixItemP2( p9 );
    	QPointF mpoint2(100,100);
    	gfxPixItemP2.setPos(mpoint2);
    	scene->addItem(&gfxPixItemP2);
    
    	//Graphics only show up if this message box is here.
    	//Also, you have to keep the message box open for the graphics
    	//to appear. Once you close the box, the graphics disappear.
    	QMessageBox msgBox;
    	msgBox.setText("My graphics only show up if I exec() this QMessageBox");
    	msgBox.exec();
    }
    
    #include "main.moc"
    

  • Lifetime Qt Champion

    @Darkware said:
    Hi the differnce between having the code directly in main and
    using void startscreen(QGraphicsScene *scene)
    is that when using the function, variables can run out of scope and get deleted.

    When u then put in messagebox and use exec() u block/stop it from running out of
    scope until u press ok.

    I didnt look through all the code but you clearly have some classes u allocated in the function that need to have longer life than the function call.
    Eaxmple
    addItem(QGraphicsItem * item)
    expects pointer to the element.
    You give it address of element
    QGraphicsPixmapItem gfxPixItemP2( p9 );
    scene->addItem(&gfxPixItemP2);

    gfxPixItemP2 will ONLY exists as long as inside function.
    You need to new it
    QGraphicsPixmapItem *gfxPixItemP2=new QGraphicsPixmapItem ( p9 );
    scene->addItem(gfxPixItemP2);



  • Thanks. I got it working.

    Sam, onek24, mrjj - thank you for all for the help you have given me.


Log in to reply