0

I am trying to load an .jpg image of resolution 30592 x 18432 in PyQt5 using QImage.

image = QImage(image_path)

# (same behavior with QPixmap as well)

But QImage returns a NULL image when I check with its isNull() method. So tried descaling the image and found out that I am able to load images with width less than 30000. So 29500 x 17774 works. I have 16GB RAM so I don't suspect any memory constraints (At 29500 x 17774, memory usage is about 3.5 GB while loading and gets down to 1.5GB while displaying image after loading is finished).

So I thought this issue is probably due to max size limit of QImage. So I searched online and only relevant forum I could find was this, according to which QImage support upto 32767x32767 pixels. So my original image should have loaded but it didn't.

Is max supported resolution is different for Qt(C++) and PyQt?

Are there any other methods to load images of this size. So far I have tried:

  1. Loading images using cv.imread(), it does loads the 30592x18432 image but on converting it to QImage, it returns null.

  2. Descaling as I mentioned before, its my last resort only as I am losing some details while zooming in.

  3. I am trying to convert Mat/Numpy.array images (cv.imread()) to QImages in tiles of 1000x1000. It works but not yet perfect. Still working on that.

Version Details:

Installation: Anaconda 22.9.0 (64 bit)

Installation Dir/Env: Base/Root

Python: 3.9.13 (64 bit)

PyQt: 5.9.2

PrimuSPS
  • 11
  • 2
  • *This is just an uninformed guess* - but maybe the thread reading your image is still in progress when you're calling `isNull`? Could be worth to test adding `time.sleep` (or equivalent) between the constructor call and null checking. – simeonovich May 12 '23 at 10:09
  • @simeonovich No, Qt loads images in the *current* thread of the constructor (or load function call). – musicamante May 12 '23 at 11:24
  • @simeonovich no, threads dont work like that, QImage(image_path) be execute first and control wont move to the nexxt statement untill current one is finished executing – PrimuSPS May 12 '23 at 11:37
  • 3
    The [question you linked to](https://stackoverflow.com/q/7080052/984421) **does not** state that "QImage supports up to 32767x32767 pixels". That only applies to QPixmap. The true limits for QImage are explained in [this answer](https://stackoverflow.com/a/24728584/984421) and [this answer](https://stackoverflow.com/a/7081057/984421). To make the correct calculation, you need to do `image.width() * image.height() * image.depth()` and check that it's less than INT_MAX (which is 2,147,383,647 on most systems). – ekhumoro May 12 '23 at 11:49
  • @ekhumoro Oh I see, but it didn't worked with pixmap as well, i didn't calculate the actual depth but did set minimum pixel density while i was experimenting with descaling but it also didn't worked leaving me with resolution only. Are depth and pixel density different? – PrimuSPS May 12 '23 at 12:07
  • @PrimuSPS I don't see the relevance of pixel density. After creating `image = QImage(image_path)`, what are the actual values of `image.format()`, `image.width()`, `image.height()` and `image.depth()`? – ekhumoro May 12 '23 at 13:11
  • @ekhumoro I can't calculate them they way its done in Qt C++, loading 30592 x 18432 image using `image = QImage(image_path)` QImage returns null i.e. NoneType therefore I cant get image parameters like width, height and depth whiteout loading image first – PrimuSPS May 12 '23 at 17:39
  • 1
    @PrimuSPS Okay, so it seems the internal QImageReader explicitly returns a null QImage if the load fails. Try this instead: `i = QImage(); r = QImageReader(path)`. And then check `r.errorString()`, `r.canRead()`, `r.format()`, `r.size()` (i.e. *before* trying to actually read the image). Then do the same checks again after calling `r.read(i)` (which presumably will return false). This may give some clues as to the problem and also allow calling `i.depth()` (even though the image data hasn't been loaded). You could also do the above with your smaller image to see what the differences are. – ekhumoro May 12 '23 at 19:02
  • @PrimuSPS Actually, it may be more informative to check `r.imageFormat()` rather than `r.format()`, as that returns a [QImage.Format](https://doc.qt.io/qt-5/qimage.html#Format-enum). Basically, you want to determine what QImageReader knows about your image file, before it tries to read the data. – ekhumoro May 12 '23 at 19:14
  • @ekhumoro I tried your suggestions. `r.errorString()` returns "unsupported image format" despite i am using .jpg file and like you said `r.size()` and `r.format()` returns (-1,-1) and 0 respectively. I tried other images formats like .png and even exported another .jpg using GIMP for which `r.errorString()` returns "Unknown Error" – PrimuSPS May 13 '23 at 06:20
  • @PrimuSPS On my Linux system, I am able to read a 36000 x 50000 jpeg without any problems. The image ([from wikimedia](https://commons.wikimedia.org/wiki/File:21_gigapixel_total_renovation_of_Girl_with_a_pearl_earring-Digital_Profoundism-Demo-Cropped.jpg)) is 32-bit, and uses about 7Gb of memory. This proves that the limits suggested in the linked question are wrong, and possibly only ever applied to Qt4. I also tried a 55399 x 65000 image, which QImageReader loads okay, but then cannot fully read due to insufficient memory. So it seems the only real limit in Qt5 is available memory. – ekhumoro May 14 '23 at 19:52
  • @PrimuSPS If you're not able to load a 30592 x 18432 jpeg, there must be a problem with the particular version of Qt5 you're using, or perhaps some platform-specific issue. Either that, or the jpeg is in a format that Qt does not support. How was the image created? – ekhumoro May 14 '23 at 20:05
  • Post a [mre] including a sample image file. – relent95 May 15 '23 at 01:25
  • @relent95 It already is. I have debugged line by line and problem occur only if I open image in `QImage` or convert from other formats to `QImage` . As for reference image you can use the [image](https://commons.wikimedia.org/wiki/File:21_gigapixel_total_renovation_of_Girl_with_a_pearl_earring-Digital_Profoundism-Demo-Cropped.jpg) shared by @ekhumoro – PrimuSPS May 15 '23 at 06:16
  • @ekhumoro Oh any idea how to fix with if its platform related. I have anaconda installation in root in windows. As for the original image, it was generated by stitching several images in OpenCV but I have tried other images as well including the one you shared as well and they don't load. – PrimuSPS May 15 '23 at 06:37
  • That 36000x50000 image of a girl loads fine in my Linux and Windows box. So, it's not a [mre]. – relent95 May 15 '23 at 09:07
  • @relent95 maybe issue is with my platform only (as user ekhumoro suggested). I don't know what else to give you. If you need any specific detail, I will be happy to share it – PrimuSPS May 15 '23 at 10:41
  • @PrimuSPS It sounds like Anaconda is the most likely culprit. Which *specific* version of Qt5 are you testing with? It seems that [PyQt-5.15.7](https://anaconda.org/anaconda/pyqt) is available for win-64, but win-32 only has PyQt-5.9.2. I suggest you create a venv (outside of Anaconda) and install the latest verison of PyQt5 via pip. If you're able to read the images with that, it would strongly suggest the problem lies with Anaconda. (PS: whatever the outcome, please update your question with details about your platform, and the specific versions of Anaconda and PyQt5 you are using). – ekhumoro May 15 '23 at 11:49
  • @ekhumoro oh I have version 5.9.2 which came with by default in anaconda installation. I don't know why it is 32 bit installation despite interpreter is 64 bit. I will update the post with version details and will try with 64 bit installation for PyQt. – PrimuSPS May 16 '23 at 05:40
  • Anaconda 22.9.0 cannot be downloaded anymore. Why not use recent version? How did you install PyQt? With Pip or Conda? – relent95 May 16 '23 at 09:37
  • @relent95 PyQt was bundled in the anaconda installation and that was the latest version available at the time. System that I am using doesn't have internet access so I cant update it as I like. – PrimuSPS May 17 '23 at 06:52
  • I tested the recent Anaconda pyqt package in Windows box and it works fine. Just use the recent version. You can copy a Conda environment into the offline host. See [this answer](https://stackoverflow.com/a/58103362/1186624). – relent95 May 17 '23 at 08:41

0 Answers0