5
$\begingroup$

I'm developing blender exporter for CryEngine - CryBlend.

I need to convert an image to tiff and then pass it to cryengine resource compiled. The thing is it works while saving image with blender python console:

tiffImage= bpy.data.images[1].copy()
tiffImage.filepath_raw = 'new_path.tif'
tiffImage.file_format = 'TIFF'
tiffImage.save()

but the same code placed in plugin throws an exception at save()

"RuntimeError: Error: Image "my image" does not have any image data."

What's more, while debugging that code with pydev (in plugin) then it works as expected. I'm totally puzzled with it.

here is the complete code. export.py:1196

def __export_library_images(self, parent_element):
    library_images = self.__doc.createElement("library_images")
    parent_element.appendChild(library_images)

    for image in self.__get_texture_images_for_selected_objects():
        tiffFilePath = self.__convert_to_tiff_and_save(image)
        image_path = get_relative_path(tiffFilePath)

        image_element = self.__doc.createElement("image")
        image_element.setAttribute("id", "%s" % image.name)
        image_element.setAttribute("name", "%s" % image.name)
        init_from = self.__doc.createElement("init_from")
        path_node = self.__doc.createTextNode("%s" % image_path)
        init_from.appendChild(path_node)
        image_element.appendChild(init_from)
        library_images.appendChild(image_element)

def __convert_to_tiff_and_save(self, image):
    if image.file_format is not 'TIFF':
        tiffFilePath = os.path.splitext(image.filepath)[0] + ".tif"
        cbPrint(tiffFilePath, 'debug')

        if self.__config.run_rc_and_do_materials:
            try:
                tiffImage = image.copy()
                tiffImage.filepath_raw = tiffFilePath
                tiffImage.file_format = 'TIFF'
                tiffImage.save()
            finally:
                # remove tmp image from blend file database
                bpy.data.images.remove(tiffImage)
    else:
        tiffFilePath = image.filepath

    return tiffFilePath
$\endgroup$
2
  • 1
    $\begingroup$ There are some strange things here: You shouldn't be getting an exception since you're in a try block when this happens, and you're catching all exceptions (bad boy, you!). Also (unrelated), you should never use if image.file_format is not 'TIFF': This needs to be if image.file_format != TIFF':. Furthermore, your __convert_to_tiff_etc.() doesn't return anything, but your other method seems to think it does... $\endgroup$
    – Tim Pietzcker
    Commented Sep 14, 2013 at 20:48
  • $\begingroup$ __convert_to_tiff_etc.() returns, but that code was not pasted: fixed. I'm catching all exceptions because I want to delete that temporary image from blender database no matter what. $\endgroup$
    – Mikołaj
    Commented Sep 14, 2013 at 21:22

1 Answer 1

6
$\begingroup$

You can use save_render() to save to whatever format you want, no need to duplicate an image datablock first.

In my experience, save_render() is the only reliable way to export from one format to another. I tried the .filepath_raw / .file_format way as well, but it turned out to not actually write the data in the expected format (it used the source format with target format's extension).

Note that save_render() does not render anything, it is called ..._render because it uses the render settings of the current scene.

import bpy

img = bpy.data.images[0] # pick an image datablock
filepath = r"C:\tmp\_exported_image.tif" # specify outout filepath here

# Store current render settings
settings = bpy.context.scene.render.image_settings
format = settings.file_format
mode = settings.color_mode
depth = settings.color_depth

# Change render settings to our target format
settings.file_format = 'TIFF'
settings.color_mode = 'RGBA'
settings.color_depth = '8'

# Save image to TIF, this does NOT render anything!
# It only means that the save command will use the current scene's render settings.
img.save_render(filepath)

# Restore previous render settings
settings.file_format = format
settings.color_mode = mode
settings.color_depth = depth
$\endgroup$

You must log in to answer this question.