Working with multipage image formats

Aspose.Imaging supports rich functionality to work with multipage image formats such as Gif, Tiff, Psd, Dicom, Cdr, WebP etc. Also, using Aspose.Imaging image can be exported also to multipage PDF document.

To indicate whether the image contains layers/pages/ frames the IMultipageImage interface has been introduced. All multi-page images such as PSD, CDR, GIF, etc. are descendants of this interface. Using Pages property, you can access the pages of any multi-page image in the library. Example of usage IMultipageImage interface:

try (Image image = Image.load(fileName))
{
    if (image instanceof IMultipageImage)
    {
        Image[] pages = ((IMultipageImage)image).getPages();
    }
}

Export of multipage images can be performed using MultiPageOptions class. With this option you can specify the pages that you want to export to another format. In the case of export to a single-page format, the 1st page of the range will be exported; in the case of export to a multi-page format, all pages of the range will be exported.

Example of export from multi-page format to single-page image format:

int startPage = 3;
int countPage = 1;

try (Image image = Image.load(fileName))
{
    PngOptions pngOptions = new PngOptions();
    pngOptions.setMultiPageOptions(new MultiPageOptions(new IntRange(startPage, countPage)));
    image.save(outFileName, pngOptions);
}

Example of export from multi-page format to multi-page

int startPage = 3;
int countPage = 2;

try (Image image = Image.load(fileName))
{
    PngOptions pngOptions = new PngOptions();
    pngOptions.setMultiPageOptions(new MultiPageOptions(new IntRange(startPage, countPage)));
    image.save(outFileName, pngOptions);
}

Here the 4th and 5th pages will be exported to the tiff format

Below presented example of export from/to different multipage image formats:

private void exportImage(ImageOptionsBase imageOptions, String ext)
{
    String baseFolder = "D:\\images\\";
    String inputFolderName = baseFolder;
    String outputFolderName = baseFolder + "out\\";

    String[] files = new File(inputFolderName).list();

    if (files == null)
    {
        System.err.println("No files are found!");
        return;
    }

    for (String inputFileName : files)
    {
        String fileName = new File(inputFolderName + inputFileName).getName();
        System.out.println(fileName);

        try (Image image = Image.load(inputFileName))
        {
            //export only 2 pages
            if (image instanceof IMultipageImage && ((IMultipageImage)image).getPages() != null && ((IMultipageImage)image).getPageCount() > 2)
            {
                imageOptions.setMultiPageOptions(new MultiPageOptions(new IntRange(0, 2)));
            }
			else
            {
                imageOptions.setMultiPageOptions(null);
            }

            if (image instanceof VectorImage)
            {
                VectorRasterizationOptions defaultOptions = (VectorRasterizationOptions) image.getDefaultOptions(new Object[]{Color.getWhite(), image.getWidth(), image.getHeight()});
                imageOptions.setVectorRasterizationOptions(defaultOptions);
                defaultOptions.setTextRenderingHint(TextRenderingHint.SingleBitPerPixel);
                defaultOptions.setSmoothingMode(SmoothingMode.None);
            }

            String outFileName = outputFolderName + fileName + ext;
            image.save(outFileName, imageOptions);
        }
    }
}

// Code for using ExportImage method

ImageOptionsBase[] imageOptions = new ImageOptionsBase[] {new PsdOptions(),  new WebPOptions(), new GifOptions(),
        new TiffOptions(TiffExpectedFormat.Default), new BmpOptions(), new JpegOptions(), new Jpeg2000Options(), new PngOptions(),
        new EmfOptions(), new SvgOptions(), new WmfOptions(), new PdfOptions(),
};

String[] imageExt = new String[] {".psd", ".webp", ".gif", ".tiff", ".bmp", ".jpeg", ".j2k", ".png", ".emf", ".svg", ".wmf",".pdf"};

if (imageOptions.length != imageExt.length)
{
    throw new RuntimeException("imageOptions length not equal imageExt length");
}

for (int i = 0; i < imageOptions.length; i++)
{
    this.exportImage(imageOptions[i], imageExt[i]);
}

Support of making gifs and other multi-page (multi-frame) files from set of images

Create multipage images using AddPage method

You can create multipage image using AddPage() method. The following code shows how you can create animated images using image frames from the folder:

static void main(String[] args)
{
// The path to the documents directory.
String dataDir = "Png/";
String outDir = "gif/";
// Load frames
Iterable<RasterImage> frames = loadFrames(dataDir + "Animation frames");
GifImage image = null;
for (RasterImage frame : frames)
{
if (image == null)
{
// Create GIF image using the first frame
image = new GifImage(new GifFrameBlock(frame));
continue;
}
// Add frames to the GIF image using the AddPage method
image.addPage(frame);
}
if (image != null)
{
image.save(outDir + "Multipage.gif");
// Clear all resources
image.close();
}
TiffImage tiffImage = null;
for (RasterImage frame : frames)
{
if (tiffImage == null)
{
// Create TIFF image using the first frame
tiffImage = new TiffImage(new TiffFrame(frame));
continue;
}
// Add frames to the TIFF image using the AddPage method
tiffImage.addPage(frame);
}
if (tiffImage != null)
{
tiffImage.save(outDir + "Multipage.tif", new TiffOptions(TiffExpectedFormat.TiffJpegRgb));
// Clear all resources
tiffImage.close();
}
WebPImage webImage = null;
for (RasterImage frame : frames)
{
if (webImage == null)
{
// Create WEBP image using the first frame
webImage = new WebPImage(frame);
continue;
}
// Add frames to the TIFF image using the AddPage method
webImage.addPage(frame);
}
if (webImage != null)
{
webImage.save(outDir + "Multipage.webp");
// Clear all resources
webImage.close();
}
ApngImage apngImage = null;
for (RasterImage frame : frames)
{
if (apngImage == null)
{
// Create APNG image using the first frame and it's size
apngImage = new ApngImage(new ApngOptions(), frame.getWidth(), frame.getHeight());
}
// Add frames to the APNG image using the AddPage method
apngImage.addPage(frame);
}
if (apngImage != null)
{
apngImage.save(outDir + "Multipage.png");
// Clear all resources
apngImage.close();
}
DicomImage dicomImage = null;
for (RasterImage frame : frames)
{
if (dicomImage == null)
{
// Create DICOM image using the first frame and it's size
dicomImage = new DicomImage(new DicomOptions(), frame.getWidth(), frame.getHeight());
}
// Add frames to the DICOM image using the addPage method
dicomImage.addPage(frame);
}
if (dicomImage != null)
{
// Remove default empty page
dicomImage.removePage(0);
dicomImage.save(outDir + "Multipage.dcm");
// Clear all resources
dicomImage.close();
}
}
private static Iterable<RasterImage> loadFrames(String directory)
{
return new FileList(directory);
}
private static class FileList implements Iterable<RasterImage>
{
private final File[] images;
FileList(String directory)
{
images = new File(directory).listFiles();
}
@Override
public Iterator<RasterImage> iterator()
{
return new Iterator<RasterImage>(){
int index = -1;
@Override
public boolean hasNext()
{
if (images == null || index + 1 >= images.length)
return false;
index++;
return true;
}
@Override
public RasterImage next()
{
return (RasterImage) Image.load(images[index].getAbsolutePath());
}
@Override
public void remove()
{
throw new UnsupportedOperationException();
}
};
}
}

Create multipage image from vector images

In order to use vector images as animation frames you need to rasterize them first. The following source code sample shows how to create TIFF image using vector images:

static void multipageFromVector()
{
// Rasterize vector images
rasterizeSvgToPng("Vector images\\cube.svg", "Vector images\\Rasterized\\cube.png");
rasterizeSvgToPng("Vector images\\greenGrapes.svg", "Vector images\\Rasterized\\greenGrapes.png");
rasterizeSvgToPng("Vector images\\text.svg", "Vector images\\Rasterized\\text.png");
// Load frames
Iterable<RasterImage> frames = loadFrames("Vector images\\Rasterized");
TiffImage image = null;
for (RasterImage frame : frames)
{
if (image == null)
{
// Create TIFF image using the first frame
image = new TiffImage(new TiffFrame(frame));
continue;
}
// Add frames to the TIFF image using the AddPage method
image.addPage(frame);
}
if (image != null)
{
// Save TIFF image using options
TiffOptions options = new TiffOptions(TiffExpectedFormat.TiffJpegRgb);
image.save("MultipageFromVector.tif", options);
}
}
private static void rasterizeSvgToPng(String inputPath, String outputPath)
{
// Load vector image
try (Image image = Image.load(inputPath))
{
// Save PNG image
final PngOptions options = new PngOptions();
// Create rasterization options
final SvgRasterizationOptions svgRasterizationOptions = new SvgRasterizationOptions();
svgRasterizationOptions.setPageWidth(image.getWidth());
svgRasterizationOptions.setPageHeight(image.getHeight());
options.setVectorRasterizationOptions(svgRasterizationOptions);
image.save(outputPath, options);
}
}