Drawing Images using Graphics

Drawing Images using Graphics

With the Aspose.Imaging library you can draw simple shapes like lines, rectangles and circles, as well as complex shapes like polygons, curves, arcs and Bezier shapes. Aspose.Imaging library creates such shapes using Graphics class that resides in the com.aspose.imaging package. Graphics objects are responsible for performing different drawing operations on an image, thus changing the image’s surface. The Graphics class uses a variety of helper objects to enhance the shapes:

  • Pens, to draw lines, outline shapes, or render other geometric representations.
  • Brushes, to define how areas are filled in.
  • Fonts, to define the shape of characters of text.

Drawing with the Graphics Class

Below is a code example demonstrating the use of the Graphics class. The example source code has been split into several parts to keep it simple and easy to follow. Step by step, the examples show how to:

  1. Create an image.
  2. Create and initialize a Graphics object.
  3. Clear the surface.
  4. Draw an ellipse.
  5. Draw a filled polygon and save the image.

Programming Samples

Creating an Image

Start by creating an image using any of the methods described in “Creating Opening and Saving Images”.

Create and Initialize a Graphics Object

Then create and initialize a Graphics object by passing the Image object to its constructor.

Clear the Surface

Clear the Graphics surface by calling the Graphics class clear method and pass a color as a parameter. This method fills the Graphics surface with the color passed in as argument.

Draw an Ellipse

You may notice that the Graphics class has exposed plenty of methods to draw and fill shapes. You’ll find get the complete list of methods in the Aspose.Imaging for Java API Reference. There are several overloaded versions of the drawEllipse method exposed by the Graphics class. All these methods accept a Pen object as its first argument. The later parameters are passed to define the bounding rectangle around the ellipse. For the sake of this example, use the version accepting a Rectangle object as the second parameter to draw an ellipse using the Pen object in your desired color.

Draw a Filled Polygon

Next, draw a polygon using the LinearGradientBrush and an array of points. The Graphics class has exposed several overloaded versions of the fillPolygon method. All of these accept a Brush object as its first argument, defining the characteristics of the fill. The second parameter is an array of points. Please note that every two consecutive points in the array specify a side of the polygon.

Measure string using Aspose.Graphics

Aspose.Imaging Graphics supports method to measure string. Here the sample code for it is provided.

import com.aspose.imaging.Image;
import com.aspose.imaging.Graphics;
try (Image backgoundImage = Image.load("image1.png"))
{
Graphics gr = new Graphics(backgoundImage);
com.aspose.imaging.StringFormat format = new com.aspose.imaging.StringFormat();
com.aspose.imaging.SizeF size = gr.measureString("Test", new com.aspose.imaging.Font("Arial",10), com.aspose.imaging.SizeF.getEmpty(), format);
System.out.println("Size.Width = " + size.getWidth()); // Should be 31.15668f +/- 1.0f
System.out.println("Size.Height = " + size.getHeight()); // Should be 16.5625f +/- 1.0f
}

Drawing Images using Graphics : Complete Source

All classes that implement Closeable interface and access unmanaged resources are instantiated in the try-with-resources or try-finally statements to ensure that they are disposed of correctly.

// The path to the documents directory.
String dataDir = "dataDir/";
//Create an instance of BmpCreateOptions and set its various properties
try (com.aspose.imaging.imageoptions.BmpOptions createOptions = new com.aspose.imaging.imageoptions.BmpOptions())
{
createOptions.setBitsPerPixel(24);
//Create an instance of FileCreateSource and assign it to Source property
createOptions.setSource(new com.aspose.imaging.sources.FileCreateSource(dataDir + "sample.bmp", false));
//Create an instance of Image
try (com.aspose.imaging.Image image = com.aspose.imaging.Image.create(createOptions, 500, 500))
{
//Create and initialize an instance of Graphics
com.aspose.imaging.Graphics graphics = new com.aspose.imaging.Graphics(image);
//Clear the image surface with white color
graphics.clear(Color.getWhite());
//Create and initialize a Pen object with blue color
com.aspose.imaging.Pen pen = new com.aspose.imaging.Pen(com.aspose.imaging.Color.getBlue());
//Draw Ellipse by defining the bounding rectangle of width 150 and height 100
graphics.drawEllipse(pen, new com.aspose.imaging.Rectangle(10, 10, 150, 100));
try (LinearGradientBrush linearGradientBrush = new LinearGradientBrush(image.getBounds(), Color.getRed(), Color.getWhite(), 45f))
{
graphics.fillPolygon(linearGradientBrush, new Point[] { new Point(200, 200), new Point(400, 200), new Point(250, 350) });
}
// Save all changes.
image.save();
}
}

Drawing Text on images using Graphics

Using Aspose.Imaging you can easily draw text on image with text alignment using Graphics.

import com.aspose.imaging.*;
import com.aspose.imaging.brushes.SolidBrush;
import com.aspose.imaging.imageoptions.PngOptions;
import com.aspose.imaging.sources.FileCreateSource;
String templatesFolder = "c:\\Users\\USER\\Downloads\\";
System.out.println("Running example PixelPerfectTextAlignment");
String[] alignments = {"Left", "Center", "Right"};
for (String alignment : alignments)
{
drawString(templatesFolder, alignment);
}
System.out.println("Finished example PixelPerfectTextAlignment");
private static void drawString(String baseFolder, String align)
{
String fileName = "output_" + align + ".png";
String outputFileName = baseFolder + fileName;
String[] fontNames =
{
"Arial", "Times New Roman",
"Bookman Old Style", "Calibri", "Comic Sans MS",
"Courier New", "Microsoft Sans Serif", "Tahoma",
"Verdana", "Proxima Nova Rg"
};
float[] fontSizes = { 10f, 22f, 50f, 100f };
int width = 3000;
int height = 3500;
//Create an instance of PngOptions and set its various properties
try (PngOptions pngOptions = new PngOptions())
{
//Set the Source for PngOptions
pngOptions.setSource(new FileCreateSource(outputFileName));
//Create an instance of Image
try (Image image = Image.create(pngOptions, width, height))
{
//Create and initialize an instance of Graphics class
Graphics graphics = new Graphics(image);
graphics.beginUpdate();
//Clear Graphics surface
graphics.clear(Color.getWhite());
//Create a SolidBrush object and set its various properties
SolidBrush brush = new SolidBrush();
brush.setColor(Color.getBlack());
float x = 10;
int lineX;
float y = 10;
float w = width - 20;
Pen pen = new Pen(Color.getRed(), 1);
int alignment;
switch (align)
{
case "Left":
alignment = StringAlignment.Near;
lineX = Math.round(x);
break;
case "Center":
alignment = StringAlignment.Center;
lineX = Math.round(x + w / 2f);
break;
case "Right":
alignment = StringAlignment.Far;
lineX = (int) (x + w);
break;
default:
throw new IllegalArgumentException("Unknown alignment: " + align);
}
StringFormat stringFormat = new StringFormat(StringFormatFlags.ExactAlignment);
stringFormat.setAlignment(alignment);
for (String fontName : fontNames)
{
for (float fontSize : fontSizes)
{
Font font = new Font(fontName, fontSize);
String text = String.format("This is font: %s, size:%d", fontName, (int) fontSize);
SizeF s = graphics.measureString(text, font, SizeF.getEmpty(), null);
graphics.drawString(text, font, brush, new RectangleF(x, y, w, s.getHeight()), stringFormat);
y += s.getHeight();
}
graphics.drawLine(pen, new Point((int) (x), (int) y), new Point((int) (x + w), (int) y));
}
graphics.drawLine(pen, new Point(lineX, 0), new Point(lineX, (int) y));
// save all changes.
image.save();
}
}
}

Memory Strategy optimization

Graphics operations can be proceeded using memory strategy optimization - i.e. limiting memory buffer size for operation.

final String dataDir = "dataDir/";
final int ImageSize = 2000;
try (ImageOptionsBase createOptions = new PngOptions())
{
createOptions.setSource(new FileCreateSource(dataDir + "temporary.png"));
createOptions.setBufferSizeHint(30); // Memory limit is 30 Mb
try (Image image = Image.create(createOptions, ImageSize, ImageSize))
{
Graphics graphics = new Graphics(image);
// You can use any graphic operations here, all of them will be performed within the established memory limit
// For example:
graphics.clear(Color.getLightSkyBlue());
graphics.drawLine(new Pen(Color.getRed(), 3f), 0, 0, image.getWidth(), image.getHeight());
}
}
// A large number of graphic operations are also supported:
final int OperationAreaSize = 10;
try (ImageOptionsBase createOptions = new PngOptions())
{
createOptions.setSource(new FileCreateSource(dataDir + "temporary.png"));
createOptions.setBufferSizeHint(30); // Memory limit is 30 Mb
try (Image image = Image.create(createOptions, ImageSize, ImageSize))
{
Graphics graphics = new Graphics(image);
graphics.beginUpdate();
graphics.clear(Color.getLightSkyBlue());
int x, y;
for (int column = 0; column * OperationAreaSize < ImageSize; column++)
{
for (int row = 0; row * OperationAreaSize < ImageSize; row++)
{
x = column * OperationAreaSize;
y = row * OperationAreaSize;
boolean reversed = (column + row) % 2 != 0;
if (reversed)
{
graphics.drawLine(
new Pen(Color.getRed()),
x + OperationAreaSize - 2,
y,
x,
y + OperationAreaSize);
}
else
{
graphics.drawLine(
new Pen(Color.getRed()),
x,
y,
x + OperationAreaSize - 2,
y + OperationAreaSize);
}
}
}
// About 40k operations will be applied here, while they do not take up too much memory
// (since they are already unloaded into the external file, and will be loaded from there one at a time)
graphics.endUpdate();
}
}