Loading image for display in script window.

Hi Everyone,

Another quick question: is there a quick way to load an image in the general formats supported by Blender (*.png, *.jpg, etc.) for display using the BGL commands?

I have found the method by jms:
http://jmsoler.free.fr/didacticiel/blender/tutor/def_tga_pic.htm
which involves reading raw RGB data directly from an appropriate binary file. However, I was wondering if there is a way to generate a texture buffer directly from an Image object? Something like:


# Theoretical process (not real code):
import Blender
from Blender import Image

image = Image.Load("test.png")
buffer = image.getBuffer()

Thanks,

Jonathan Merritt.

any time that you want to import an image it involved decoding the format and reading the RGB all that your proposing is a built in c++ extensed function

not a bad idea but the only speed increase would be the speed difference between c++ and python

MacBlender

Look at this page:
http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_charger1image.htm

That’s cool… :o

Look at this page:
http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_charger1image.htm

That looks excellent for textured objects, but what I’m trying to do is straightforward bitmap drawing. I’m following the methods that Blender itself uses for display of images, because I’m concerned about the accuracy of my graphics card if I were to use textures.

This is how I’m drawing my bitmaps:

def drawImage(image, x, y, w, h, zoom):
	"""
	Draws an image in the current OpenGL context.  This method takes care of
	the problem of OpenGL clipping the raster position if it is outside of the
	viewport.  Note that the image is always drawn so that a pixel boundary is
	aligned along the left and bottom of the window.
	
	@param image	BGL buffer containing the image to draw; this may be NULL, 
					 in which case no image will be drawn.
	@param x, y		Coordinates of the bottom-left of the image (integers).
	@param w, h		Width of the original, un-zoomed image.
	@param zoom		Zoom factor for the image (float).
	"""
	if image is None:
		return
	BGL.glPixelStorei(BGL.GL_UNPACK_ROW_LENGTH, w)
	dx = dy = 0
	if x < 0:
		dx = -x
		x = 0
		BGL.glPixelStorei(BGL.GL_UNPACK_SKIP_PIXELS, int(dx / zoom))
	else:
		x = int(x / zoom) * zoom
	if y < 0:
		dy = -y
		y = 0
		BGL.glPixelStorei(BGL.GL_UNPACK_SKIP_ROWS, int(dy / zoom))
	else:
		y = int(y / zoom) * zoom
	BGL.glPixelZoom(zoom, zoom)
	BGL.glRasterPos2d(x, y)
	BGL.glDrawPixels(int(w-(dx/zoom)), int(h-(dy/zoom)), BGL.GL_RGBA, 
		BGL.GL_UNSIGNED_BYTE, image)
	BGL.glPixelStorei(BGL.GL_UNPACK_ROW_LENGTH, 0)
	BGL.glPixelStorei(BGL.GL_UNPACK_SKIP_PIXELS, 0)
	BGL.glPixelStorei(BGL.GL_UNPACK_SKIP_ROWS, 0)
	BGL.glPixelZoom(1.0, 1.0)

Jonathan Merritt.

It seems that you do not really use my script.

The image is loaded in the card’s memory and there is no problem with
clipping . Just try negative value for x,y and you will see that it works perfectly.

@jms: your site looks like it has good info on it but I have visited it several times and there doesn’t appear to be an English version or maybe I’m missing it?

Do you need an english version ?

http://jmsoler.free.fr/didacticiel/blender/tutor/english/cpl_charger1image_en.htm

Thanks!

Hi jms,

It seems that you do not really use my script.

The image is loaded in the card’s memory and there is no problem with
clipping . Just try negative value for x,y and you will see that it works perfectly.

I think I might have been a bit unclear. I am using a modified version of one of your scripts, just not the texture mapping script. :smiley: There are two problems:

  1. The code I am using is a modification of your script that uses glDrawPixels(). The problem with glDrawPixels() is that if you set a raster position outside of the viewport, it gets clipped and the image is not shown. This happens on my setup, at least, and is acceptable according to the OpenGL spec. (NB: It should be possible to set a valid raster position outside the viewport by passing a NULL argument to glDrawBitmap() and offsetting the raster position. However, I don’t think we can do this in Blender because of the BGL.Buffer wrapping the underlying C pointer.) To overcome this clipping problem, I used the ROW_LENGTH, SKIP_PIXELS and SKIP_ROWS states you can see in the code. The use of these states constrains me to use pixel-boundary-aligned drawing.

  2. I don’t want to use texture mapping to achieve the same effect (your second script) because I have read that it can be inaccurate on some graphics cards. My application is for camera calibration, so I ideally want everything to be as accurate as possible. If the user clicks on the (probably zoomed) image, I need to know exactly where in each pixel they have clicked. I believe there may also be problems using texture mapping if the user tries to view very large images using older cards.

Jonathan Merritt.

ok,

could I add these info to this page ?

Hi Jean Michel,

can you tell me if there is a way to retrieve rgba datas from the glbuffer
it is cool to be able to display an image but noone seems to be pointing out the terrible cruelty:
“dieu du ciel mais c’est pas vrai !!!”: there is no way to check the value of a particular pixel
for instance if you want to make displacement mapping

???