TASImage doesn't export *.png file with alpha channel

I am using TASImage to produce images that I am then using in a deep-learning context. For this, I am storing information in the alpha channel using the TASImage::GetArgbArray() function and using std::memcpy to copy an equally sized array to this address.

I then use the TASImage::WriteImage to save this data in PNG images. However, if I use the pngcheck tool on one of these images, I get back something like the following:

OK: 1818373647206787957741394541112858493011.png (123x123, 24-bit RGB, non-interlaced, 99.6%).

This doesn’t include the alpha channel, and so I have lost a channel of data that I need.

Does anyone know how I can fix this issue?

Can you provide a small example reproducing this problem ?

Sure:

constexpr UInt_t imageHeight = 12;
constexpr UInt_t imageWidth = 12;
union {
    UInt_t imageData[imageHeight][imageWidth];
    unsigned char channelData[imageHeight][imageWidth][4];
};

std::memset(imageData, 0, sizeof(imageData));

static_assert(sizeof(imageData) == sizeof(channelData), "imageData must have the same  raw size as channelData");

for (auto y = 0U; y < imageHeight; ++y)
{
    for (auto x = 0U; x < imageWidth; ++x)
    {
         channelData[y][x][0] = static_cast<unsigned char>(rand() % 255);
    }
}

TASImage image( imageWidth, imageHeight );
image.SetImageQuality(TAttImage::kImgBest);
image.SetImageCompression(100);
std::memcpy(image.GetArgbArray(), *imageData, sizeof(imageData));

image.WriteImage("test.png");

If I then run pngcheck test.png, I get the following:

OK: test.png (12x12, 24-bit RGB, non-interlaced, 0.9%).

Again, only a 24-bit image, the alpha channel is missing!

you mean pngcheck I guess…

Yes, sorry! I’ve corrected that in the original post now.

I managed to install pngcheck on may Mac and I get:

$ pngcheck test.png 
OK: test.png (12x12, 24-bit RGB, non-interlaced, 24.5%).

I will check

I have generated a png picture with root containing some transparency (sol phs channel is on I guess), and I get:

$ pngcheck c1.png 
OK: c1.png (696x499, 24-bit RGB, non-interlaced, 99.7%).

Seems to be the same … I have no idea what to do …
I know transparency is working in png root images and that’s we are looking for.

Are you saying that if you use TASImage::Open it will correctly retrieve the alpha channel?

I have tried to open the image using the PIL library for Python and it tells me it only has RGB layers too, perhaps there is a strange formatting issue in libAfterImage?

I think a workaround will be to save the alpha channel separately perhaps?

I am saying that if I generate an image with transparency using ROOT and save it as a png file then the transparency works.

{
   TCanvas *c1 = new TCanvas("c1", "c1",10,45,700,527);

   TEllipse *ellipse = new TEllipse(0.4326648,0.5926316,0.1561605,0.1105263,0,360,0);
   ellipse->SetFillColor(2);
   ellipse->Draw();

   ellipse = new TEllipse(0.4032951,0.6,0.0508596,0.2884211,0,360,0);

   Int_t ci;      // for color index setting
   TColor *color; // for color definition with alpha
   ci = 1180;
   color = new TColor(ci, 0.52, 0.76, 0.64, " ", 0.63);
   ellipse->SetFillColor(ci);
   ellipse->Draw();

}

For me, even on the TCanvas, there is no transparancy. The red ellipse is strictly behind the green one and there is no change in colour in the green ellipse where the red ellipse is behind it.

Could you run the following for me, and let me know what the output is?

include "TROOT.h"
#include "TASImage.h"

#include <iostream>
#include <iomanip>
#include <set>

void imageTest()
{
    TASImage* image = static_cast<TASImage*>(TASImage::Open("test.png"));

    if (!image)
    {
        std::cerr << "Unable to open \"test.png\"" << std::endl;
        return;
    }

    TCanvas* canvas = new TCanvas("canvas", "Image Canvas", image->GetWidth(), image->GetHeight());

    image->Draw();

    // Check the image for any alpha transparancy:
    UInt_t* argbArray = image->GetArgbArray();
    unsigned char* channelArray = reinterpret_cast<unsigned char*>(argbArray);

    std::set<unsigned char> uniqueValues;
    for (std::size_t i = 0U; i < 4 * image->GetHeight() * image->GetWidth(); i += 4U)
    {
        uniqueValues.emplace( channelArray[i] );
    }

    std::cout << uniqueValues.size() << " unique alpha channel values found!\n\n";

    for (auto value : uniqueValues)
    {
        std::cout << static_cast<UInt_t>(value) << '\n';
    }
    std::cout << std::flush;
}

For me, this gives me a single unique alpha channel value, 255. Which suggests that the png file does indeed not have an alpha channel (so the libAfterImage library assumes that it is fully opaque).

When I run the macro I sent you I get the following image. You can see it has transparency. Which root version are you using ? on which machine ? try to run in batch mode. Transparency does not work with X11.

Interesting, that’s very different to my image:

I’m running on my local machine, running Ubuntu 16.04. I’m using ROOT version 6.08/00. However, my initial issue was generated whilst using ROOT 5.34.21 and Ubuntu 14.04. However, I do recover the same image as you if I run in batch mode.

However, if I rerun my previous macro in batch mode where I actively manipulate the alpha channel and then reload it using the other macro I posted, I find that there is still no alpha channel. And this appears to be the case regardless of the format that I save the image in.

Yes as i said you should run in batch mode to have the transparency. I am not sure how TAsimage generated transparency. May be it does it without using the alpha channel in png.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.