3
$\begingroup$

I would like to be able to draw a circle inside an image that is available in image editor.

I found this code here but I do not know how to manipulate the xy values for drawing a circle properly.

size = 640, 480

import bpy
# blank image
image = bpy.data.images.new("MyImage", width=size[0], height=size[1])

## For white image
# pixels = [1.0] * (4 * size[0] * size[1])

pixels = [None] * size[0] * size[1]
for x in range(size[0]):
    for y in range(size[1]):
        # assign RGBA to something useful
        r = x / size[0]
        g = y / size[1]
        b = (1 - r) * g
        a = 1.0

        pixels[(y * size[0]) + x] = [r, g, b, a]

# flatten list
pixels = [chan for px in pixels for chan in px]

# assign pixels
image.pixels = pixels

# write image
image.filepath_raw = "/tmp/temp.png"
image.file_format = 'PNG'
image.save()

```
$\endgroup$
1
  • $\begingroup$ Wow never knew direct pixel access was possible. Can we now extend it with popular python image libraries as well? $\endgroup$
    – Peter
    Commented Jan 25, 2020 at 11:24

1 Answer 1

3
$\begingroup$

Try this (I'm on Blender 2.81a):

import bpy
import math

size = 640, 480

# Calculate distance between two point
def distance(p0, p1):
    return math.sqrt((p0[0] - p1[0])**2 + (p0[1] - p1[1])**2)

# blank image
image = bpy.data.images.new("circle_img", width=size[0], height=size[1])

pixels = [None] * size[0] * size[1]
center = (int(size[0]/2.0), int(size[1]/2.0)) # center of image
radius = 50 # radius of circle in pixels
for x in range(size[0]):
    for y in range(size[1]):
        d = distance((x,y),center)
        if d < radius:
            r = g = b = a = 1.0 # white
        else:
            r = g = b = 0.0 # black
            a = 1.0            
        pixels[(y * size[0]) + x] = [r, g, b, a]

# flatten list
pixels = [chan for px in pixels for chan in px]

# assign pixels
image.pixels = pixels

# write image
image.filepath_raw = "/tmp/temp.png"
image.file_format = 'PNG'
image.save()

Circle isn't very pretty though (could use some anti-alias or blur)!

$\endgroup$
2
  • $\begingroup$ Thanks, that works for me. $\endgroup$
    – yarun can
    Commented Jan 14, 2020 at 17:16
  • $\begingroup$ Be tempted to leverage of v = Vector((x + 0.5, y + 0.5)) rather than the expensive euclidean distance calculation, and maybe use the "pixel center" (eg for pixel 0, 0 the center is (0.5, 0.5)) and not type cast the image center to int. The distance is then (v - center).length $\endgroup$
    – batFINGER
    Commented Jan 15, 2020 at 2:10

You must log in to answer this question.

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