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

GIF smooth resize



  • I have a problem resizing a .gif file. Qt documentation points out directly that QSize.scaled() method has Qt.KeepAspectRatio argument that should resize the .gif file smoothly preserving the original proportions:
    0_1550146691759_aspect.png

    But it doesn't work in my case. It just resizes to the exact pixels I set and ignores the third argument (the original gif's width is larger than height):
    0_1550146860927_sample.gif

    Static image has no problem with it since there's Qt.SmoothTransformation argument in QPixmap.scaled() method which works fine. For static images.

    So how can I keep the original propotions of the gif when resizing it?
    Below is my example code:

    import sys
    from   PyQt5.QtWidgets import *
    from   PyQt5.QtGui     import *
    from   PyQt5.QtCore    import *
    
    GIF = 'GIF.gif'        # Insert your gif path here
    
    class Window(QWidget):
        def __init__(self):
            super().__init__()
            self.resize(500, 500)
            label = QLabel()
    	
            vbox = QVBoxLayout()
            vbox.addWidget(label)
            vbox.setAlignment(Qt.AlignCenter)
            self.setLayout(vbox)
    
            gif = QMovie(GIF)
            gif.setScaledSize(QSize().scaled(300, 300, Qt.KeepAspectRatio))
            label.setMovie(gif)
            gif.start()
    
    app = QApplication(sys.argv)
    screen = Window()
    screen.show()
    sys.exit(app.exec_())
    


  • So I just remembered about this post and since there's still no answer, I'll post my own workaround.

    from PIL import Image
    
    def smooth_gif_resize(gif, frameWidth, frameHeight):
        gif = Image.open(gif)
        gifWidth0, gifHeight0 = gif.size
    
        widthRatio = frameWidth / gifWidth0
        heightRatio = frameHeight / gifHeight0
    
        if widthRatio >= heightRatio:
            gifWidth1 = gifWidth0 * heightRatio
            gifHeight1 = frameHeight
            return gifWidth1, gifHeight1
    
        gifWidth1 = frameWidth
        gifHeight1 = gifHeight0 * widthRatio
        return gifWidth1, gifHeight1
    

    And then your doing something like this:

    gif = QMovie(GIF)
    gifSize = QSize(*smooth_gif_resize(gif, 300, 300))
    gif.setScaledSize(gifSize)
    label.setMovie(gif)
    gif.start()
    

    You are welcome!


Log in to reply