In this article, we will learn about generating images in C# using ImageMagick.
Let’s dive in.
What is ImageMagick?
ImageMagick is a free and open-source cross-platform library for displaying, creating, converting, modifying, and editing raster images. It is a popular choice for a wide range of image-related tasks, including web development, graphic design, scientific research, medical imaging, and astronomy.
We will use this library to create an image and draw a green circle in the middle of the image.
To start, let’s navigate to the project directory on the terminal to import the ImageMagick NuGet package into our project:
dotnet add package Magick.NET-Q8-AnyCPU
This version of Magick.NET
package has a Quantum Depth of 8 (Q8)
. Thus, it uses 8 bits per channel for color representation. This means that it uses 256 levels of color intensity for each channel (red, green, blue). AnyCPU
implies this package is compiled to be compatible with both 32-bit and 64-bit systems.
We use the Magick.NET-Q8-AnyCPU
NuGet package because it’s a good balance between color precision and memory usage. This is in comparison to the other Magick.NET
packages: Magick.NET-Q16-AnyCPU
and Magick.NET-Q16-HDRI-AnyCPU
.
Creating a Blank Image
Next, let’s create a static ImageService
class in which we define static methods for creating an image, drawing a circle on it, and finally saving the image to a file.
First, let’s define a method to create a blank image:
public static MagickImage CreateBlankImage(int width, int height, MagickColor color) { return new MagickImage(color, width, height); }
In our CreateBlankImage()
method, we create a blank image with a specified width
, height
, and color
using the MagickImage
class from the ImageMagick library. We then return the newly createdMagickImage
object.
Drawing on Images in ImageMagick
Rendering a shape onto an image in ImageMagick is a two-step process. First, we need to define a Drawables
object that we desire to render onto a MagickImage
. Second, using the MagickImage.Draw()
we render the Drawables
object on the image.
Creating Our Drawables Object
So let’s first define a method to create a circle Drawables
:
public static Drawables CreateCircle( int centerX, int centerY, int radius, int strokeWidth, MagickColor strokeColor, MagickColor fillColor) { if (centerX <= 0 || centerY <= 0 || radius <= 0 || strokeWidth <= 0) { throw new ArgumentException( "The values for the circle's center, radius, and stroke width must be greater than zero." ); } var drawables = new Drawables(); drawables.StrokeColor(strokeColor); drawables.FillColor(fillColor); drawables.StrokeWidth(strokeWidth); drawables.Circle(centerX, centerY, centerX, centerY - radius); return drawables; }
The CreateCircle()
method accepts six parameters:
- X and Y coordinates of the circle’s center:
centerX
andcenterY
- The radius of the circle:
radius
- Width of the circle’s outline:
strokeWidth
- Color of the circle’s outline:
strokeColor
- Interior color of the circle:
fillColor
We check and throw an ArguementException
if the int
parameter values are less than or equal to zero.
Next, using the Drawables
class from ImageMagick, we create a drawables
object. We then set the stroke color, fill color, and stroke width of our drawables
object using the respective methods. Lastly, we call the Circle()
method to create a circle using the provided properties. The circle’s center is set at (centerX, centerY)
and the circle extends to (centerX, centerY - radius)
, defining its radius.
Finally, we return drawables
object which represents the circle we desire to render onto a MagickImage
.
Rendering Our Drawables Object
Now that we have a Drawables
object representing the circle we wish to render onto our image, let’s create a new helper method to draw the circle:
public static void DrawOnImage(MagickImage image, Drawables drawables) { image.Draw(drawables); }
Our DrawOnImage()
method takes a MagickImage
and a Drawables
object as parameters.
Then we simply call the image.Draw()
method with our drawables
object as an argument. Draw()
renders the provided drawable object onto the image.
Essentially, we modify the image by superimposing the drawable object onto it.
Saving Images in ImageMagick
We have seen how to both create and modify an image, but all of that would be in vain if we didn’t have a way to actually save the image:
public static void SaveImage(MagickImage image, string outputPath) { image.Write(outputPath, MagickFormat.Png); }
Here we define our SaveImage()
method. We provide both a MagickImage
to save and an outputPath
defining the destination for our saved image.
Next, with image.Write(outputPath, MagickFormat.png)
, we write the image to our specified output path, in our desired png
format.
Putting It All Together
Finally, let’s bring our previously created methods into our Program
class and test them out:
string outputPath = @"outputImage.png"; var image = ImageService.CreateBlankImage(480, 300, MagickColors.AliceBlue); var strokeColor = MagickColors.YellowGreen; var fillColor = MagickColors.Transparent; var circle = ImageService.CreateCircle(image.Width / 2, image.Height / 2, 100, 5, strokeColor, fillColor); ImageService.DrawOnImage(image, circle); ImageService.SaveImage(image, outputPath); Console.WriteLine("Image generated and saved successfully.");
First, we define the path where our generated image outputImage.png
will be saved.
Next, we create a blank image with a width of 480 pixels and a height of 300 pixels. We set the fill color to MagickColors.AliceBlue
using one of the predefined colors from the MagickColors
class. MagickColors
is a class within the ImageMagick library that provides predefined color objects.
As we prepare to draw our circle, we again use the MagickColors
class to define our strokeColor
as YellowGreen
and our fillColor
as Transparent
.
Next, we call our CreateCircle()
static method to generate a circle. We perform a simple calculation to place the circle at the center of our image and set the radius
to 100 pixels. We set the strokeWidth
at 5, and finally pass in our previously defined strokeColor
and fillColor
values.
With our circle
created, we invoke our DrawOnImage()
method to complete our image generation and modification.
Finally, we save our modified image to our earlier defined outputPath
, with an affirmative message printed on the console:
Image generated and saved successfully.
Next, let’s have a look at our image:
Conclusion
In this article, we have looked at generating images in C# by using the ImageMagick library.