Search code examples
c#switch-statementimage-formats

Is it possible to use switch to select ImageFormat?


I convert an image from one format to another and want to use the switch to process different formats. System.Drawing.Imaging.ImageFormat is public sealed class and switch doesn't work with it. The below code is working, but I want to use the switch here. Can you help me with some advice?

public static void ConvertImageFormat(Image image, string targetImageFilePath, int newWidth, int newHeight, ImageFormat imageFormatToConvert)
    {
        using (Bitmap bitmap = new Bitmap(image, newWidth, newHeight))
        {
            using (Graphics graphic = Graphics.FromImage(bitmap))
            {
                graphic.InterpolationMode = InterpolationMode.HighQualityBicubic;
                graphic.SmoothingMode = SmoothingMode.HighQuality;
                graphic.CompositingQuality = CompositingQuality.HighQuality;
                graphic.PixelOffsetMode = PixelOffsetMode.HighQuality;

                graphic.DrawImage(image, 0, 0, newWidth, newHeight);

                if (Equals(ImageFormat.Png, imageFormatToConvert))
                {
                    bitmap.Save(targetImageFilePath, ImageFormat.Png);
                }
                else if (Equals(ImageFormat.Gif, imageFormatToConvert))
                {
                    bitmap.Save(targetImageFilePath, ImageFormat.Gif);
                }
                else if (Equals(ImageFormat.Jpeg, imageFormatToConvert))
                {
                    ImageCodecInfo[] arrImageCodecInfo = ImageCodecInfo.GetImageEncoders();
                    using (EncoderParameters encoderParameters = new EncoderParameters(1))
                    {
                        encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, 90L);
                        bitmap.Save(targetImageFilePath, arrImageCodecInfo[1], encoderParameters);
                    }
                }
                else
                {
                    throw new Exception($"Convert to <{imageFormatToConvert.ToString()}> from " +
                                        $"<{new ImageFormatConverter().ConvertToString(image.RawFormat)}>" +
                                        $" image format is not supported now.");
                }
            }
        }
    }

Solution

  • No, you can't use Switch with ImageFormat as it is class.

    In C# 6, the match expression must be an expression that returns a value of the following types:

    a char.
    a string.
    a bool.
    an integral value, such as an int or a long.
    an enum value.
    

    Starting with C# 7, the match expression can be any non-null expression.

    Because C# 6 supports only the constant pattern and does not allow the repetition of constant values, case labels define mutually exclusive values, and only one pattern can match the match expression. As a result, the order in which case statements appear is unimportant.

    In C# 7, however, because other patterns are supported, case labels need not define mutually exclusive values, and multiple patterns can match the match expression. Because only the statements in the switch section that contains the first matching pattern are executed, the order in which case statements appear is now important. If C# detects a switch section whose case statement or statements are equivalent to or are subsets of previous statements, it generates a compiler error, CS8120, "The switch case has already been handled by a previous case."

    switch (C# Reference) MSDN article

    Instead of trying to use Switch I will suggest you to simplify your if else statements to the following:

    if (Equals(ImageFormat.Png, imageFormatToConvert) || Equals(ImageFormat.Gif, imageFormatToConvert) || Equals(ImageFormat.Jpeg, imageFormatToConvert)
    {
        if (Equals(ImageFormat.Jpeg, imageFormatToConvert))
        {
            ImageCodecInfo[] arrImageCodecInfo = ImageCodecInfo.GetImageEncoders();
            using (EncoderParameters encoderParameters = new EncoderParameters(1))
            {
                encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, 90L);
                bitmap.Save(targetImageFilePath, arrImageCodecInfo[1], encoderParameters);
            }
        }
        else{
            bitmap.Save(targetImageFilePath, imageFormatToConvert);
        }
    }
    else
    {
        throw new Exception($"Convert to <{imageFormatToConvert.ToString()}> from " +
                            $"<{new ImageFormatConverter().ConvertToString(image.RawFormat)}>" +
                            $" image format is not supported now.");
    }