0
$\begingroup$

Is it possible to read RGB values from a pixel of a texture using UV coordinates and use that in drivers? Python code?

I'd like to create a driver to influence object's locations, rotation and visibility, but the only input I have is through a texture.

I'm using a special project template with certain points on the texture feeding color or B/W values for materials. I'd like to use the same texture to convey some values to drivers - changing the geometry of the scene, not only materials.

$\endgroup$
  • 1
    $\begingroup$ Sure, a PyDriver can access image pixels. I am skeptical that the scene will update correctly on frame change, but at render time it should update ok. $\endgroup$ – Jaroslav Jerryno Novotny Jan 26 '17 at 14:10
  • $\begingroup$ I only render single frames. But I select the frame depending on some other stuff. I'll either render frame 1 or 2, but all textures are static. Could you proved an example or direct me to some sources? $\endgroup$ – unfa Jan 26 '17 at 16:12
1
$\begingroup$

Each image datablock in Blender has a pixels property. This is an array of pixels starting from the bottom row left to right.

The RGBA values of a pixels are listed after one another. The RGBA values for the bottom-left pixels will be indiced with 0, 1, 2 and 3. The RGBA values of the second pixels can be called with the indices 4, 5, 6, 7 from the pixel list.

Starting with this post, this blog has lots of informations about pixels in bpy.data.images.

I have created a sample script which manipulates the object location based on frames of an images. (Compare the attached file.)

import bpy

def updateFromImage(scene):
    frame = scene.frame_current
    obj = scene.objects['Cube']

    pixels = bpy.data.images['InputImage'].pixels

    # read the green pixels
    greenPixelAtFrameNo = pixels[frame*4 + 1]
    obj.location.z = greenPixelAtFrameNo * 5
    obj.location.x = frame



bpy.app.handlers.frame_change_pre.append(updateFromImage)

| improve this answer | |
$\endgroup$
  • $\begingroup$ Fantastic! Looks like the pixels[] array is one-dimensional, which is a bit strange to allocate 6-dimensional dataset (X,Y,R,G,B,A) but your example shows how to access all I need. I need to know the image resolution thought to be able to interpret the table properly. I tried using this: bpy.data.images[].resolution But it gives me strange values: >>> bpy.data.images['InputImage'].resolution Vector((2835.0, 2835.0)) for your demo image that is 16x16 pixels big. I don't know what is this. $\endgroup$ – unfa Jan 27 '17 at 14:50
  • 1
    $\begingroup$ Check out this (blenderscripting.blogspot.de/2012/08/…) entry in the blog I linked. He writes a method to get pixels by coordinates. Instead of resolution that property you need is "size". "size[0]" is the width and "size[1]" the height in pixels. So to get a pixel at e.g. (12, 10) you need to calculate the index with: ((12-1) * size[0] + 10) * 4. Should I extend my answer with methods to get specific pixels or can you already continue with this? $\endgroup$ – Leander Jan 27 '17 at 15:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.