"The python console check"
In case Markus is busy can get a lot of info using autocomplete Tab in the python console, with an image as img
>>> img.pixels.foreach_get(
foreach_get(seq)
.. method:: foreach_get(seq)
This is a function to give fast access to array data.
which is plainly different from, for instance a mesh me
vertices, which asks for an attribute attr
, eg for vert coordinates "co"
>>> me.vertices.foreach_get(
foreach_get(attr, seq)
.. method:: foreach_get(attr, seq)
This is a function to give fast access to attributes within a collection.
A very slight improvement in speed can be attained by using np.empty
to initialize the array, since any garbage will be filled by the foreach get.
import time
import numpy as np
REPS = 100
def time_it(func):
def wrapper(*arg, **kw):
t1 = time.time()
for i in range(REPS):
func(*arg, **kw)
t2 = time.time()
print(func.__name__, (t2 - t1))
return wrapper
@time_it
def read_pixels(img):
resolution = img.size[0] * img.size[1]
colors = np.zeros(resolution*4, dtype=np.float32)
img.pixels.foreach_get(colors)
colors = np.reshape(colors, (resolution, 4))
return colors
@time_it
def read_pixels2(img):
x, y = img.size
pixels = np.empty(x * y << 2, dtype=np.float32)
img.pixels.foreach_get(pixels)
return pixels.reshape((x, y, 4))
@time_it
def nptest1(img):
x, y = img.size
return np.array(img.pixels, dtype=np.float32).reshape((x, y, 4))
@time_it
def nptest2(img):
x, y = img.size
return np.array(img.pixels[:], dtype=np.float32).reshape((x, y, 4))
import bpy
for img in bpy.data.images:
nptest1(img)
nptest2(img)
read_pixels(img)
read_pixels2(img)
#break
Results
nptest1 8.4240
nptest2 7.0605
read_pixels 0.2264
read_pixels2 0.2222
Note on posting noticed I had reshaped to image x, y, 4, however reshape is an almost time "free" method, will get back if otherwise. (Got a squeak more using bitwise shift to quadruple)
foreach_get
method on thepixels
object, so the method uses itsself
argument which is set automatically to thepixels
object. From what I could google, other people useforeach_get
by only passing the numpy array as a temporary buffer, so you should tryimg.pixels.foreach_get(colors)
$\endgroup$