Search code examples
imagepyqtqpixmap

QPixmap width and height return 0


problemPicture

ENV

  • Win10
  • python3.7
  • PyQt5

Desc

With the following code, where image_path is the absolute path to problemPicture.(this is not a question about cannot find the pic)

pixmapHight and pixmapWidth will get 0, but the picture can be well openned and viewed with default APP

And for most pictures, this code works well, but fail on this special one.

so can anyone explain it and give me some advice?

pixmap = QPixmap(image_path)
pixmapHight = pixmap.height()
pixmapWidth = pixmap.width()

PS this question seems the same, but the answer is not accepted, and neither to my question.


Solution

  • I find it is caused by wrong suffix.

    The pic saved locally is suffixed by .png, but the real format is jpg.

    When specifying with right format, eg: QPixmap(image_path, format = 'jpg'), I can get correct height and width.

    here is my sample code to check real format:

    import os
    import sys
    import imghdr
    from PyQt5.QtGui import *
    from PyQt5.QtCore import *
    from PyQt5.QtWidgets import *
    class DemoApp(QMainWindow):
        def is_type_wrong(self, path):
        current_type = path[path.rfind('.')+1:]
        real_type = 'xxx'
        if path.lower().endswith('.gif') or path.lower().endswith('.jpg') or path.lower().endswith('.png'):
            header = []
            with open(path, 'rb') as f:
                while(len(header) < 5):
                    header.append(f.read(1))
            print(header)
            if (header[0] == b'\x47' and header[1] and b'\x49' and header[2] == b'\x46' and header[3] == b'\x38'):
                real_type = 'gif'
            if (header[0] == b'\xff' and header[1] == b'\xd8'):
                real_type = 'jpg'
            if (header[0] == b'\x89' and header[1] == b'\x50' and header[2] == b'\x4e' and header[3] == b'\x47' and header[4] == b'\x0D'):
                real_type = 'png'
        return current_type != real_type, real_type
    
    def __init__(self, parent=None):
        super(DemoApp, self).__init__(parent)
        image_path_list = ['D:\FailPic.png', 'D:\OkPic.png', 'D:\FromWeb.jpg']
        for image_path in image_path_list:
            if os.path.exists(image_path):
                fmt = imghdr.what(image_path)
                if fmt == None:
                    # I get one picture still can be opened with default app while imghdr.what return None
                    isWrongType, real_type = self.is_type_wrong(image_path)
                    if isWrongType:
                        fmt = real_type
                    else:
                        print("!!! corrupted picture: %s" %image_path)
                pixmap = QPixmap(image_path, format = fmt)
                pixmapHight = pixmap.height()
                pixmapWidth = pixmap.width()
                print("[%s]isNull:%d pixmapHight: %f, pixmapWidth: %f, fmt: %s" %(image_path, pixmap.isNull(), pixmapHight, pixmapWidth, fmt))
            else:
                print("pic % not found" %(image_path))
    if __name__ == "__main__":
        app = QApplication(sys.argv)
        main_window = DemoApp()
        main_window.show()
        sys.exit(app.exec_())