This project has moved. For the latest updates, please go here.

Image transparency and opacity issue.

Dec 17, 2014 at 11:00 PM
I'm currently having an issue where the transparent portion of a PNG is turning gray when I adjust the opacity of the image. The following code replicates the issue I'm having in my application:
MagickImage img = new MagickImage(responseStream);

double opacitySetting = Quantum.Max / (Quantum.Max * 0.5);
img.Alpha(AlphaOption.Set);
img.Evaluate(Channels.Alpha, EvaluateOperator.Set, Quantum.Max / opacitySetting);

MagickImage tiles = new MagickImage(new FileInfo("C:\\bar.png"));
MagickImage canvas = new MagickImage(Color.Transparent, tiles.Width, tiles.Height);

canvas.Composite(tiles, Gravity.Center, CompositeOperator.Atop);
canvas.Composite(img, Gravity.Center, CompositeOperator.Atop);

byte[] bytes = canvas.ToByteArray(MagickFormat.Png);
using (Stream fileStream = File.Create("C:\\foo.png"))
{
   fileStream.Write(bytes, 0, bytes.Length);
}
The above produces this image where instead it should look like this (with more transparency in the overlay). Does this have anything to do with this issue?

Thanks in advance for any help!
Coordinator
Dec 18, 2014 at 10:47 AM
That might be related to the other issue. We are having some problems with transparency in ImageMagick 7. We are working on fixing this right now. I will test your code later after that problem has been fixed and get back to you. Can you share a link to your input images so I can reproduce the problem easier? Feel free to contact me trough CodePlex if you don't want to share them publicly.
Coordinator
Dec 22, 2014 at 10:29 PM
Edited Dec 22, 2014 at 10:29 PM
This problem is not related to the other issue. The reason you are seeing the grey pixels is because you are using EvaluateOperator.Set. This will set the alpha to (Quantum.Max / 2) for every pixel, even the pixels that are already fully transparent. You will get the correct result if you use EvaluateOperator.Min. It will set the alpha to at least (Quantum.Max / 2) and that will keep the fully transparent pixels the same. Below is a simplified version of your code.
using (MagickImage img = new MagickImage(responseStream))
{
  double opacitySetting = Quantum.Max / (Quantum.Max * 0.5);
  img.Alpha(AlphaOption.Set);
  img.Evaluate(Channels.Alpha, EvaluateOperator.Min, Quantum.Max / opacitySetting);

  using (MagickImage tiles = new MagickImage("C:\\bar.png")
  {
    tiles.Composite(img, Gravity.Center, CompositeOperator.Atop);
    tiles.Write("C:\\foo.png");
  }
}