Manipulating PNG Images

Specifying Transparency for PNG Images

One of the advantages of saving images in PNG format is that PNG can have transparent background. Aspose.Imaging for Java provides the feature for specifying transparency for the PngImage & RasterImage classes as demonstrated in the below section.

Aspose.Imaging for Java API can be used to set any color as transparent while creating new PNG images or converting existing images to PNG format. For this purposes, the Aspose.Imaging for Java API has exposed TransparentColor property and PngColorType enumeration that can be set to specify any color to be rendered as transparent in the resultant PNG image.

The below provided code snippet demonstrates how to convert an existing BMP image to PNG format by creating a PNG image from scratch while specifying the desired color as transparent.

// For complete examples and data files, please go to https://github.com/Muhammad-Adnan-Ahmad/Aspose.Imaging-for-Java
// Initialize variables to hold width & height values
int width = 0;
int height = 0;
// Initialize an array of type Color to hold the pixel data
Color[] pixels = null;
// Create an instance of RasterImage and load a BMP image
RasterImage raster = (RasterImage) Image.load(dataDir + "aspose-logo.jpg");
// Store the width & height in variables for later use
width = raster.getWidth();
height = raster.getHeight();
// Load the pixels of RasterImage into the array of type Color
pixels = raster.loadPixels(new Rectangle(0, 0, width, height));
// Create & initialize an instance of PngImage while specifying size and PngColorType
PngImage png = new PngImage(width, height, PngColorType.TruecolorWithAlpha);
// Save the previously loaded pixels on to the new PngImage
png.savePixels(new Rectangle(0, 0, width, height), pixels);
// Set TransparentColor property to specify which color to be rendered as transparent
png.setTransparentColor(Color.getBlack());
// Save the result on disc
png.save(dataDir + "SpecifyTransparency_out.jpg");

Another example that converts any loaded image directly to PNG format while specifying the transparent color is as follow.

// For complete examples and data files, please go to https://github.com/Muhammad-Adnan-Ahmad/Aspose.Imaging-for-Java
// Load the source image (any format) in an instance of RasterImage
RasterImage image = (RasterImage) Image.load(dataDir + "aspose-logo.jpg");
// Set the background color for the image
image.setBackgroundColor(Color.getWhite());
// Set the transparent color for the image
image.setTransparentColor(Color.getBlack());
// Set the HasTransparentColor & HasBackgroundColor properties to true
image.setBackgroundColor(true);
image.setTransparentColor(true);
// Save the image on disc in PNG format
image.save(dataDir + "ConvertanyLoadedImageDirectlyToPNGformat_out.jpg", new PngOptions());

Compressing PNG Files

The Portable Network Graphic (PNG) is a lossless compression format for transmitting a bitmap over networks. When you save an image as a PNG file in any program, you may be asked to choose a compression level in a range from 0 to any max level. Setting this value actually compresses the file size and does not decrease the image quality. This article describes how Aspose.Imaging APIs allows you to control the PNG file size.

Aspose.Imaging APIs can be used to set the Compression Levels for the PNG file format using the PngOptions class that has an int type CompressionLevel property. This property accepts a value from 0 to 9 where 9 is the maximum compression.

The below provided code snippet demonstrates how to set the Compression Levels using Aspose.Imaging for Java API.

// For complete examples and data files, please go to https://github.com/Muhammad-Adnan-Ahmad/Aspose.Imaging-for-Java
// Load an image from file (or stream)
Image image = Image.load(dataDir + "aspose_logo.png");
// Loop over possible CompressionLevel range
for (int i = 0; i <= 9; i++) {
// Create an instance of PngOptions for each resultant PNG
PngOptions options = new PngOptions();
// Set CompressionLevel
options.setCompressionLevel(i);
// Save result on disk (or stream)
image.save("CompressingFiles_out" + i + ".png", options);
}

Specifying Bit Depth for PNG Images

Bit depth in imaging is the number of bits used to indicate the color of a single pixel in a bitmap image. Like all other bitmap formats, PNG color depth is also represented in bit such as 1-bit (2 colors), 2-bit (4 colors), 4-bit (16 colors) and 8-bit (256 colors).

Aspose.Imaging for Java API can be used to set bit depth for PNG images using BitDepth property exposed by the PngOptions class. At the moment, the BitDepth property can be set to 1, 2, 4 or 8 bits for grayscale and indexed color types. For all other color types only 8 bits are supported at the moment.

The below provided code snippet demonstrates how to set the Bit Depth of an existing PNG.

// For complete examples and data files, please go to https://github.com/Muhammad-Adnan-Ahmad/Aspose.Imaging-for-Java
// Load an existing PNG image
PngImage pngImage = (PngImage) Image.load(dataDir + "aspose_logo.png");
// Create an instance of PngOptions
PngOptions options = new PngOptions();
// Set the desired ColorType
options.setColorType(PngColorType.Grayscale);
// Set the BitDepth according to the specified ColorType
options.setBitDepth((byte) 1);
// Save changes to the disc
pngImage.save(dataDir + "SpecifyBitDepth_out.jpg", options);

Applying Filter Methods on PNG Images

Aspose.Imaging for Java provides the functionality to apply filter methods (algorithms) before compression as demonstrated in the below section. The purpose of these filter methods is to prepare the image data for optimum compression.

PngFilterType Enumeration

Following are the different type of filter methods:

Name Value Description
Adaptive 5 Adaptive filtering, means that saving process will choose most sutable filter for each data row. Best compression, slowest execution time.
Avg 3 The avg filter, means, that average filter will be applied to image data.
None 0 The null-filter, means no filtering for image data rows.
Paeth 4 The paeth predictor filter.
Sub 1 The sub filter, means substractive filtering will be applied to image data.
Up 2 The up filter, means row-by-row substraction filter will be applied.

Applying Filter Method on PNG Images

Aspose.Imaging for Java API can be used to apply filter methods before compressing any PNG image. For this purposes, the Aspose.Imaging for Java API has exposed a property named FilterType of PngOptions class. It accepts PngFilterType enumeration that can be used to specify the filter method (algorithm) among the five including 0 for none. The below provided code snippet demonstrates how to apply filter method on PNG image.

// For complete examples and data files, please go to https://github.com/Muhammad-Adnan-Ahmad/Aspose.Imaging-for-Java
com.aspose.imaging.fileformats.png.PngImage png = (com.aspose.imaging.fileformats.png.PngImage) com.aspose.imaging.Image
.load(dataDir + "aspose_logo.png");
// Create an instance of PngOptions
com.aspose.imaging.imageoptions.PngOptions options = new com.aspose.imaging.imageoptions.PngOptions();
// Set the PNG filter method
options.setFilterType(com.aspose.imaging.fileformats.png.PngFilterType.Paeth);
// Save changes to the disc
png.save(dataDir + "ApplyFilterMethod_out.jpg", options);

Changing Background Color of a Transparent PNG Image

PNG format images can have transparent background. Aspose.Imaging for Java provides the feature to change the background color of a PNG image that has transparent background.

Aspose.Imaging for Java API can be used to set/change color of a transparent PNG image. The below provided code snippet demonstrates how to set/change the background color of a transparent PNG image.

// For complete examples and data files, please go to https://github.com/Muhammad-Adnan-Ahmad/Aspose.Imaging-for-Java
// Create an instance of Image class and load a PNG image
com.aspose.imaging.Image img = com.aspose.imaging.Image.load(dataDir + "aspose_logo.png");
// Create an instance of RasterImage and get the pixels array by calling
// method LoadArgb32Pixels.
com.aspose.imaging.RasterImage rasterImg = (com.aspose.imaging.RasterImage) img;
int[] pixels = rasterImg.loadArgb32Pixels(img.getBounds());
// Iterate through the pixel array.
for (int i = 0; i < pixels.length; i++) {
// Check the pixel information that if it is a transparent color
// pixel
if (pixels[i] == rasterImg.getTransparentColor().toArgb()) {
// Change the pixel color to white
pixels[i] = com.aspose.imaging.Color.getWhite().toArgb();
}
}
// Replace the pixel array into the image.
rasterImg.saveArgb32Pixels(img.getBounds(), pixels);
// Save the updated image to disk.
rasterImg.save(dataDir + "ChangeBackgroundColor_out.png");

Optimizing Memory Usage

When reading a big PNG file, the total amount of RAM the process will take is always a concern. There are measures which can be adopted to cope with the challenge. Aspose.Imaging provides some relevant options and API calls to lower, reduce and optimize memory use. Also, it can help the process work more efficiently and run faster.

The following example shows how to read a large PNG file in optimized mode.

String dataDir = Utils.getSharedDataDir(ReadLargePNGFile.class) + "ManipulatingPNGImages/";
Image image = Image.load(dataDir + "halfGigImage.png");
// Create an instance of JpegOptions
JpegOptions options = new JpegOptions();
image.save(dataDir + "halfGigImage.jpg", options);