← All ideas
  • Published 21 Sep 2019

Image Format Add-ons

My proposal is to add the ability for users to create Python add-ons that load custom image formats "natively" within Blender.

Motivation

Working with non-standard or proprietary image formats within Blender (of which there are countless) is a pain, requiring the user to convert the images to more common formats outside of Blender before working with them.

Though it's currently possible to write an operator to load an image of a custom format, the loaded image isn't treated as a "first-class" image because it:

  • Cannot be natively reloaded from its the source file
  • Cannot natively save the image in its original format

Being able to treat custom image formats as first-class images would allow a much smoother and natural workflow, as well as enabling the community to provide support for new and emerging formats.

API

Adding a new file format should be as simple as possible, with the user needing only to provide a few key methods (mirroring the existing requirements for ImFileType struct).

I propose a new bpy.types.ImageFormat class with stub methods to be filled out by the user ( load_bytes , save etc.). The Python interface would look something like this (not an exhaustive implementation):

(Apologies for the wacky formatting, this site doesn't like indentation apparently).

class FOOBAR_IF_MyImageFormat(bpy.types.ImageFormat):
        bl_name = None  # Name of file format (eg. WebP)
        bl_description = None   # Brief description of format (eg. WebP Image)
    bl_extensions = []  # List of extensions (eg. ['.webp'])
    bl_default_role = None  # The color role default (either `byte` or `float`)
    
    @classmethod
    def init(cls):
    	'''
    	Initialization logic, if needed.
    	'''
    	pass
    
    @classmethod
    def exit(cls):
    	'''
    	Tear-down logic, if needed.
    	'''
    	pass

    @classmethod
    def is_a_bytes(cls, bytes: bytes) -> bool:
    	'''
    	Returns True if the bytes indicate they are of this image
    	format type (eg. checking FourCC).
    	'''
        return False
    
    @classmethod
    def is_a_filename(cls, filepath: str) -> bool:
    	'''
    	Returns True if the file path indicates that it is
    	of this image format type (eg. checking file extension).
    	'''
        return False

    @classmethod
    def load_bytes(cls, bytes: bytes, flags: int, colorspace: imbuf.ColorSpace) -> ImBuf:
        '''
        Returns a new ImBuf instance given a byte array.
        If an error occurs, raise an Exception.
        '''
        raise NotImplementedError()
       
    @classmethod
    def load_filepath(cls, filepath: str, flags: int, colorspace: imbuf.ColorSpace): -> ImBuf:
    	'''
    	Returns a new ImBuf instance given a filepath.
    	If an error occurs, raise an Exception.
    	'''
        raise NotImplementedError()
    
    @classmethod
    def load_tile(cls, imbuf: ImBuf, bytes: bytes, tile: Tuple[int], bytes: bytearray):
    	'''
    	Loads a tile from the image buffer.
    	'''
    	raise NotImplementedError()

    @classmethod
    def save(cls, imbuf: ImBuf, filepath: str, flags: int):
    	'''
    	Saves an image to the given file path.
    	'''
    	raise NotImplementedError()

Registering the image format add-on can be done the same way other add-ons (eg. operators) are already registered currently (note the IF acronym (for "Image Format").

# Register
bpy.utils.register_class(FOOBAR_IF_MyImageFormat)

# Unregister
bpy.utils.unregister_class(FOOBAR_IF_MyImageFormat)

Technical Notes

  • Some additional work will be required to get started. For example, the relatively new imbuf module would need to have its Python bridge extended to allow for key bits of functionality to be exposed (eg. I/O of pixel data, color space information etc.)
  • Currently, the image file types are listed out in the IMB_FILE_TYPES static-array, which is immutable. This will need to be changed to a dynamic array so that new file formats can be registered and unregistered at run-time.
  • File types are stored in hard-coded enumerations throughout the code (eg. emImbTypes , R_IMF_IMTYPE_PNG ). These values are stored in DNA data, so a forward compatible solution will need to be devised to account for this. For example, a new R_IMF_IMTYPE_ADDON could be added to indicate that the file type is associated with an add-on. There may be issues with that approach, but I might need some input from someone more familiar with the systems in play.

Comments?

I'm looking for input before I begin; any showstoppers I might be missing etc. Thank you for your time.

96.2%

Development Status: In Development

Upvote 25 Downvote 1
cmbasnett
21 Sep 2019

4 Comments

Josephbburg

I often dream of using KRITA images natively in Blender, with layers.

6

Just curious why not using multi channel EXR format? It goes up to 32bit

1
cmbasnett Author

This comment is missing the point.

There are loads of image formats outside of the ones that Blender supports that are domain specific . For example, video games, GIS systems etc. all use specialized image formats that are not supported by Blender. If you want to use them in Blender, you need to convert them to a supported format before importing. Allowing users to make their own addons for supporting different image types is the only way to accomplish what is described above.

Kenzie

Awesome idea!

1