Is there a way to validate the transparency of an image using ImageSharp?

1.4k Views Asked by At

We have a requirement that aside from client side validation, we also need to validate the transparency of the uploaded image in MVC controller. We know we can do this using the System.Drawing library but, we're moving away from System.Drawing due to performance issues and we're also targeting to deploy our application into cloud that has no GDI support. Is there a way that we can validate the transparency of the uploaded image using Imagesharp. Thanks.

1

There are 1 best solutions below

4
On

This is an interesting question with some slight ambiguity. I don't know whether your want to check for the potential of transparent pixels or whether there actually are transparent pixels in the image. Each scenario requires very different behavior.

Scenario 1: Test for Potential Transparency

To do this you'll want to query the metadata.

The Image type and it's generic variant contain a property called Metadata which is of type ImageMetadata. You can query this type for format specific metadata.

For example. If you wanted to query png metadata, you would use

// Get the metadata. Using Identity allows this without fully
// decoding the image pixel data.
using var info = Image.Identify(...);

PngMetadata meta = info.Metadata.GetPngMetadata();

// Query the color type to get color information.
PngColorType = meta.ColorType;

The PngColorType can actually support an alpha component for every entry.

  • GrayscaleWithAlpha
  • Grayscale *
  • RgbWithAlpha
  • Rgba *
  • Palette *

(*) Only transparent if PngMetadata.HasTransparency is true.

Scenario 2: Test for Actual Transparency

To do this you'll need to fully decode the image into a pixel format that supports transparency.

using var image = Image<Rgba32>.Load(...);

for (int y = 0; y < image.Height; y++)
{
    // It's faster to get the row and avoid a per-pixel multiplication using
    // the image[x, y] indexer
    Span<Rgba32> row = image.GetPixelRowSpan(y);
    for (int x = 0; x < row.Length; x++)
    {
        Rgba32 pixel = row[x];

        if (pixel.A < byte.MaxValue) 
        {
            // return true. 
        }
    }
}

Both approaches should be fast enough depending on your scenario.