2
$\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 Answer 1

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$
6
  • 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
    Commented Mar 1, 2018 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$ Commented Mar 1, 2018 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
    Commented Mar 1, 2018 at 14:44
  • $\begingroup$ @troy_s Sure, don't worry $\endgroup$ Commented Mar 2, 2018 at 21:52
  • 1
    $\begingroup$ Wait, so there's no way to export associated alpha to PNG in Blender? I get completely trashed results when I try that... $\endgroup$
    – unfa
    Commented Oct 25, 2020 at 21:29

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .