Script to loop through image pixels

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?

Thanks so much

The API does expose image.pixels.

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.

This will be very, very slow.:frowning:

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.

Don’t do that!

>>> print(myImage.pixels[index])

you should always create a copy of the pixels, e.g.

pixels = myImage.pixels[:]

accessing your own copy of pixels will be several times faster

Wow CoDEmanX that is much faster! Thanks! I revised my script basing it off the code from a great website I found (http://blenderscripting.blogspot.com/2012/08/adjusting-image-pixels-walkthrough.html). If anyone could give me some feedback on the script I would greatly appreciate it.

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’)?

Thanks so much!

Maybe have a look at this addon:http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/UV/Bake_Texture_to_Vertex_Colors

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…