EXR Swizzle on Save or Load?

Hi guys,
I’ve been having troubles with EXR IO in Cinder. It seems like either EXR saving, or loading, is swizzling channels.

Using asakusa.exr from the TinyEXR github as a test case, I can load just fine via loadImage:

mTex = gl::Texture2d::create(loadImage(getAssetPath(“asakusa.exr”)));

Rendering this just through gl::draw(img) shows as expected([please refer to the github source, i can only post one image as a new user):

Now, if I save this loaded texture (“mTex”) through:
writeImage("C:\OutputEXR.exr", mTex->createSource(), cinder::ImageTarget::Options(), "exr");

And load this EXR file as above:
mTex = gl::Texture2d::create(loadImage(getAssetPath(“C:\OutputEXR.exr”)));

Then what I see in the same draw method, becomes:

This is definitely swizzled.

I’m unsure where the swizzling is happening - I am assuming on Load, as the same “OutputEXR.exr” file I just created, previews perfectly fine in Photoshop & Blender, suggesting the data is absolutely fine, but just how it’s imported is getting changed.

I took a look but couldn’t figure out how to fix this, so I was hoping anyone else had an idea? It seems consistent and works with image loading/saving via EXR, on files with Alpha and no Alpha.

Yea that doesn’t seem right. Mind opening an issue on the github tracker? Also stepping through the ImageSourceFileTinyExr::load() method might tell how the channels are being assigned.

But if the data is loaded and displayed correctly from the original, but not your from your saved exr, wouldn’t that indicate there is a problem in the saving (btw that is done here)?


Channel names is set to GBR here. While channel order seems to be BGR here.

According to tinyexr, most readers expect the channel order to be BGR/BGRA. So, we should probably fix the channel names.


Hi guys,
thats great, thanks. I tried a local change, changing the following lines [202-206] in ImageFileTinyExr.cpp to:

setChannelOrder( ( mNumComponents == 3 ) ? ImageIo::ChannelOrder::BGR : ImageIo::ChannelOrder::ABGR );
if( mNumComponents == 3 )
	mChannelNames = { "B", "G", "R" };
	mChannelNames = { "A", "B", "G", "R" };`

Seems to have fixed it.
I think the other packages may have been doing some convenience-swizzling and thus threw me off with some false results.

Hm, thanks for investigating. I agree that we should write as BGR / ABGR by default, but also we should still be able to read GBR / AGBR, and the code here should handle it. Hey if Photoshop can do it, we should be able to too. :slight_smile: I’ve been stepping through but don’t yet see why the color channels are getting swizzled…

Also, I’m not sure why the original asakusa.exr shows in OS X Finder as having 3 channels but loads with tinyexr as 4 channels. That might not be anything but it does seem like a waste of memory.

If any hi-def users out there would like to tackle these issues and open PRs it would be most welcome, I know both @andrewfb and myself, who wrote the original tinyexr wrapper, are a bit busy right now wrapping up some things for the next release…

Edit: I’ve created an issue here for tracking.