In C#, we can do a lot of image operations using which one can easily manipulate images and use them in their projects. The post is divided in 6 sections with each section with their respective codes answering questions asked to me many time before and apparently people are still looking for them:

1. Image conversion

a. Converting a image to byte array – in various scenarios you’ll come across this situation where you would require to convert an image into a byte [] so that you can store it into the database or transmit the image over the web. It can be done like follows:


public static Byte[] ConvertImageToByteArray(Bitmap image)
{
	var ic = new ImageConverter();
    return ic.ConvertTo(image, typeof(byte[])) as byte[];
}

The same thing can be done using Memory Stream as follows:


public byte[] ImageToByteArray(Image imageIn)
{
   var ms = new MemoryStream();
   imageIn.Save(ms, ImageFormat.Bmp);
   return ms.ToArray();
}

b. Converting a byte array t0 Image – similar to the above situation, you would like to convert a byte [] that you obtained from the database (or any other source) into an image object. You can do it like below:


public static Bitmap ConvertByteArrayToImage(byte[] byteArray)
{
    var ic = new ImageConverter();
    var img = (Image)ic.ConvertFrom(byteArray);
    return new Bitmap(img);
}

Using Memory Stream it can be done as follows:


public Image ByteArrayToImage(byte[] byteArrayIn)
{
    var ms = new MemoryStream(byteArrayIn);
	var returnImage = Image.FromStream(ms);
    return returnImage;
}

2. Creating an Image from Text

Yes, this is possible via code J, its somewhat like creating a captcha that is used by many site for security purpose. The code to it is:


public static Bitmap CreateBitmapImageFromText(string sImageText, int width, int height)
{
	var objBmpImage = new Bitmap(width, height);

	// Create the Font object for the image text drawing.
	var objFont = new Font("Arial", 40, FontStyle.Bold, GraphicsUnit.Pixel);

	// Create a graphics object to measure the text's width and height.
	Graphics objGraphics = Graphics.FromImage(objBmpImage);

	// This is where the bitmap size is determined.
	var intWidth = (int)objGraphics.MeasureString(sImageText, objFont).Width;
	var intHeight = (int)objGraphics.MeasureString(sImageText, objFont).Height;

	// Create the bmpImage again with the correct size for the text and font.
	objBmpImage = new Bitmap(objBmpImage, new Size(intWidth, intHeight));

    // Add the colors to the new bitmap.
	objGraphics = Graphics.FromImage(objBmpImage);

	// Set Background color
	objGraphics.Clear(Color.Black);
	objGraphics.SmoothingMode = SmoothingMode.AntiAlias;
	objGraphics.TextRenderingHint = TextRenderingHint.AntiAlias;
	objGraphics.DrawString(sImageText, objFont, new SolidBrush(Color.White), 0, 0);
	objGraphics.Flush();
	return (objBmpImage);

}

3. Getting an Image from a Url

If you wish to download an image from any given url and convert into an image object, you can do so as follows:


public static Image GetImageFromURL(string strURL)
{
	Image retVal;
	
	try
	{
		var request = (HttpWebRequest)WebRequest.Create(strURL);
		request.Timeout = 60000; // 5 seconds in milliseconds
		request.ReadWriteTimeout = 20000; // allow up to 20 seconds to elapse

		// execute the request
		var response = (HttpWebResponse)request.GetResponse();
		retVal = Image.FromStream(response.GetResponseStream());
	}
	catch (Exception)
	{
		retVal = null;
	}

	return retVal;
}

4. Getting thumbnail of a word document

If you require using a thumbnail of word document you can do that too. The code I mentioned below uses Open Xml and to be able to use it, follow the below steps:

  • Download and install the Open Xml SDK 2.0.
  • In your project, add reference to “DocumentFormat.OpenXml” and “WindowsBase”.
  • Add this statement at the top of the file “using DocumentFormat.OpenXml.Packaging;”

Now you can use the following code:


public Image GetDocThumnail(string docFilePath)
{
	var wordprocessingDocument = WordprocessingDocument.Open(docFilePath, false);
	var thumbnailPart = wordprocessingDocument.ThumbnailPart;
	if (thumbnailPart != null)
	{
		var stream = thumbnailPart.GetStream(FileMode.Open, FileAccess.Read);
		var byteArr = ReadAllBytes(stream);
		return ByteArrayToImage(byteArr);               
	}
	
	return null;
}

public static byte[] ReadAllBytes(Stream source)
{
	var originalPosition = source.Position;
	source.Position = 0;

	try
	{
		var readBuffer = new byte[4096];
		var totalBytesRead = 0;
		int bytesRead;

		while ((bytesRead = source.Read(readBuffer, totalBytesRead, readBuffer.Length - totalBytesRead)) > 0)
	    {
			totalBytesRead += bytesRead;
			if (totalBytesRead != readBuffer.Length) continue;

		    var nextByte = source.ReadByte();
			if (nextByte == -1) continue;

			var temp = new byte[readBuffer.Length * 2];
			System.Buffer.BlockCopy(readBuffer, 0, temp, 0, readBuffer.Length);
			System.Buffer.SetByte(temp, totalBytesRead, (byte)nextByte);
			readBuffer = temp;
			totalBytesRead++;

		}

	    var buffer = readBuffer;
	    if (readBuffer.Length == totalBytesRead) return buffer;

		buffer = new byte[totalBytesRead];
		System.Buffer.BlockCopy(readBuffer, 0, buffer, 0, totalBytesRead);
		return buffer;

	}
	finally
	{
		source.Position = originalPosition;
	}
}

Please note that a method named “ByteArrayToImage” is used, this has been already defined in the first section i.e. Image Conversion (you can copy it from there).

5. Combining two images

In a scenario where you would like to combine two images either horizontally or vertically, you can do so by using 2 or more bitmap images as follows:

a. Combining images vertically


public static Bitmap CombineVertically(Bitmap[] files)
{
	//read all images into memory
	var images = new List<Bitmap>();
	Bitmap finalImage = null;

	try
	{
		int width = 0;
		int height = 0;
		
		foreach (Bitmap image in files)
		{
			//create a Bitmap from the file and add it to the list
			Bitmap bitmap = image;

			//update the size of the final bitmap
			width = bitmap.Width > width ? bitmap.Width : width;
			height += bitmap.Height;
			images.Add(bitmap);
		}

		//create a bitmap to hold the combined image
		finalImage = new Bitmap(width, height);

		//get a graphics object from the image so we can draw on it
		using (Graphics g = Graphics.FromImage(finalImage))
		{
			//set background color
			g.Clear(Color.Black);

		    //go through each image and draw it on the final image
			int offset = 0;

			foreach (Bitmap image in images)
			{
				g.DrawImage(image, new Rectangle(0, offset, image.Width, image.Height));
				offset += image.Height;
			}
		}

		return finalImage;
	}
	catch (Exception)
	{
		if (finalImage != null)
			finalImage.Dispose();

		throw;
	}
	finally
	{
		//clean up memory
		foreach (Bitmap image in images)
		{
			image.Dispose();
		}
	}
}

b. Combining images horizontally


public static Bitmap CombineHorizontally(Bitmap[] files, int[,] dimentions, int[,] finalImageDimentions)
{
	//read all images into memory
	var images = new List<Bitmap>();

	Bitmap finalImage = null;

	try
	{
		int width = 0;
		int height = 0;

		foreach (Bitmap image in files)
		{
			//create a Bitmap from the file and add it to the list
			Bitmap bitmap = image;

		    //update the size of the final bitmap
			width += bitmap.Width;
			height = bitmap.Height;
			images.Add(bitmap);
		}

		//create a bitmap to hold the combined image
		finalImage = new Bitmap(finalImageDimentions[0, 0], finalImageDimentions[0, 1]);

		//get a graphics object from the image so we can draw on it
		using (Graphics g = Graphics.FromImage(finalImage))
		{
			//set background color
			g.Clear(Color.Black);

			//go through each image and draw it on the final image
			int offset = 0;
			
			foreach (Bitmap image in images)
			{
				if (offset == 0)
				{
					int titleimageSpaceWidthCenter = dimentions[0, 0] / 2;
					int titleimageoffset = titleimageSpaceWidthCenter - image.Width / 2;
					g.DrawImage(image, new Rectangle(titleimageoffset, 0, image.Width, image.Height));
					offset += dimentions[0, 0];
				}
				else
				{
					int i = dimentions[0, 1] / 2;
					g.DrawImage(image, new Rectangle(offset, i, dimentions[1, 0], dimentions[1, 1]));
					offset += dimentions[1, 0];
				}
			}
		}

	   return finalImage;
	}
	catch (Exception)
	{
		if (finalImage != null)
			finalImage.Dispose();
		
		throw;
	}
	finally
	{
		//clean up memory
		foreach (Bitmap image in images)
			image.Dispose();
	}
}

6. Resizing an image while maintaining the aspect ratio and maximum width & height

This use case I came across just while writing this blog and believe me, it’s one of the most required codes that I have come across. It’s almost like resizing an image using Photoshop and without losing any quality at all. The method resizes a given image in such a way that the dimensions of the image are contained inside the maxWidth and maxHeight values.


public static Bitmap ResizeImage(Bitmap fullsizeImage, int maxWidth, int maxHeight)
{
	// Prevent using images internal thumbnail
	fullsizeImage.RotateFlip(RotateFlipType.Rotate180FlipNone);
	fullsizeImage.RotateFlip(RotateFlipType.Rotate180FlipNone);

    int imageWidth;
	int imageHeight;

	var newWidth = maxHeight*fullsizeImage.Width/fullsizeImage.Height;
	if(newWidth > maxWidth)
	{
		imageHeight = fullsizeImage.Height * maxWidth / fullsizeImage.Width;               
		imageWidth = maxWidth;
	}
	else
	{
		imageWidth = newWidth;
		imageHeight = maxHeight;
	}

    Image newImage = fullsizeImage.GetThumbnailImage(imageWidth, imageHeight, null, IntPtr.Zero);
	
	// Clear handle to original file so that we can overwrite it if necessary
	fullsizeImage.Dispose();

	// Return resized picture
	return (Bitmap) newImage;
}

Using the above methods you will be able to do most of the image operations required by you. Just in case something is not clear to you or you need help on a related issue, you can contact me.

Advertisements