# Creating and packing a 32-bit float image

How can I specify the file type and color depth when generating and packing an image with Python?

I'm trying to generate an image with full 32-bit float color depth and pack it into my blend file but I keep getting it revert back to 8-bits per channel.

I'm creating the image using the following python code :

import bpy

width = 800
height = 400

image = bpy.data.images.new("testimagepacked", width=width, height=height,float_buffer=True)

pixels = [None] * width * height

for x in range(0,width):
for y in range(0,height):
pixels[(y*width)+x] = [float(x)/width,float(y)/height,-y+x,1.0]

pixels = [chan for px in pixels for chan in px]
image.pixels = pixels
image.update()


This successfully creates the image and dragging the mouse across it in the UV/Image Editor shows that the pixels are correctly stored as floats (with the Blue channel ranging way beyond the usual 0.0, 1.0 limits and green and red not being rounded to 1/256ths).

If I manually select Image/Save As Image and specify the format as OpenEXR, RGBA, Float(full) to save if as a file and then select Image/Pack then the image is packed into the blend file retaining its full 32-bit precision.

This shows that it's possible to pack the image in 32-bit precision.

I have tried to replicate these actions in Python but am unable to save the image as 32-bit float - I can't figure out how to specify the image file format.

The nearest I've got is to save the image as OpenEXR but, apparently, not in 32-bit float for the image loses its precision when it's packed using this :

image.file_format = 'OPEN_EXR'
image.filepath='//created image.exr'

image.save()
image.pack(as_png=False) # I expected this to pack as float rather than PNG but this doesn't seem to work
image.use_fake_user = True


How can I specify the Image Format Settings when saving the image from Python? Even better would be to be able to directly pack the image (as 32-bit float) without having to save it to disk at all, but I don't think this is possible.

• Yep, seems not possible at the moment... the image needs to be saved before :/ Alternatively you could use python's tempfile library docs.python.org/3.6/library/tempfile.html (just an idea). – p2or Mar 7 '17 at 7:48
• @poor Thanks - that sounds useful for generating a temporary filename - I'll look into that. – Rich Sedman Mar 7 '17 at 9:10

It would seem that to control the image format that gets packed into a blend file, you will need to save the image to disk and then re-open it.

To get control of the file format an image is saved to disk with, you can use save_render(). The render settings from the scene parameter holds the ImageFormatSettings which allow you to adjust the settings. If you don't want to use the render settings from the current scene you can create a new one just for this.

scn = bpy.data.scenes.new('img_settings')
scn.render.image_settings.file_format = 'OPEN_EXR_MULTILAYER'
scn.render.image_settings.color_mode = 'RGBA'
scn.render.image_settings.color_depth = '32'
img_path = bpy.path.abspath('//')
img_file = image.name+'.exr'
image.save_render(img_path+img_file, scene=scn)

But this still leaves you with an edited image that doesn't respond to pack(). To get around this, remove the image block and open it from the file.
bpy.data.images.remove(image)