Click here to Skip to main content
15,867,704 members
Articles / Programming Languages / C#
Article

Image Format Conversion in .NET

Rate me:
Please Sign up or sign in to vote.
3.35/5 (17 votes)
7 Jul 20025 min read 266.8K   2   64   17
Discusses how to convert image formats in .NET, exemplified by a WebService that converts image formats on the fly!

Introduction

.NET is productive! There's no doubt in that. The framework contains huge number of classes, which encapsulate many of the tasks required by the developer during the course of development. Take for instance, the TCPListener class that has simplified design of a TCP server to few lines of code, from the huge bunch that was written back in the days of Winsock. Another good example is that of working with images, in particular, converting images from one format to another, which is the main focus of this article.

I shall start off by introducing to the classes involved in working with images and their conversion, and show you how that is done. Finally, we build a real-life application: a .NET XML Webservice that shall convert images from one file format to another, on the fly! Next, we shall also have a look at a very simple C# client that shall invoke the webservice and convert images using it. So, without any further delay, lets get started.

Creating and converting image

The very first step in working with images is to create an object of the Image class object, which is present in the System.Drawing namespace. Since converting image file format requires the image to be present as a file, we shall create the Image object using the FromFile static method of the class, as shown below:

C#
Image imgInFile=Image.FromFile(strFileName);

strFileName is the complete path to the image file. Now that we have an Image object ready, the second line of code that converts the image to a specified file format is this:

C#
imgInFile.Save(strOutFileName,ImageFormat.Bmp); 

The first parameter to the Save method is the complete path to the output filename, while the second parameter is an enumeration, defined in System.Drawing.Imaging, that lets you specify the format in which the file should be saved. The above code saves the image as a .BMP file, but there are 8 more image file formats in which the image can be saved.

Now that we have seen what all it takes to convert an image into a different format (which isn't much, right ?), lets have a look at our image format conversion webservice.

Inside WSC_ConvertImage

Here's the code to our image conversion webservice:

C#
<%@ WebService language="C#" class="WSC_ConvertImage" %>
using System;
using System.Web.Services;
using System.Xml.Serialization;
using System.Drawing; // for Image class
using System.Drawing.Imaging; // for ImageFormat class
using System.IO; // for FileStream class
public class WSC_ConvertImage : WebService {
    [WebMethod]
    public bool ConvertImage(byte[] bytInFile, int intToFormat, 
         out byte[] bytOutFile)
    {
        // has something been sent or not...
        bytOutFile=null;
        if (bytInFile.Length==0)
        {
            // nope.. indicate failure
            return false;
        }

        // Since webservices are stateless, and each webmethod call is
        // indepedent of another, we must have a unique file name for
        // processing each request.
        string strFileName=Server.MapPath(".")+"\\"+
           Guid.NewGuid().ToString();

        // write the byte array sent to us as a file..
        FileStream fsFile=null;
        try
        {
            fsFile=File.Create(strFileName);
        }
        catch
        {
            // unable to create input file..
            return false;
        }

        // write the byte array to it..
        try
        {
            fsFile.Write(bytInFile,0,bytInFile.Length);
        }
        catch
        {
            // unable to write to the file..
            fsFile.Close();
            return false;
        }

        // close the file..
        fsFile.Close();

        // load the image from the file..
        Image imgInFile=Image.FromFile(strFileName);

        // save to the format specified..
        string strOutFileName=strFileName;

        switch(intToFormat)
        {
        case 1: // BMP
            strOutFileName=strOutFileName+".BMP";
            imgInFile.Save(strOutFileName,ImageFormat.Bmp); 
            break;
        case 2: // EXIF
            strOutFileName=strOutFileName+".EXIF";
            imgInFile.Save(strOutFileName,ImageFormat.Exif); 
            break;
        case 3: // EMF
            strOutFileName=strOutFileName+".EMF";
            imgInFile.Save(strOutFileName,ImageFormat.Emf); 
            break;
        case 4: // GIF
            strOutFileName=strOutFileName+".GIF";
            imgInFile.Save(strOutFileName,ImageFormat.Gif); 
            break;
        case 5: // ICO
            strOutFileName=strOutFileName+".ICO";
            imgInFile.Save(strOutFileName,ImageFormat.Icon); 
            break;
        case 6: // JPEG
            strOutFileName=strOutFileName+".JPG";
            imgInFile.Save(strOutFileName,ImageFormat.Jpeg); 
            break;
        case 7: // PNG
            strOutFileName=strOutFileName+".PNG";
            imgInFile.Save(strOutFileName,ImageFormat.Png); 
            break;
        case 8: // TIFF
            strOutFileName=strOutFileName+".TIFF";
            imgInFile.Save(strOutFileName,ImageFormat.Tiff); 
            break;
        case 9: // WMF
            strOutFileName=strOutFileName+".WMF";
            imgInFile.Save(strOutFileName,ImageFormat.Wmf); 
            break;
        default:
            strOutFileName=strOutFileName+".BMP";
            imgInFile.Save(strOutFileName,ImageFormat.Bmp); 
            break;
        }

        // read the output file..
        try
        {
            fsFile=File.Open(strOutFileName,FileMode.Open,FileAccess.Read);
        }
        catch
        {
            // unable to read output file..
            return false;
        }

        // write to the output byte array..
        try
        {
            // create array to read in image file..
            int iSize=Convert.ToInt32(fsFile.Length);
            bytOutFile = new byte[iSize];

            // read the converted image...
            fsFile.Read(bytOutFile,0,iSize);
        }
        catch
        {
            // unable to write to the array..
            fsFile.Close();
            return false;
        }

        // close the file..
        fsFile.Close();

        // delete the created files..
        try
        {
            File.Delete(strFileName);
            File.Delete(strOutFileName);
        }
        catch
        {
            // do nothing..
        }

        return true;
    }
}

Lets follow the top down approach. The code places references to required namespaces, including System.Drawing for using the Image class, System.Drawing.Imaging for using the ImageFormat enumeration, and finally, System.IO for working with files (we will see why, shortly).

Now, since this webservice has to convert an image from one format to another, it must have access to that image, and it will have to return the converted image. There are couple of issues here:

  • The webservice could be located anywhere globally, while the image could be someplace other than the webservice server.
  • We can't transfer files, as such, using webservices.
  • Once the converted image is created on the webservice server, how do we return it to the client? Refer to the second issue.

The single solution, which handles these issues gracefully, is to send the image as an array of bytes, which the webservice processes, and returns the converted image as a byte array. And this is how the ConvertImage web method has been implemented. The first parameter to the method is the byte array of the source image file. The client of the webservice is responsible for creating this byte array. The second parameter specifies the format in which the image is to be converted. Numeric values are used to specify the format, as can be seen from the switch-case construct further down the code. Finally, the third parameter is an out parameter, and is a byte array in which the converted image will be returned, and the webservice client shall create a file out of this byte array. The webmethod returns a boolean to indicate the success of the conversion.

Now that we have discussed the design implications behind the signature of the webmethod, lets understand how the webservice actually works.

How ConvertImage works?

The webmethod starts of by initializing the outbound array to null. Next, it is checked if bytes comprising the image to be converted have been sent or not. Incase not, then false is returned. Otherwise, a unique filename is generated using the NewGuid method of the Guid structure so that each webmethod call has a unique filename for processing the inptu bytes. Incase you don't know, GUIDs are 128bit numbers that are used in COM for specifying various kinds of identifiers, and are almost guaranteed to be unique.

Next, the input bytes are written to the file, created from the unqiue filename generated previosuly, and an Image object is created by loading the image using the FromFile static method. If any exception is thrown, the method returns false. Subsequently, depending upon the kind of conversion specified by the ToFormat parameter, appropriate output filename is generated, by prefixing the relevant image file extension, to the generated input filename. Next, the SaveAs method is called, with the appropriate enumeration value (corresponding to the format in which the image should be converted), and the image conversion takes place.

The final portion deals with opening and reading the output file, and transferring the bytes of the converted image file in the out byte array, that shall be sent back to the client, which will then write to a file. Finally, true is returned if everything has gone fine, to indicate a successful image conversion.

The Client

Now that we have seen how the webservice works, here's a look into a simple client for the webservice:

C#
using System;
using System.IO;
public class TestImage
{
    public static void Main()
    {
        Console.WriteLine("Enter filename: ");
        string strFileName=Console.ReadLine();
        FileStream fs=File.Open(strFileName,FileMode.Open,FileAccess.Read);
        byte[] inByte = new byte[fs.Length];
        fs.Read(inByte,0,inByte.Length);
        fs.Close();

        WSC_ConvertImage wsc = new WSC_ConvertImage();
        byte[] outByte=null;
        if (wsc.ConvertImage(inByte,1,out outByte)==false)
            Console.WriteLine("Covnersion failed");
        else
        {
            fs=File.Create("output.bmp");
            fs.Write(outByte,0,outByte.Length);
            fs.Close();
            Console.WriteLine("Conversion over"); 
        }
    }
}

The client starts of by opening the input file specified in the read mode, and reading its contents in a byte array. Next, it creates an object of the webservice, wsc, and invokes the webmethod. If an error occurs, approprate message is displayed. Otherwise, a file by the name of output.bmp is created (since the client is performing the conversion to BMP format), and the bytes sent out by the webmethod, comprising of the converted image file, are written to the created file. Hence, the conversion takes place.

Conclusion

Its very obvious that webservices carry a lot of punch, especially with what all they can do with the framework's support. This was a very simple exemplification of the future of distributed software services. Hope you felt the power and flexibility.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
United States United States
I hold Early Acheiver in MCSE 2000, MCSE NT 4.0, MCP+I, and actively involved in programming using C/C++, .NET framework, C#, Win32 API, VB, ASP and MFC.

I also have various publications to my credit at MSDN Online Peer Journal, Windows Developer Journal (http://www.wdj.com/), Developer 2.0 (http://www.developer2.com/), and PC Quest (http://www.pcquest.com/).

Comments and Discussions

 
GeneralCertain formats do not work Pin
gggustafson26-May-10 10:34
mvagggustafson26-May-10 10:34 
QuestionHow Can I Have a Cursor File from .Bmp file Pin
Nirav_Vyas1-Feb-09 19:17
Nirav_Vyas1-Feb-09 19:17 
Questionplz help me on C# Pin
todd_yx25-Jul-07 1:00
todd_yx25-Jul-07 1:00 
QuestionHow can i test the client filename? Pin
David Rosa20-Mar-07 7:07
David Rosa20-Mar-07 7:07 
Generalusing System.Drawing; Pin
luisnike1926-May-05 7:48
luisnike1926-May-05 7:48 
GeneralRe: using System.Drawing; Pin
alien25025-Jul-08 2:00
alien25025-Jul-08 2:00 
GeneralDoes this convert Tiff file to multipage jpeg files Pin
Ather Ali Shaikh22-Jul-04 20:09
professionalAther Ali Shaikh22-Jul-04 20:09 
GeneralRe: Does this convert Tiff file to multipage jpeg files Pin
NotProfessional19-Dec-04 17:22
NotProfessional19-Dec-04 17:22 
GeneralRe: Does this convert Tiff file to multipage jpeg files Pin
jpatel3517-Feb-11 16:53
jpatel3517-Feb-11 16:53 
Generalsave emf or wmf Pin
Anonymous18-Jun-04 22:01
Anonymous18-Jun-04 22:01 
GeneralRe: save emf or wmf Pin
rajeshb7929-Nov-04 3:59
rajeshb7929-Nov-04 3:59 
GeneralRe: save emf or wmf Pin
danbenedek9-Mar-07 2:07
danbenedek9-Mar-07 2:07 
GeneralRe: save emf or wmf Pin
Magnus_18-Feb-08 2:08
Magnus_18-Feb-08 2:08 
QuestionWhy not use In memorystream? Pin
Wiiilmaa21-May-03 2:15
Wiiilmaa21-May-03 2:15 
AnswerRe: Why not use In memorystream? Pin
Member 11809492-Feb-04 20:46
Member 11809492-Feb-04 20:46 
GeneralRe: Why not use In memorystream? Pin
Anonymous6-Feb-04 8:35
Anonymous6-Feb-04 8:35 
GeneralRe: Why not use In memorystream? Pin
TaliBuster31-Mar-05 9:17
TaliBuster31-Mar-05 9:17 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.