PDF size optimization including images

Hi, Appfarm community

I’m encountering an issue with PDF generation in Appfarm using the “Generate Document” action. The PDFs are becoming extremely large - for instance, three images totaling only 10 MB are producing a PDF over 50 MB without any other content. It is nothing new that PDFs contains a lot of “overhead” incresing the file size, but I need to find a solution for generating PDFs including images without increasing the file size that much. After investigating, it seems the problem is related to large images being appended during PDF generation. These images are stored in Appfarm (https://storage.googleapis.com).

The images are imported from a third-party solution into Appfarm using “Create file object” with Source Type URL, and not using Source Type Default and Accepted File Types Image with the possibility to compress image quality on creation.

I’ve attempted to implement image compression logic for the HTML before generating the PDF in Appfarm, but without any luck. The following HTML/JavaScript approach works well in other PDF-generating software I’m using converting HTML to PDF:

<head>
	<meta charset="UTF-8">
	<script>
		// Maximum dimension threshold for image compression
		const MAX_DIMENSION = 1000;
		async function compressImage(url) {
			try {
				const img = new Image();
				await new Promise((resolve, reject) => {
					img.onload = resolve;
					img.onerror = reject;
					img.crossOrigin = 'anonymous';
					img.src = url;
				});
				// Skip compression for smaller images
				if (img.width <= MAX_DIMENSION && img.height <= MAX_DIMENSION) {
					return url;
				}
				const canvas = document.createElement('canvas');
				const ctx = canvas.getContext('2d');
				const scale = Math.min(MAX_DIMENSION / img.width, MAX_DIMENSION / img.height);
				canvas.width = img.width * scale;
				canvas.height = img.height * scale;
				ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
				return canvas.toDataURL('image/jpeg', 0.7);
			} catch (error) {
				console.error('Image compression failed:', error);
				return url;
			}
		}
		document.addEventListener('DOMContentLoaded', async () => {
			const images = document.querySelectorAll('img');
			for (const img of images) {
				if (img.src) {
					const compressedDataUrl = await compressImage(img.src);
					img.src = compressedDataUrl;
				}
			}
		});
	</script>
</head>

Has anyone successfully retrieved images from Appfarm, “compressed them”, and then included them in HTML before generating a PDF? Or perhaps you’ve found another solution to this PDF size issue?

Any advice or examples would be greatly appreciated!

Thanks in advance,
Sondre

Hello,

You’re right - we currently don’t have image compression functionality when using URL as the source type. I had a similar problem, and found that setting quality=1 when compressing images can significantly reduce file sizes for PDFs and reports.

The issue is that when creating file objects with source type URL, files are sent directly to storage. In contrast, using the default source type with image compression allows for client-side compression.

I’ve noted this limitation regarding image compression and shared it with our Platform team. Without knowing too much about your use case, I would suggest these workarounds:

  1. Pre-processing images before importing them from your third-party solution
  2. Reducing file sizes at creation time

Thanks for bringing this up!

I have come across the same issue in the Generate Document action node (PDF) in a service. How do you compress the images in the Template String function? I am not able to do it. @Nikoline @sgjeilo

Thanks, Sinan

Hello,

Sorry about the delayed answer!

I have not managed to compress images in a template string function, but I have managed to reduce image file size upon file/image creation. E.g when capturing images using your device camera, the image quality is set to a lower value than default(this is a setting on the create file object action node). By doing this, your PDF will as a resut be “smaller”.

Action node settings:

If your images are created elsewhere and imported, I would suggest compressing them before uploading them to the app or using a third party compression service to compress large images :slightly_smiling_face: