Skip to main content
Skip table of contents

Reduce image


reducesize

JAVA

JAVA
/*
    This file is part of the iText (R) project.
    Copyright (c) 1998-2023 Apryse Group NV
    Authors: Apryse Software.

    For more information, please contact iText Software at this address:
    sales@itextpdf.com
 */
package com.itextpdf.samples.sandbox.images;

import com.itextpdf.io.source.ByteArrayOutputStream;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfIndirectReference;
import com.itextpdf.kernel.pdf.PdfName;
import com.itextpdf.kernel.pdf.PdfNumber;
import com.itextpdf.kernel.pdf.PdfObject;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.PdfStream;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.WriterProperties;
import com.itextpdf.kernel.pdf.xobject.PdfImageXObject;

import java.awt.Graphics2D;
import javax.imageio.ImageIO;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;

public class ReduceSize {
    public static final String DEST = "./target/sandbox/images/reduce_size.pdf";

    public static final String SRC = "./src/main/resources/pdfs/single_image.pdf";

    public static void main(String[] args) throws Exception {
        File file = new File(DEST);
        file.getParentFile().mkdirs();

        new ReduceSize().manipulatePdf(DEST);
    }

    protected void manipulatePdf(String dest) throws Exception {
        PdfWriter writer = new PdfWriter(dest, new WriterProperties().setFullCompressionMode(true));
        PdfDocument pdfDoc = new PdfDocument(new PdfReader(SRC), writer);
        float factor = 0.5f;

        for (PdfIndirectReference indRef : pdfDoc.listIndirectReferences()) {

            // Get a direct object and try to resolve indirects chain.
            // Note: If chain of references has length of more than 32,
            // this method return 31st reference in chain.
            PdfObject pdfObject = indRef.getRefersTo();
            if (pdfObject == null || !pdfObject.isStream()) {
                continue;
            }

            PdfStream stream = (PdfStream) pdfObject;
            if (!PdfName.Image.equals(stream.getAsName(PdfName.Subtype))) {
                continue;
            }

            if (!PdfName.DCTDecode.equals(stream.getAsName(PdfName.Filter))) {
                continue;
            }

            PdfImageXObject image = new PdfImageXObject(stream);
            BufferedImage origImage = image.getBufferedImage();
            if (origImage == null) {
                continue;
            }

            int width = (int) (origImage.getWidth() * factor);
            int height = (int) (origImage.getHeight() * factor);
            if (width <= 0 || height <= 0) {
                continue;
            }

            // Scale the image
            BufferedImage resultImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            AffineTransform at = AffineTransform.getScaleInstance(factor, factor);
            Graphics2D graphics = resultImage.createGraphics();
            graphics.drawRenderedImage(origImage, at);
            ByteArrayOutputStream scaledBitmapStream = new ByteArrayOutputStream();
            ImageIO.write(resultImage, "JPG", scaledBitmapStream);

            resetImageStream(stream, scaledBitmapStream.toByteArray(), width, height);
            scaledBitmapStream.close();
        }

        pdfDoc.close();
    }

    private static void resetImageStream(PdfStream stream, byte[] imgBytes, int imgWidth, int imgHeight) {
        stream.clear();
        stream.setData(imgBytes);
        stream.put(PdfName.Type, PdfName.XObject);
        stream.put(PdfName.Subtype, PdfName.Image);
        stream.put(PdfName.Filter, PdfName.DCTDecode);
        stream.put(PdfName.Width, new PdfNumber(imgWidth));
        stream.put(PdfName.Height, new PdfNumber(imgHeight));
        stream.put(PdfName.BitsPerComponent, new PdfNumber(8));
        stream.put(PdfName.ColorSpace, PdfName.DeviceRGB);
    }
}

C#

C#
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using iText.Kernel.Pdf;
using iText.Kernel.Pdf.Xobject;

namespace iText.Samples.Sandbox.Images
{
    public class ReduceSize
    {
        public static readonly String DEST = "results/sandbox/images/reduce_size.pdf";

        public static readonly String SRC = "../../../resources/pdfs/single_image.pdf";

        public static void Main(String[] args)
        {
            FileInfo file = new FileInfo(DEST);
            file.Directory.Create();

            new ReduceSize().ManipulatePdf(DEST);
        }

        protected void ManipulatePdf(String dest)
        {
            PdfWriter writer = new PdfWriter(dest, new WriterProperties().SetFullCompressionMode(true));
            PdfDocument pdfDoc = new PdfDocument(new PdfReader(SRC), writer);
            float factor = 0.5f;

            foreach (PdfIndirectReference indRef in pdfDoc.ListIndirectReferences())
            {
                // Get a direct object and try to resolve indirects chain.
                // Note: If chain of references has length of more than 32,
                // this method return 31st reference in chain.
                PdfObject pdfObject = indRef.GetRefersTo();
                if (pdfObject == null || !pdfObject.IsStream())
                {
                    continue;
                }

                PdfStream stream = (PdfStream) pdfObject;
                if (!PdfName.Image.Equals(stream.GetAsName(PdfName.Subtype)))
                {
                    continue;
                }

                if (!PdfName.DCTDecode.Equals(stream.GetAsName(PdfName.Filter)))
                {
                    continue;
                }

                PdfImageXObject image = new PdfImageXObject(stream);
                MemoryStream imageStream = new MemoryStream(image.GetImageBytes());
                Bitmap bitmap = new Bitmap(imageStream);
                imageStream.Close();

                int width = (int) (bitmap.Width * factor);
                int height = (int) (bitmap.Height * factor);
                if (width <= 0 || height <= 0)
                {
                    continue;
                }

                // Scale the image
                Bitmap scaledBitmap = new Bitmap(bitmap, new Size(width, height));
                MemoryStream scaledBitmapStream = new MemoryStream();
                scaledBitmap.Save(scaledBitmapStream, ImageFormat.Jpeg);
                
                ResetImageStream(stream, scaledBitmapStream.ToArray(), width, height);
                scaledBitmapStream.Close();
            }

            pdfDoc.Close();
        }

        private static void ResetImageStream(PdfStream stream, byte[] imgBytes, int imgWidth, int imgHeight)
        {
            stream.Clear();
            stream.SetData(imgBytes);
            stream.Put(PdfName.Type, PdfName.XObject);
            stream.Put(PdfName.Subtype, PdfName.Image);
            stream.Put(PdfName.Filter, PdfName.DCTDecode);
            stream.Put(PdfName.Width, new PdfNumber(imgWidth));
            stream.Put(PdfName.Height, new PdfNumber(imgHeight));
            stream.Put(PdfName.BitsPerComponent, new PdfNumber(8));
            stream.Put(PdfName.ColorSpace, PdfName.DeviceRGB);
        }
    }
}
JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.