1
$\begingroup$

Just after hours of finding what is wrong, i have found that RGB channels are multiplied by alpha channel during output to PNG (and other RGBA supported formats), actually each channel is divided by alpha. Was trying to neutralize this by multiplying on alpha by math nodes but without success.

Is there any working method to store RGBA as it was transferred from the "Combine RGBA" node to the "File Output" node ? ie straight but not multiplied ?

PS. Just encode into the 4 channels very different information, like in B - Quantizing into 1 byte Thanks for the help !

$\endgroup$
1
$\begingroup$

Just found a workaround.

The idea is to output to OpenEXR file format, where all channels are stored as is. Then post process it by another program to output PNG.

I've used https://github.com/Enichan/sharpexr library (MIT License) with the following C# code:

using System;
using SharpEXR;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;

namespace EXR2PNG
{
    class Program
    {
        static void Main(string[] args)
        {
            if (args.Length != 2)
            {
                Help();
                return;
            }
            var img = EXRFile.FromFile(args[0]);
            var part = img.Parts[0];
            part.OpenParallel(args[0]);

            var bmp = new Bitmap(part.DataWindow.Width, part.DataWindow.Height);
            var data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
            var destBytes = part.GetBytes(ImageDestFormat.BGRA8, GammaEncoding.Linear, data.Stride);
            Marshal.Copy(destBytes, 0, data.Scan0, destBytes.Length);
            bmp.UnlockBits(data);
            bmp.Save(args[1], ImageFormat.Png);
        }
        static void Help()
        {
            Console.WriteLine("Usage:\r\n\tEXP2PNG [SourceEXRFilePath] [TargetPNGFilePath");
        }
    }
}

Actually is not a solution to make it with the Blender directly, so i don't mark it as answer.

Please note, if you are going to use this code with sharpexr library, you must out OpenEXR file with RGBA, Color Depth set as Float (Half) and Codec as None, because the library doesn't support compression and seems Float (Full).

enter image description here

EDIT: Here is a PowerShell script to process multiple frames

Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope CurrentUser
cd c:\Projects\GinaGame\ArtWork\Images\cube 

dir *.exr | ForEach-Object {c:\Projects\sharpexr\EXR2PNG\bin\Release\EXR2PNG.exe $_.Name ($_.Name+'.png')}
$\endgroup$
  • 1
    $\begingroup$ You very likely don't want this. Only associated (premultiplied) alpha can represent occlusion and emission correctly. OpenEXR by convention, will be associated alpha. This is at least one of the prime reasons why PNG has never been adopted in visual effects pipelines. $\endgroup$ – troy_s Mar 1 '18 at 2:25
  • $\begingroup$ @troy_s The original idea is to encode other info into channels, not just RGBA, say as here my original question where RG - (XY offset), B - index in platte, A - as Alpha $\endgroup$ – Oleg Skripnyak Mar 1 '18 at 12:40
  • $\begingroup$ You already found the right format in EXR then. You can store an arbitrary number of data channels in an EXR. No need to abuse an alpha channel. $\endgroup$ – troy_s Mar 1 '18 at 14:44
  • $\begingroup$ @troy_s Sure, don't worry $\endgroup$ – Oleg Skripnyak Mar 2 '18 at 21:52
  • $\begingroup$ Thank you for sharing this, even if it slightly deviates from the question. $\endgroup$ – Leander Jun 24 '18 at 10:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.