1

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.");
                }
            }
        }
    }
gorkem
  • 731
  • 1
  • 10
  • 17
Nikita Sychou
  • 189
  • 1
  • 11

2 Answers2

0

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.");
}
Samvel Petrosov
  • 7,580
  • 2
  • 22
  • 46
  • Thanks. I read this documentation before ask question, but may be I miss something. UPD: Simplify in such way not good, to my mind, because if you add support [tiff format](https://stackoverflow.com/questions/11668945/convert-tiff-to-jpg-format/11669224#11669224) you need add new else if. – Nikita Sychou Jun 21 '17 at 14:48
  • @NikitaSychou I have written that Code only seeing the code you have provided and there is nowhere written that this cases may be changed. Yes if you add other Formats with their special parts of code off course this code is not simplifying anything. – Samvel Petrosov Jun 21 '17 at 15:02
0

Just ToString() the ImageFormat, and switch on the (string) result?

ImageFormat overrides ToString to yield a "human readable" result. See MSDN.

var desiredImageFormatName = imageFormatToConvert.ToString();

switch (desriredImageFormatName)
{
    case "JPEG": // or whatever ImageFormat.Jpeg.ToString() returns
        ...
}
Gary McGill
  • 26,400
  • 25
  • 118
  • 202
  • 2
    I think that this is not a good solution as if one day `ImageFormat.Jpeg.ToString()` will be changed and instead of `Jpeg` will return `JPEG` his code will stop working – Samvel Petrosov Jun 21 '17 at 14:21
  • @S.Petrosov: Actually, I agree. It would be better *not* to use `ImageFomat` as the parameter type in the first place, and simply use an `enum` or a `string`, which would be easier to `switch` on. I can't see why it would be strictly necessary to use the type for this. – Gary McGill Jun 21 '17 at 14:41
  • I think that OP does not realize the danger of using the switch for this kind of situation and is thinking of how to simplify the code. But as a result even if the switch will be used the code will be very like the one that he already has. – Samvel Petrosov Jun 21 '17 at 14:45
  • @S.Petrosov:Yes, I agree that switch doesn't provide unbelievable simplify the code. Gary McGill, S.Petrosov Thanks to both! – Nikita Sychou Jun 21 '17 at 15:07