SirTony
10/7/2014 - 2:26 PM

A simple tool to convert an input image to a different format.

A simple tool to convert an input image to a different format.

//Compile with: csc /nologo /r:System.Drawing.dll imgconv.cs

using System;
using System.IO;
using System.Drawing;
using System.Reflection;
using System.Drawing.Imaging;

static class Program
{
    private static void Main( string[] args )
    {
        if( args.Length < 3 )
        {
            Console.WriteLine( @"Usage:
    imgconv <source image file> <target image file> <target format> [quality]" );

            return;
        }

        bool success;
        string source = args[0];
        string target = args[1];
        ImageFormat format = GetFormatByName( args[2] );

        if( format == null )
        {
            Console.Error.WriteLine( "Unknown image format '{0}'.", args[2] );
            Environment.Exit( 1 );
            return;
        }

        if( !File.Exists( source ) )
        {
            Console.Error.WriteLine( "Cannot find input file." );
            Environment.Exit( 2 );
            return;
        }

        int quality = 0;

        if( args.Length >= 4 )
        {
            success = Int32.TryParse( args[3], out quality ) && quality <= 100 && quality >= 0;

            if( !success )
                quality = 75;

            if( format == ImageFormat.Jpeg )
            {
                if( !success )
                    Console.Error.WriteLine( "Warning: invalid value supplied to [quality], defaulting to 75." );
            }
            else
            {
                Console.Error.WriteLine( "Warning: Quality only valid for JPEG targets, ignoring." );
            }
        }

        if( File.Exists( target ) )
        {
            Console.Out.WriteLine( "Warning: destination file already exists, overwrite? [Y/n] " );
            bool overwrite = Char.ToLower( Console.ReadKey().KeyChar ) == 'y';

            if( !overwrite )
            {
                Environment.Exit( 3 );
                return;
            }
        }

        Image img;
        success = Try( () => Image.FromFile( source ), out img );

        if( !success )
        {
            Console.Error.WriteLine( "Error loading source image file." );
            Environment.Exit( 4 );
            return;
        }

        Action save = delegate()
        {
            if( format == ImageFormat.Jpeg )
                SaveJpegWithQuality( img, target, quality );
            else
                img.Save( target, format );
        };

        if( !Try( save ) )
        {
            Console.Error.WriteLine( "Error saving target image." );
            Environment.Exit( 5 );
            return;
        }

        Console.Out.WriteLine( "Successfully saved target image." );
    }

    private static bool Try( Action callable )
    {
        try
        {
            callable();
            return true;
        }
        catch
        {
            return false;
        }
    }

    private static bool Try<T>( Func<T> callable, out T result )
    {
        try
        {
            result = callable();
            return true;
        }
        catch
        {
            result = default( T );
            return false;
        }
    }

    private static ImageFormat GetFormatByName( string name )
    {
        Type type = typeof( ImageFormat );
        PropertyInfo prop = type.GetProperty( name, BindingFlags.Public | BindingFlags.Static | BindingFlags.IgnoreCase );

        if( prop == null )
            return null;

        return prop.GetValue( null ) as ImageFormat;
    }

    private static void SaveJpegWithQuality( Image img, string path, int quality )
    {
        ImageCodecInfo encoder = GetJpegCodec();

        if( encoder == null )
            img.Save( path, ImageFormat.Jpeg );
        else
        {
            EncoderParameters @params = new EncoderParameters( 1 );
            EncoderParameter qualityParam = new EncoderParameter( Encoder.Quality, (long)quality );
            @params.Param[0] = qualityParam;

            img.Save( path, encoder, @params );
        }
    }

    public static ImageCodecInfo GetJpegCodec()
    {
        ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();

        foreach( ImageCodecInfo codec in codecs )
        {
            if( codec.FormatID == ImageFormat.Jpeg.Guid )
                return codec;
        }

        return null;
    }
}