How can access to pixel data with PYQt' QImage scanline()
Asked Answered
W

1

4

I need to access the pixel data in a qimage object with PyQt4.

The .pixel() is too slow so the docs say to use the scanline() method.

In c++ I can get the pointer returned by the scanline() method and read/write the pixel RGB value from the buffer.

With Python I get the SIP voidptr object that points to the pixels buffer so I can only read the pixel RGB value using bytearray but I cannot change the value in the original pointer.

Any suggestions?

Webbing answered 6/7, 2012 at 9:58 Comment(0)
M
8

Here are some examples:

from PyQt4 import QtGui, QtCore
img = QtGui.QImage(100, 100, QtGui.QImage.Format_ARGB32)
img.fill(0xdeadbeef)

ptr = img.bits()
ptr.setsize(img.byteCount())

## copy the data out as a string
strData = ptr.asstring()

## get a read-only buffer to access the data
buf = buffer(ptr, 0, img.byteCount())

## view the data as a read-only numpy array
import numpy as np
arr = np.frombuffer(buf, dtype=np.ubyte).reshape(img.height(), img.width(), 4)

## view the data as a writable numpy array
arr = np.asarray(ptr).reshape(img.height(), img.width(), 4)
Malpighiaceous answered 9/7, 2012 at 17:20 Comment(4)
Good question; added another answer to the list.Malpighiaceous
Dude, you can't imagine how long I was googling how to do that. Huge thanks. Worth saying that the last line creates a view, not a copy into the data. If somebody wants to create a copy of QImage, call .copy() on array. Plus, keep an eye on format. I needed to get RGB, thus calling something like arr[:, :, [0, 2]] = arr[:, :, [2, 0]] helpedNanosecond
Very nice solution. In python 3.6 and PySide6, setsize, byteCount, asstring and buffer are not available. One might need to use img.bytePerLine() * img.height() and memoryview instead.Bathesda
@Zézouille please consider adding a new answer!Malpighiaceous

© 2022 - 2024 — McMap. All rights reserved.