Can I draw a line in a image with OpenGL

I’m use to work in C# and Java, and there I have the “canvas” of a image, so I can draw in a image using the canvas, and then save the image with my draw on top.

In python I have something like this:

bgl.glEnable(bgl.GL_BLEND)
bgl.glBegin(bgl.GL_LINES)
bgl.glVertex2f(*v1)
bgl.glVertex2f(*v2)
bgl.glEnd()

How can I redirect this code the image? I want to draw a line, and then save the image.

It really depends on the context that you are trying to draw the line in. Are you trying to draw the line in the 3D Viewport in Blender or on screen in the BGE? Are you trying to draw in 2D or 3D? Do you want this stored in a Texture or as a file on disk?

Using BGL like that is going to render in the Viewport or in the BGE game world. If you wanted to capture the data in a Texture you could try doing a render-to-texture operation and using your BGL code to draw into that texture.

If you are looking for behavior that is more similar to working with a “canvas” (in Java drawing directly into a JFrame or JPanel for example) then you might investigate the “Python Image Library” or PIL. That is a Python library that allows you to open raster images like JPG, BMP, GIF, etc and apply 2D filter effects as well as 2D raster drawing (draw lines, rects, etc).

If you use PIL then you can create images directly in memory and write them to disk. Getting that image data into a Blender texture would require some extra work.

Please note that the original PIL project stopped being maintained. The active project is actually called “Pillow”, it is a fork of PIL and has the same classes/methods with fixes and enhancements.

What I want is to draw in the render result and save the image. Do you know any website or article to give some advice about this?

I do not know if this is the best way, but you can change each pixel of an image:
for example, to change the first pixel (in the lower left corner of an image), we can type:

bpy.data.images['Image Name'].pixels[0:4] = (Red, Green, Blue, Alpha) #Here "Red, Green, Blue, Alfa" are floating values.

Are you drawing in 3D or 2D?

I would think that the op is looking for a way to make his measureit addon render able.

If someone is interested, I have a question in http://blender.stackexchange.com/questions/31979/is-possible-to-draw-over-render-image-and-save-it

Here a proof of concept:


import bpy
import bgl
import blf
import bpy_extras.image_utils as img_utils


# Get the render image
path = "c:\	mp\	mp_render.png"
try:
    result = bpy.data.images['Render Result']
    if result.has_data is False:
        bpy.ops.render.render()
        result = bpy.data.images['Render Result']
except:
    bpy.ops.render.render()
    result = bpy.data.images['Render Result']
    
# Save and reload
result.save_render(path)
img = img_utils.load_image(path)




viewport_info = bgl.Buffer(bgl.GL_INT, 4)
bgl.glGetIntegerv(bgl.GL_VIEWPORT, viewport_info)


scene = bpy.context.scene
render_scale = scene.render.resolution_percentage / 100


WIDTH  = int(scene.render.resolution_x * render_scale)
HEIGHT = int(scene.render.resolution_y * render_scale)


# Load image on memory
img.gl_load(0, bgl.GL_NEAREST, bgl.GL_NEAREST)
tex = img.bindcode


# Create output image (to apply texture)
out = bpy.data.images.new("output", WIDTH, HEIGHT)
buffer = bgl.Buffer(bgl.GL_FLOAT, WIDTH * HEIGHT * 4)


bgl.glDisable(bgl.GL_SCISSOR_TEST) # if remove this line, get blender screenshot not image 
bgl.glViewport(0, 0, WIDTH, HEIGHT)


bgl.glMatrixMode(bgl.GL_PROJECTION)
bgl.glLoadIdentity()
bgl.gluOrtho2D(0, WIDTH, 0, HEIGHT)


# Clear
bgl.glClearColor(0.0, 0.0, 0.0, 0.0)
bgl.glClear(bgl.GL_COLOR_BUFFER_BIT | bgl.GL_DEPTH_BUFFER_BIT)


bgl.glEnable(bgl.GL_TEXTURE_2D)
bgl.glBindTexture(bgl.GL_TEXTURE_2D, tex)


bgl.glBegin(bgl.GL_QUADS)
bgl.glColor3f(1.0, 1.0, 1.0)
bgl.glTexCoord2f(0.0, 0.0)
bgl.glVertex2f(0.0, 0.0)
bgl.glTexCoord2f(1.0, 0.0)
bgl.glVertex2f(WIDTH, 0.0)
bgl.glTexCoord2f(1.0, 1.0)
bgl.glVertex2f(WIDTH, HEIGHT)
bgl.glTexCoord2f(0.0, 1.0)
bgl.glVertex2f(0.0, HEIGHT)
bgl.glEnd()


bgl.glLineWidth(10)
bgl.glBegin(bgl.GL_LINES)
bgl.glColor4f(1.0, 0.0, 0.0, 1.0)
#bgl.glTexCoord2f(0.0, 0.0)
bgl.glVertex2f(0.0, 0.0)
#bgl.glTexCoord2f(1.0, 1.0)
bgl.glVertex2f(WIDTH, HEIGHT)
bgl.glEnd()


# Draw a Text
font_id = 0
bgl.glColor4f(1.0, 1.0, 0.0, 1.0)
blf.size(font_id, 18, 72)
blf.position(font_id, 0.5, 0.5, 0)
blf.draw(font_id, "Hello World")   


#
bgl.glFinish()
bgl.glReadPixels(0, 0, WIDTH, HEIGHT , bgl.GL_RGBA, bgl.GL_FLOAT, buffer) # read image data
out.pixels = buffer[:] # Assign image data
img.gl_free() # free opengl image memory


#reset
bgl.glEnable(bgl.GL_SCISSOR_TEST)
# restore opengl defaults
bgl.glLineWidth(1)
bgl.glDisable(bgl.GL_BLEND)
bgl.glColor4f(0.0, 0.0, 0.0, 1.0)

After run the script, open a image viewer and look at output image.