3
$\begingroup$

I need to ascertain if it's possible to complete a project in Blender exclusively (my preference) or if I need to use an OpenGL API to write an external application for my needs.

If the project can be completed in Blender, then I need to be able to color pixels on a 2D image using Python within Blender. If that can be done by pixel coordinate, then my project can be completed in Blender.

Because the Blender API documentation is laid out by structure of API itself rather than by task (a good thing!) I'm having trouble locating the part of it that I'm interested in. Because usually Blender isn't used for this, I can't find any discussions that point me in the right direction.

edit: I see that bpy.ops.paint.sample_color() can be used to sample a color on an image; I'm just having trouble finding a way to directly manipulate pixels.

edit2: I should mention that I also found this in old documentation, but searches for something similar in the current documentation come up empty.

last edit: This thread from 2007 includes a script for pixel level access to images. however, it is dependent upon classes that are not a part of the Blender API and do not appear to be part of the Python repository. The colour class does not inherit as_tuple, which in turn only seems to be part of the decimal class.

So, I'm not listing it as an answer because there's no way to know with certainty just what the author meant when those classes are used.

$\endgroup$
2
  • $\begingroup$ Would you add your last edit to this meta question meta.blender.stackexchange.com/questions/429/duplicate-answers/… I think this is a very good example. $\endgroup$
    – stacker
    Commented Sep 18, 2014 at 12:07
  • $\begingroup$ That page shows me as logged out and will not let me log in. When I click "log in", the page just refreshes, and when I click "join", it loads a page that shows me as logged in but it's back to logged out on that page. $\endgroup$
    – JPHarford
    Commented Sep 19, 2014 at 1:19

2 Answers 2

5
$\begingroup$

Within blender's image class you can access the raw pixel data at image.pixels as an array of floats, 4 floats per pixel (RGBA). image.size[0] is the width in pixels image.size[1] for height.

This answer shows how to crop an image, while this one about performance might be useful.

$\endgroup$
1
  • $\begingroup$ Awesome, thank you! I saw that pixels can be grabbed that way, but thought that each element of the pixel array is a single float. That's much more intuitive. $\endgroup$
    – JPHarford
    Commented Sep 16, 2014 at 7:13
4
$\begingroup$

This snippet provides a get and set_pixel function as a demo a sine is drawn. It uses a image named 'Untitled' (default when you create a new one in the UV-Editor)

import bpy
import math

# image name from UV editor
image = bpy.data.images['Untitled']
width = image.size[0]
height = image.size[1]

# RGBA
color = (1.0, 0.0, 0.0 , 1.0 )
print("%d x %d" % ( width,height))


def set_pixel(img,x,y,color):
    offs = (x + int(y*width)) * 4
    for i in range(4):
        image.pixels[offs+i] = color[i]

def get_pixel(img,x,y):
    color=[]
    offs = (x + y*width) * 4
    for i in range(4):
        color.append( image.pixels[offs+i] )
    return color

inc = math.pi * 2 / width
s = - math.pi    
for x in range(0, width-1):
    y =  math.sin( s ) * (height/2) + height/2-1
    #print( get_pixel( image, x, y) )
    set_pixel(image, x,int(y),color)
    s = s + inc

Result:

enter image description here

$\endgroup$
1
  • $\begingroup$ Very cool! This is as straightforward as I would have hoped. I just hesitated to experiment on those lines out of sheer inexperience and I thought the pixels array held a single float per index $\endgroup$
    – JPHarford
    Commented Sep 16, 2014 at 7:19

Not the answer you're looking for? Browse other questions tagged .