1
$\begingroup$

I want to know if it is possible to pass bpy.data.images["image"].as_pointer() to a C function to update image pixels directly, instead of using pixels.foreach_set() and pixels.foreach_get()

Edit:

I tried the following to change the float_buffer,but this did not work, the image stays the same. I have tried updating the image by setting the dirty flag, but this results in illegal memory access crash. I also tried calling image.update() and image.pixels.update() on the Python side hoping for a miracle lol.

void EXPORT set_all_pixels_to_white(ImBuf *buf) {
    float *pixels = buf->float_buffer.data;
    int num_pixels = buf->x * buf->y * buf->channels;
    for (int i = 0; i < num_pixels; i += buf->channels) {
        pixels[i] = 1;
        pixels[i + 1] = 0;
        pixels[i + 2] = 0;
        pixels[i + 3] = 1;
    }
}

Python side:

scene.mydll.set_all_pixels_to_red.argtypes = [POINTER(c_uint8)]
scene.mydll.set_all_pixels_to_red(byref(ctypes.c_uint8(my_image.as_pointer())))
$\endgroup$

1 Answer 1

2
+50
$\begingroup$

From the source code that Blender Python uses to set image pixels, we can learn a thing or two:

  • The pointer you are sending to the dll refers to an Image. That is a different type than ImBuf.
  • You can get the ImBuf using BKE_image_acquire_ibuf(), so you have to mimic that function somehow in your dll.
  • An ImBuf is not always using the float_buffer. When ibuf->float_buffer.data == nullptr, it means that the image data is in ibuf->byte_buffer.data.
  • It is not guaranteed that an image has 4 channels, that's only when the image has an alpha channel. So to be completely safe when writing the pixel data, you should do something like
if (buf->channels == 4) {
  pixels[i + 3] = 1;
}

Perhaps this gives you some directions to get your code working.

$\endgroup$
1
  • $\begingroup$ Thank you, exactly what I needed. I missed BKE_image_acquire_ibuf() during my search of Blender source code. $\endgroup$ Commented Dec 7, 2023 at 15:00

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.