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 Python via .NET provides the feature for specifying transparency for the PngImage & RasterImage classes as demonstrated in the below section. Aspose.Imaging for Python via .NET 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 Python via .NET API has exposed TransparentColor property and PngColorType enumeration that can be set to specify any color to be rendered as transparent in the newly created 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.
import aspose.pycore as aspycore | |
from aspose.imaging import Image, RasterImage, Rectangle, Color | |
from aspose.imaging.imageoptions import PngOptions | |
from aspose.imaging.fileformats.png import PngColorType, PngImage | |
import os | |
if 'TEMPLATE_DIR' in os.environ: | |
templates_folder = os.environ['TEMPLATE_DIR'] | |
else: | |
templates_folder = r"C:\Users\USER\Downloads\templates" | |
delete_output = 'SAVE_OUTPUT' not in os.environ | |
data_dir = templates_folder | |
# Initialize variables to hold width & height values | |
width = 0 | |
height = 0 | |
# Initialize an array of type Color to hold the pixel data | |
pixels = None | |
# Create an instance of RasterImage and load a BMP image | |
with aspycore.as_of(Image.load(os.path.join(data_dir, "template.png")), RasterImage) as raster: | |
# Store the width & height in variables for later use | |
width = raster.width | |
height = raster.height | |
# Load the pixels of RasterImage into the array of type Color | |
pixels = raster.load_pixels(Rectangle(0, 0, width, height)) | |
# Create & initialize an instance of PngImage while specifying size and PngColorType | |
with PngImage(width, height, PngColorType.TRUECOLOR_WITH_ALPHA) as png: | |
# Save the previously loaded pixels on to the new PngImage and Set TransparentColor property to specify which color to be rendered as transparent | |
png.save_pixels(Rectangle(0, 0, width, height), pixels) | |
png.transparent_color = Color.black | |
png.has_transparent_color = True | |
png.save(os.path.join(data_dir, "result.jpg")) | |
if delete_output: | |
os.remove(os.path.join(data_dir, "result.jpg")) |
Setting Resolution for PNG Images
With Aspose.Imaging for Python via .NET 2.5.0, the API exposes the ResolutionSetting class which can be used to set the resolution for all image formats including PNG. This article demonstrates the usage of the Aspose.Imaging for Python via .NET API to set the horizontal & vertical resolution parameters for the PNG image format. The code snippet below loads an existing BMP image and converts it to PNG format also changing the resolution.
import aspose.pycore as aspycore | |
from aspose.imaging import Image, RasterImage, Rectangle, ResolutionSetting | |
from aspose.imaging.fileformats.png import PngImage | |
from aspose.imaging.imageoptions import PngOptions | |
import os | |
if 'TEMPLATE_DIR' in os.environ: | |
templates_folder = os.environ['TEMPLATE_DIR'] | |
else: | |
templates_folder = r"C:\Users\USER\Downloads\templates" | |
delete_output = 'SAVE_OUTPUT' not in os.environ | |
data_dir = templates_folder | |
file_name = os.path.join(data_dir, "template.tiff") | |
# Initialize variables to hold width & height values | |
width = 0 | |
height = 0 | |
# Initialize an array of type Color to hold the pixel data | |
pixels = None | |
# Create an instance of RasterImage and load a BMP image | |
with aspycore.as_of(Image.load(os.path.join(data_dir, "template.png")), RasterImage) as raster: | |
# Store the width & height in variables for later use | |
width = raster.width | |
height = raster.height | |
# Load the pixels of RasterImage into the array of type Color | |
pixels = raster.load_pixels(Rectangle(0, 0, width, height)) | |
# Create & initialize an instance of PngImage while specifying size and PngColorType | |
with PngImage(width, height) as png: | |
# Save the previously loaded pixels on to the new PngImage | |
png.save_pixels(Rectangle(0, 0, width, height), pixels) | |
# Create an instance of PngOptions, Set the horizontal & vertical resolutions and Save the result on disc | |
options = PngOptions() | |
options.resolution_settings = ResolutionSetting(72, 96) | |
png.save(os.path.join(data_dir, "result.png"), options) | |
if delete_output: | |
os.remove(os.path.join(data_dir, "result.png")) |
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 Python via .NET API.
import aspose.pycore as aspycore | |
from aspose.imaging import Image | |
from aspose.imaging.imageoptions import PngOptions | |
import os | |
if 'TEMPLATE_DIR' in os.environ: | |
templates_folder = os.environ['TEMPLATE_DIR'] | |
else: | |
templates_folder = r"C:\Users\USER\Downloads\templates" | |
delete_output = 'SAVE_OUTPUT' not in os.environ | |
data_dir = templates_folder | |
# Load an image from file (or stream) | |
with Image.load(os.path.join(data_dir, "template.png")) as image: | |
# Loop over possible CompressionLevel range | |
for i in range(9): | |
# Create an instance of PngOptions for each resultant PNG, Set CompressionLevel and Save result on disk | |
options = PngOptions() | |
options.compression_level = i | |
file_name = os.path.join(data_dir, str(i) + "_out.png") | |
image.save(file_name, options) | |
if delete_output: | |
os.remove(file_name) |
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 Python via .NET 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. The below provided code snippet demonstrates how to set the Bit Depth of an existing PNG.
import aspose.pycore as aspycore | |
from aspose.imaging import Image | |
from aspose.imaging.imageoptions import PngOptions | |
from aspose.imaging.fileformats.png import PngColorType, PngImage | |
import os | |
if 'TEMPLATE_DIR' in os.environ: | |
templates_folder = os.environ['TEMPLATE_DIR'] | |
else: | |
templates_folder = r"C:\Users\USER\Downloads\templates" | |
delete_output = 'SAVE_OUTPUT' not in os.environ | |
data_dir = templates_folder | |
# Load an existing PNG image | |
with aspycore.as_of(Image.load(os.path.join(data_dir, "template.png")), PngImage) as png: | |
# Create an instance of PngOptions, Set the desired ColorType, BitDepth | |
# according to the specified ColorType and save image | |
options = PngOptions() | |
options.color_type = PngColorType.GRAYSCALE | |
options.bit_depth = 1 | |
png.save(os.path.join(data_dir, "result.png"), options) | |
if delete_output: | |
os.remove(os.path.join(data_dir, "result.png")) |
Applying Filter Methods on PNG Images
Aspose.Imaging for Python via .NET 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. Aspose.Imaging for Python via .NET API can be used to apply filter methods before compressing any PNG image. For this purposes, the Aspose.Imaging for Python via .NET 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.
import aspose.pycore as aspycore | |
from aspose.imaging import Image | |
from aspose.imaging.fileformats.png import PngImage, PngFilterType | |
from aspose.imaging.imageoptions import PngOptions | |
import os | |
if 'TEMPLATE_DIR' in os.environ: | |
templates_folder = os.environ['TEMPLATE_DIR'] | |
else: | |
templates_folder = r"C:\Users\USER\Downloads\templates" | |
delete_output = 'SAVE_OUTPUT' not in os.environ | |
data_dir = templates_folder | |
with aspycore.as_of(Image.load(os.path.join(data_dir, "template.png")), PngImage) as png: | |
# Create an instance of PngOptions, Set the PNG filter method and Save changes to the disc | |
options = PngOptions() | |
options.filter_type = PngFilterType.PAETH | |
png.save(os.path.join(data_dir, "result.png"), options) | |
if delete_output: | |
os.remove(os.path.join(data_dir, "result.png")) |
Changing Background Color of a Transparent PNG Image
PNG format images can have transparent background. Aspose.Imaging for Python via .NET provides the feature to change the background color of a PNG image that has transparent background. Aspose.Imaging for Python via .NET 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.
import aspose.pycore as aspycore | |
from aspose.imaging import Image, RasterImage, Color | |
import os | |
if 'TEMPLATE_DIR' in os.environ: | |
templates_folder = os.environ['TEMPLATE_DIR'] | |
else: | |
templates_folder = r"C:\Users\USER\Downloads\templates" | |
delete_output = 'SAVE_OUTPUT' not in os.environ | |
data_dir = templates_folder | |
# Create an instance of Image class and load a PNG image | |
with Image.load(os.path.join(data_dir, "template.png")) as img: | |
# Create an instance of RasterImage and get the pixels array by calling method LoadArgb32Pixels. | |
raster_img = aspycore.as_of(img, RasterImage) | |
if raster_img is not None: | |
pixels = raster_img.load_argb_32_pixels(img.bounds) | |
if pixels is not None: | |
# Iterate through the pixel array and Check the pixel information that if it is a transparent color pixel and Change the pixel color to white | |
transparent_color = raster_img.transparent_color.to_argb() | |
white_color = Color.white.to_argb() | |
for i in range(pixels.length): | |
if pixels[i] == transparent_color: | |
pixels[i] = white_color | |
# Replace the pixel array into the image. | |
raster_img.save_argb_32_pixels(img.bounds, pixels) | |
# Save the updated image to disk. | |
if raster_img is not None: | |
raster_img.save(os.path.join(data_dir, "result.png")) | |
if delete_output: | |
os.remove(os.path.join(data_dir, "result.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.
import aspose.pycore as aspycore | |
from aspose.imaging import Image | |
from aspose.imaging.imageoptions import JpegOptions | |
from aspose.imaging.memorymanagement import Configuration | |
import os | |
if 'TEMPLATE_DIR' in os.environ: | |
templates_folder = os.environ['TEMPLATE_DIR'] | |
else: | |
templates_folder = r"C:\Users\USER\Downloads\templates" | |
delete_output = 'SAVE_OUTPUT' not in os.environ | |
data_dir = templates_folder | |
# Enabling the global memory usage optimization strategy. | |
# Setting a global memory limit of 50 megabytes | |
Configuration.set_buffer_size_hint(50) | |
with Image.load(os.path.join(data_dir, "template.png")) as image: | |
image.save(os.path.join(data_dir, "result.jpg"), JpegOptions()) | |
if delete_output: | |
os.remove(os.path.join(data_dir, "result.jpg")) | |
# Resetting a global memory limit | |
Configuration.set_buffer_size_hint(0) |