0

I have an image that contains tiles. I want to make a QPixmap of each tile within the QPixmap. I thought QPixmap's copy(x,y,width,height) method would do this for me, but must be copying the entire image, not just the rectangle defined by the arguments, and thus consuming WAY too much memory.

An example below illustrates the problem. My png happens to be 3400x3078 pixels, dividing by the 57 rows, 50 columns, the minipixmaps should each be 68x54 pixels, but are obviously using much more memory than that. What am I missing?

from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QApplication

import os, sys

app = QApplication(sys.argv)
file = r"/path/to/image/grid-of-tiles.png"

# image I'm using has these many rows and columns of tiles
r = 57
c = 50

pixmap = QPixmap(file)

# the tiles are known to divide evenly
width = pixmap.width() / c
height = pixmap.height() / r

# after executing the below, mem use climbs north of 9GB!
# I was expecting on the order of twice the original image's size
minipixmaps = [pixmap.copy(row*height, col*width, width, height) for row in range(r) for col in range(c)]
Matthew Curry
  • 732
  • 5
  • 15

1 Answers1

1

Thanks to eyllanesc's comment. QImage does seem better behaved:

from PyQt5.QtGui import QPixmap, QImage
from PyQt5.QtWidgets import QApplication

import os, sys

app = QApplication(sys.argv)
file = r"/path/to/image/grid-of-tiles.png"

# image I'm using has these many rows and columns of tiles
r = 57
c = 50

mosaic = QImage(file) # QImage instead of QPixmap

# the tiles are known to divide evenly
width = mosaic.width() / c
height = mosaic.height() / r

# much less memory!
minipixmaps = [QPixmap.fromImage(mosaic.copy(row*height, col*width, width, height)) for row in range(r) for col in range(c)]
Matthew Curry
  • 732
  • 5
  • 15
  • 1
    Thanks, this was helpful! But shouldn't it be columns and rows swapped, i.e. `copy(col*width, row*height, width, height)`? – theozh Nov 08 '20 at 19:10
  • sorry @theozh can't remember, the codebase was a few years ago now, and the current job doesn't use much Python, but that's quite possible. The arguments do look like they should be as you say. – Matthew Curry Mar 18 '21 at 23:30