Converting Images

Converting Images to Black n White and Grayscale

Sometimes you may require to convert colored images to Black n White or Grayscale for printing or archiving purposes. This article demonstrates the use of Aspose.PSD for Java API to achieve this using two methods as stated below.

  • Binarization
  • Grayscaling

Binarization

In order to understand the concept of Binarization, it is important to define a Binary Image; that is a digital image that can have only two possible values for each pixel. Normally, the two colors used for a binary image are black and white though any two colors can be used. Binarization is the process of converting an image to bi-level meaning that each pixel is stored as a single bit (0 or 1) where 0 denotes the absence of color and 1 means presence of color. Aspose.PSD for Java API currently supports two Binarization methods.

Binarization with Fixed Threshold

The following code snippet shows you how to use fixed threshold binarization can be applied to an image.

String dataDir = Utils.getDataDir(BinarizationWithFixedThreshold.class) + "Conversion/";
String sourceFile = dataDir + "sample.psd";
String destName = dataDir + "BinarizationWithFixedThreshold_out.jpg";
try (Image image = Image.load(sourceFile);
RasterCachedImage rasterCachedImage = (RasterCachedImage) image) {
if (!rasterCachedImage.isCached()) {
// Cache image if not already cached
rasterCachedImage.cacheData();
}
// Binarize image with predefined fixed threshold and Save the resultant image
rasterCachedImage.binarizeFixed((byte) 100);
rasterCachedImage.save(destName, new JpegOptions());
}

Binarization with Otsu Threshold

The following code snippet shows you how Otsu threshold binarization can be applied to an image.

String dataDir = Utils.getDataDir(BinarizationWithOtsuThreshold.class) + "Conversion/";
String sourceFile = dataDir + "sample.psd";
String destName = dataDir + "BinarizationWithOtsuThreshold_out.jpg";
try (Image image = Image.load(sourceFile);
// Cast the image to RasterCachedImage and Check if image is cached
RasterCachedImage rasterCachedImage = (RasterCachedImage) image) {
if (!rasterCachedImage.isCached()) {
// Cache image if not already cached
rasterCachedImage.cacheData();
}
// Binarize image with Otsu Thresholding and Save the resultant image
rasterCachedImage.binarizeOtsu();
rasterCachedImage.save(destName, new JpegOptions());
}

Grayscaling

Gray-scaling is the process of converting a continuous-tone image to an image with discontinues gray shades. The following code snippet shows you how to use Grayscaling.

String dataDir = Utils.getDataDir(GrayScaling.class) + "Conversion/";
String sourceFile = dataDir + "sample.psd";
String destName = dataDir + "Grayscaling_out.jpg";
try (Image image = Image.load(sourceFile)) {
// Cast the image to RasterCachedImage and Check if image is cached
RasterCachedImage rasterCachedImage = (RasterCachedImage) image;
if (!rasterCachedImage.isCached()) {
// Cache image if not already cached
rasterCachedImage.cacheData();
}
// Transform image to its grayscale representation and Save the resultant image
rasterCachedImage.grayscale();
rasterCachedImage.save(destName, new JpegOptions());
}

Convert GIF Image Layers To TIFF Image

Sometimes it is needed to extract and convert layers of a PSD Image into another raster image format to meet an application need. Aspose.PSD API supports the feature of extracting and converting layers of a PSD Image into another raster image format. Firstly, we will create instance of image and load PSD image from the local disk, then we will iterate each layer in the Layer property. Then we will convert the block to TIFF image. The following code snippet shows you how to convert PSD image layers to TIFF images.

String dataDir = Utils.getDataDir(GIFImageLayersToTIFF.class) + "Conversion/";
String sourceFile = dataDir + "sample.psd";
// Load a PSD image and Convert the image's layers to Tiff images.
try (PsdImage image = (PsdImage) Image.load(sourceFile)) {
// Iterate through array of PSD layers
for (int i = 0; i < image.getLayers().length; i++) {
// Get PSD layer.
Layer layer = image.getLayers()[i];
// Create an instance of TIFF Option class and Save the PSD layer as TIFF image
TiffOptions objTiff = new TiffOptions(TiffExpectedFormat.TiffDeflateRgb);
layer.save("output" + i + "_out.tiff", objTiff);
}
}

Converting CMYK PSD to CMYK TIFF

Using Aspose.PSD for Java, developers can convert CMYK PSD file to CMYK tiff format. This article shows how to export / convert CMYK PSD file to CMYK tiff format with Aspose.PSD. Using Aspose.PSD for Java you can load PSD images and then you can set various properties using TiffOptions class and save or export the image. The following code snippet shows you how to achieve this feature.

String dataDir = Utils.getDataDir(CMYKPSDtoCMYKTiff.class) + "Conversion/";
String sourceFile = dataDir + "sample.psd";
String destName = dataDir + "output.tiff";
try (Image image = Image.load(sourceFile)) {
image.save(destName, new TiffOptions(TiffExpectedFormat.TiffLzwCmyk));
}

Exporting Images

Along with a rich set of image processing routines, Aspose.PSD provides specialized classes to convert PSD file formats to other formats. Using this library, PSD images conversion is very simple and intuitive. Below are some specialized classes for this purpose in ImageOptions namespace.

  • BmpOptions
  • GifOptions
  • JpegOptions
  • Jpeg2000Options
  • TiffOptions
  • PngOptions

It is easy to export PSD images with Aspose.PSD for Java API. All you need is an object of the appropriate class from ImageOptions namespace. By using these classes, you can easily export any image created, edited or simply loaded with Aspose.PSD for Java to any supported format.

Combining Images

This example uses Graphics class and shows how to combine two or more images into a single complete image. To demonstrate the operation, the example creates a new PsdImage and draws images on the canvas surface using Draw Image method exposed by Graphics class. Using Graphics class two or more images can be combined in such way that the resultant image will look as a complete image with no space between the image parts and no pages. The canvas size must be equal to the size of resultant image. Following is the code demonstration that shows how to use Draw Image method of the Graphics class to combine images in a single image.

String dataDir = Utils.getDataDir(CombiningImages.class) + "DrawingAndFormattingImages/";
// Create an instance of PsdOptions and set its various properties
PsdOptions imageOptions = new PsdOptions();
// Create an instance of FileCreateSource and assign it to Source property
imageOptions.setSource(new FileCreateSource(dataDir + "Two_images_result_out.psd", false));
try (Image image = Image.create(imageOptions, 600, 600)) {
// Create and initialize an instance of Graphics, Clear the image surface with white color and Draw Image
Graphics graphics = new Graphics(image);
graphics.clear(Color.getWhite());
graphics.drawImage(Image.load(dataDir + "example1.psd"), 0, 0, 300, 600);
graphics.drawImage(Image.load(dataDir + "example2.psd"), 300, 0, 300, 600);
image.save();
}

Expand and Crop Images

Aspose.PSD API allows you to expand or crop an image during image conversion process. Developer needs to create a rectangle with X and Y coordinates and specify the width and height of the rectangle box. The X,Y and Width, Height of rectangle will depict the expansion or cropping of the loaded image. If it is required to expand or crop the image during image conversion, perform the following steps:

  1. Create an instance of RasterImage class and load the existing image.
  2. Create an Instance of ImageOption class.
  3. Create an instance of Rectangle class and initialize the X,Y and Width, Height of the rectangle
  4. Call Save method of the RasterImage class while passing output file name, image options and the rectangle object as parameters.
String dataDir = Utils.getDataDir(ExpandAndCropImages.class) + "DrawingAndFormattingImages/";
String sourceFile = dataDir + "example1.psd";
String destName = dataDir + "jpeg_out.jpg";
try (RasterImage rasterImage = (RasterImage) Image.load(sourceFile)) {
rasterImage.cacheData();
// Create an instance of Rectangle class and define X,Y and Width, height of the rectangle, and Save output image
Rectangle destRect = new Rectangle(-200, -200, 300, 300);
rasterImage.save(destName, new JpegOptions(), destRect);
}

Read and Write XMP Data To Images

XMP (Extensible Metadata Platform) is an ISO standard. XMP standardizes a data model, a serialization format and core properties for the definition and processing of extensible metadata. It also provides guidelines for embedding XMP information into popular image such as JPEG, without breaking their readability by applications that do not support XMP. Using Aspose.PSD for Java API developers can read or write XMP metadata to images. This article demonstrates how XMP metadata can be read from image and write XMP metadata to images.

Create XMP Metadata, Write It And Read From File

With the help of XMP namespace developer can create XMP metadata object and write it to an image. The following code snippet shows you how to use the XmpHeaderPi, XmpTrailerPi, XmpMeta, XmpPacketWrapper, PhotoshopPackage and DublinCorePackage packages contained in XMP namespace.

String dataDir = Utils.getDataDir(CreateXMPMetadata.class) + "DrawingAndFormattingImages/";
// Specify the size of image by defining a Rectangle
Rectangle rect = new Rectangle(0, 0, 100, 200);
// create the brand new image just for sample purposes
try (PsdImage image = new PsdImage(rect.getWidth(), rect.getHeight())) {
// create an instance of XMP-Header
XmpHeaderPi xmpHeader = new XmpHeaderPi();
xmpHeader.setGuid(dataDir);
// create an instance of Xmp-TrailerPi
XmpTrailerPi xmpTrailer = new XmpTrailerPi(true);
// create an instance of XMPmeta class to set different attributes
XmpMeta xmpMeta = new XmpMeta();
xmpMeta.addAttribute("Author", "Mr Smith");
xmpMeta.addAttribute("Description", "The fake metadata value");
// create an instance of XmpPacketWrapper that contains all metadata
XmpPacketWrapper xmpData = new XmpPacketWrapper(xmpHeader, xmpTrailer, xmpMeta);
// create an instacne of Photoshop package and set photoshop attributes
PhotoshopPackage photoshopPackage = new PhotoshopPackage();
photoshopPackage.setCity("London");
photoshopPackage.setCountry("England");
photoshopPackage.setColorMode(ColorMode.Rgb);
// add photoshop package into XMP metadata
xmpData.addPackage(photoshopPackage);
// create an instacne of DublinCore package and set dublinCore attributes
DublinCorePackage dublinCorePackage = new DublinCorePackage();
dublinCorePackage.setAuthor("Charles Bukowski");
dublinCorePackage.setTitle("Confessions of a Man Insane Enough to Live With the Beasts");
dublinCorePackage.addValue("dc:movie", "Barfly");
// add dublinCore Package into XMP metadata
xmpData.addPackage(dublinCorePackage);
MemoryStream ms = new MemoryStream();
// update XMP metadata into image
image.setXmpData(xmpData);
// Save image on the disk or in memory stream
image.save(dataDir + "create_XMP_Metadata.psd");
}

Export Images in Multi Threaded Environment

Aspose.PSD for Java now supports converting images in multi threaded environment. Aspose.PSD for Java ensures the optimized performance of operations during execution of code in multi-threaded environment. All image option classes (e.g. BmpOptions, TiffOptions, JpegOptions, etc.) in the Aspose.PSD for Java implement IDisposable interface. Therefore it is a must that developer properly dispose off the image options class object in case Source property is set. Following code snippet demonstrates the said functionality.

String dataDir = Utils.getDataDir(ExportImagesinMultiThreadEnv.class) + "Conversion/";
String imageDataPath = dataDir + "sample.psd";
try {
FileInputStream fileStream = new FileInputStream(imageDataPath);
PsdOptions psdOptions = new PsdOptions();
// Set the source property of the imaging option class object.
psdOptions.setSource(new StreamSource(fileStream));
// Following is the sample processing on the image.
RasterImage image = (RasterImage) Image.create(psdOptions, 10, 10);
Color[] pixels = new Color[4];
for (int i = 0; i < 4; ++i) {
pixels[i] = Color.fromArgb(40, 30, 20, 10);
}
image.savePixels(new Rectangle(0, 0, 2, 2), pixels);
image.save();
} finally {
// Delete the output file.
File f = new File(imageDataPath);
if (f.exists()) {
f.delete();
}
}

Aspose.PSD now supports SyncRoot property while working in multi-threaded environment. Developer can use this property to synchronize access to the source stream. Following code snippet demonstrates how the SyncRoot property can be used.

String dataDir = Utils.getDataDir(SyncRoot.class) + "Conversion/";
// Create an instance of Stream container class and assign memory stream object.
StreamContainer streamContainer = new StreamContainer(new java.io.ByteArrayInputStream(new byte[0]));
try {
// check if the access to the stream source is synchronized.
synchronized (streamContainer.getSyncRoot()) {
// do work
// now access to streamContainer is synchronized
}
} finally {
streamContainer.dispose();
}