Hey, everyone! I have been blending for a while but have not done too much scripting. I am trying to make a script that iterates through the pixels in a loaded image and gets the RGB values of each pixel. This script will eventually become part of a larger script. In python 2.7, I believe you can use the python image library (PIL), but blender 2.6x uses python 3. Can anyone help me out?
This might get you going. I am not sure how the pixel data is actually stored? Four numbers for each pixel would be my guess.
This code assumes you have a texture named “myTexture” that has an image loaded.
import bpy
myTexture = bpy.data.textures.get("myTexture")
myImage = myTexture.image
imgWidth = myImage.size[0]
imgHeight = myImage.size[1]
for y in range(1,imgHeight):
for x in range (1,imgWidth):
index = x * y
print(myImage.pixels[index])
My range might be off by one I am not sure if this is zero based.
Oh great thank you! However, you are also right about the being very, very slow part. Is there any way to speed this up? I plan on having a black and white image consisting of mostly black pixels. I don’t care about the black pixels. I merely want to know the positions of the white pixels.
import bpy D = bpy.data
def find_white_pixels():
test_file = 'binarized.png'
img = D.images[test_file]
w = width = img.size[0]
print("width =",w)
h = height = img.size[1]
print("height = ",h)
# work on a copy instead, it's much faster
RGBA_list = list(img.pixels)
num_pixels = (w*h)
# this collects every 4 items in pixels and stores them inside a tuple
# and sticks all tuples into the grouped_list
gl = grouped_list = [RGBA_list[ipx] for ipx in range(0, len(RGBA_list), 4)]
print("grouped_list length = ",len(gl))
def idx_to_co(idx, width):
r = int(idx / width)
c = idx % width
return r, c
pixel_coordinate_list = pcl = []
count = 0
gl_counter = 0
for i in gl:
if (i>0):
pcl.append([idx_to_co(gl_counter, width)])
count = count+1
gl_counter = gl_counter + 1
print("gl_counter = ", gl_counter)
print ("r,c =",idx_to_co(gl_counter, width))
print("Number of non-black pixels = ", count) #This is total number of non-black pixels found
find_white_pixels()
Also, I was a little confused what line of code to use to make it so I didn’t have to open it in the UV editor first. What’s the difference between bpy.data.images.load(‘path’) and bpy.ops.image.open(filepath=‘path’)?
i bet your code can be simplified and maybe made a little faster still.
bpy.ops.* is always an operator, which requires a certain context (e.g. UV editor opened and certain object type selected etc.)
functions inside the data structure bpy.data.* are low-level functions, which should work context-independent. I recommend using them whenever available, as it’s less hassle (with context) and faster.
I tried that script but even with correct path i keeps giving me error;
raceback (most recent call last):
File “/Users/romboutversluijs/Desktop/Thea_1355/Random colors.blend/Text”, line 45, in <module>
File “/Users/romboutversluijs/Desktop/Thea_1355/Random colors.blend/Text”, line 7, in find_white_pixels
KeyError: ‘bpy_prop_collection[key]: key “/Users/romboutversluijs/Desktop/IBL-color.png” not found’
Error: Python script fail, look in the console for now…