c++imagenukeopenexr

OpenEXR RgbaOutputFile is flipped in Nuke


I have been trying to create EXR images from the OpenEXR library but the image is coming into Nuke upside down. The only thing that seems to render the image the way that I expect is DJV.

I am getting a visual file which looks correct ,with the cube toward the bottom of the image and the light on the top edge, in DJV with DECREASING_Y: DJV_EXR

However, when I bring the same image into Nuke it is showing the image upside down, with the cube toward the top of the image and the light on the bottom edge: Nuke_EXR

The same thing seems to happen with Photoshop.

Here is the code that I am using to try to create the image:

RgbaOutputFile file(filename, width, height, WRITE_RGBA, 1, IMATH_NAMESPACE::V2f(0, 0), 1, DECREASING_Y, Imf_2_3::Compression::ZIPS_COMPRESSION);
file.setFrameBuffer(pixels, 1, width);
file.writePixels(height);

I have tried to use both INCREASING_Y and DECREASING_Y as well as using many different compression types. I am not sure what I am missing in this process.

Does anyone know why this would happen? Is there a fix for this?


Solution

  • Was told that the image being flipped in DJV was actually a bug with DJV and is being looked into for the next release: https://github.com/darbyjohnston/DJV/issues/195

    The real issue here was that the image was upside down when read from the RenderTexture.

    The solution that I found was to use a 2D array for loop to flip the pixels in the C++ code before calling the RgbaOutputFile.

    Rgba *flippedPixels = new Rgba[width * height];
    
    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            // Set top scanline of flippedPixels to be bottom scanline of pixels
            flippedPixels[(((height - 1) - i) * width) + j] = pixels[(i * width) + j];
        }
    }
    
    RgbaOutputFile file(filename, width, height, WRITE_RGBA, 1, IMATH_NAMESPACE::V2f(0, 0), 1, INCREASING_Y, Imf_2_3::Compression::ZIPS_COMPRESSION);
    file.setFrameBuffer(flippedPixels, 1, width); // Use flippedPixels instead of pixels
    file.writePixels(height);
    
    delete flippedPixels;