To optimize a PDF with default settings is quick once you are set up.
1PDFDoc doc = new PDFDoc(filename);
2Optimizer.Optimize(doc);
1PDFDoc doc(filename);
2Optimizer::Optimize(doc);
1doc := NewPDFDoc(filename)
2OptimizerOptimize(doc)
1PDFDoc doc = new PDFDoc(filename);
2Optimizer.optimize(doc);
1async function main() {
2	const doc = await PDFNet.PDFDoc.createFromFilePath(filename);
3	await PDFNet.Optimizer.optimize(doc);
4}
5PDFNet.runWithCleanup(main);
1PTPDFDoc *doc = [[PTPDFDoc alloc] initWithFilepath: filename];
2[PTOptimizer Optimize: doc settings: [[PTOptimizerSettings alloc] init]];
1$doc = new PDFDoc($filename);
2Optimizer::Optimize($doc);
1doc = PDFDoc(filename)
2Optimizer.Optimize(doc)
1doc = PDFDoc.new(filename)
2Optimizer.Optimize(doc)
1Dim doc As PDFDoc = New PDFDoc(filename)
2Optimizer.Optimize(doc)
Compress & optimize PDF files - Full Sample
Full code sample which shows how to use 'pdftron.PDF.Optimizer' to reduce PDF file size by removing redundant information and compressing data streams using the latest in image compression technology.  Samples available in Python, C# (.Net), C++, Go, Java, Node.js (JavaScript), PHP, Ruby, VB.
Compression as a subset of optimization represents encoding specific data using fewer bits than the original content by reducing the size of the data. This is distinct from optimize (which modifies all images) because you have the ability to choose individual images and to selectively choose the compression type for each.
Apryse SDK supports all basic and advanced compression filters allowed in PDF including:
To compress images using JBIG2 compression inside a PDF.
1PDFDoc pdf_doc = new PDFDoc(filename);
2SDFDoc cos_doc = pdf_doc.GetSDFDoc();
3int num_objs = cos_doc.XRefSize();
4for (int i=1; i<num_objs; ++i)
5{
6	Obj obj = cos_doc.GetObj(i);
7	if (obj==null || obj.IsFree() || !obj.IsStream())
8		continue;
9
10	// Process only images
11	DictIterator itr = obj.Find("Subtype");
12	if (!itr.HasNext() || itr.Value().GetName() != "Image")
13		continue;
14
15	pdftron.PDF.Image input_image = new pdftron.PDF.Image(obj);
16
17	// Process only gray-scale images
18	if (input_image.GetComponentNum() != 1) 
19		continue; 
20	
21	int bpc = input_image.GetBitsPerComponent();
22	if (bpc != 1) // Recompress 1 BPC images
23		continue;
24
25	// Skip images that are already compressed using JBIG2
26	itr = obj.Find("Filter");
27	if (itr.HasNext() && itr.Value().IsName() && itr.Value().GetName() == "JBIG2Decode")
28		continue;
29	
30	FilterReader reader = new FilterReader(obj.GetDecodedStream());
31
32	ObjSet hint_set = new ObjSet();
33	Obj hint = hint_set.CreateArray();
34	hint.PushBackName("JBIG2");
35	hint.PushBackName("Lossless");
36	hint.PushBackName("Threshold");
37	hint.PushBackNumber(0.4);
38	hint.PushBackName("SharePages");
39	hint.PushBackNumber(10000);
40
41	pdftron.PDF.Image new_image = pdftron.PDF.Image.Create(
42		cos_doc,
43		reader, 							
44		input_image.GetImageWidth(),
45		input_image.GetImageHeight(),
46		1,
47		ColorSpace.CreateDeviceGray(),
48		hint  // A hint to image encoder to use JBIG2 compression
49	);
50	cos_doc.Swap(i, new_image.GetSDFObj().GetObjNum());
51}
1PDFDoc doc(filename);
2SDFDoc& cos_doc = pdf_doc.GetSDFDoc();
3int num_objs = cos_doc.XRefSize();
4for(int i=1; i<num_objs; ++i) 
5{
6	Obj obj = cos_doc.GetObj(i);
7	if(!obj || obj.IsFree() || !obj.IsStream())
8		continue; 
9
10	// Process only images
11	DictIterator itr = obj.Find("Subtype");
12	if(!itr.HasNext() || strcmp(itr.Value().GetName(), "Image"))
13		continue;
14	
15	Image input_image(obj);
16
17	// Process only gray-scale images
18	if(input_image.GetComponentNum() != 1)
19		continue;
20
21	int bpc = input_image.GetBitsPerComponent();
22	if(bpc != 1)	// Recompress only 1 BPC images
23		continue;
24
25	// Skip images that are already compressed using JBIG2
26	itr = obj.Find("Filter");
27	if (itr.HasNext() && itr.Value().IsName() && !strcmp(itr.Value().GetName(), "JBIG2Decode")) 
28		continue; 
29
30	Filter filter=obj.GetDecodedStream();
31	FilterReader reader(filter);
32
33	ObjSet hint_set; 	// A hint to image encoder to use JBIG2 compression
34	Obj hint=hint_set.CreateArray();
35
36	hint.PushBackName("JBIG2");
37	hint.PushBackName("Lossless");
38
39	Image new_image = Image::Create(
40		cos_doc, 
41		reader, 
42		input_image.GetImageWidth(), 
43		input_image.GetImageHeight(), 
44		1, 
45		ColorSpace::CreateDeviceGray(), 
46		hint
47	);
48	cos_doc.Swap(i, new_img.GetSDFDoc().GetObjNum());
49}
1cosDoc := pdfDoc.GetSDFDoc()
2numObjs := cosDoc.XRefSize()
3
4i := uint(1)
5for i < numObjs{
6	obj := cosDoc.GetObj(i)
7	if obj != nil && ! obj.IsFree() && obj.IsStream(){
8		// Process only images
9		itr := obj.Find("Subtype")
10		//if not itr.HasNext() or not itr.Value().GetName() == "Image":
11		if !itr.HasNext() || !(itr.Value().GetName() == "Image"){
12			i = i + 1
13			continue
14		}
15		inputImage := NewImage(obj)
16		// Process only gray-scale images
17		if inputImage.GetComponentNum() != 1{
18			i = i + 1
19			continue
20		}
21		// Skip images that are already compressed using JBIG2
22		itr = obj.Find("Filter")
23		if (itr.HasNext() && itr.Value().IsName() && itr.Value().GetName() == "JBIG2Decode"){
24			i = i + 1
25			continue
26		}
27
28		filter := obj.GetDecodedStream()
29		reader := NewFilterReader(filter)
30		
31		hintSet := NewObjSet()     // hint to image encoder to use JBIG2 compression
32		hint := hintSet.CreateArray()
33		
34		hint.PushBackName("JBIG2")
35		hint.PushBackName("Lossless")
36		
37		newImage := (ImageCreate(cosDoc, reader, 
38											inputImage.GetImageWidth(), 
39											inputImage.GetImageHeight(), 
40											1, 
41											ColorSpaceCreateDeviceGray(), 
42											hint))
43		
44		newImgObj := newImage.GetSDFObj()
45		itr = obj.Find("Decode")
46		
47		if itr.HasNext(){
48			newImgObj.Put("Decode", itr.Value())
49		}
50		itr = obj.Find("ImageMask")
51		if itr.HasNext(){
52			newImgObj.Put("ImageMask", itr.Value())
53		}
54		itr = obj.Find("Mask")
55		if itr.HasNext(){
56			newImgObj.Put("Mask", itr.Value())
57		}
58
59		cosDoc.Swap(i, newImgObj.GetObjNum())
60	}
61	i = i + 1
62}
1PDFDoc doc = new PDFDoc(filename);
2SDFDoc cos_doc = pdf_doc.getSDFDoc();
3int num_objs = (int) cos_doc.xRefSize();
4for (int i = 1; i < num_objs; ++i) {
5	Obj obj = cos_doc.getObj(i);
6	if (obj == null || obj.isFree() || !obj.isStream())
7		continue;
8
9	// Process only images
10	DictIterator itr = obj.find("Subtype");
11	if (!itr.hasNext() || !itr.value().getName().equals("Image"))
12		continue;
13
14	Image input_image = new Image(obj);
15
16	// Process only gray-scale images
17	if (input_image.getComponentNum() != 1)
18		continue;
19
20	int bpc = input_image.getBitsPerComponent();
21	if (bpc != 1)    // Recompress only 1 BPC images
22		continue;
23
24	// Skip images that are already compressed using JBIG2
25	itr = obj.find("Filter");
26	if (itr.hasNext() && itr.value().isName() && !itr.value().getName().equals("JBIG2Decode")) 
27		continue;
28
29	Filter filter = obj.getDecodedStream();
30	FilterReader reader = new FilterReader(filter);
31
32	ObjSet hint_set = new ObjSet();
33	Obj hint = hint_set.createArray(); // A hint to image encoder to use JBIG2 compression
34	hint.pushBackName("JBIG2");
35	hint.pushBackName("Lossless");
36
37	Image new_image = Image.create(
38		cos_doc, reader,
39		input_image.getImageWidth(),
40		input_image.getImageHeight(), 
41		1, 
42		ColorSpace.createDeviceGray(), 
43		hint
44	);
45	cos_doc.swap(i, new_img.getSDFDoc().getObjNum());
46}
1async function main() {
2	const pdf_doc = await PDFNet.PDFDoc.createFromURL(filename);
3	pdf_doc.initSecurityHandler();
4
5	const cos_doc = await pdf_doc.getSDFDoc();
6	const num_objs = await cos_doc.xRefSize();
7	for (let i = 1; i < num_objs; ++i) {
8		const obj = await cos_doc.getObj(i);
9		if (obj && !(await obj.isFree()) && await obj.isStream()) {
10			// Process only images
11			var itr = await obj.find("Subtype");
12			if (!(await itr.hasNext()) || await (await itr.value()).getName() !== "Image")
13				continue;
14			const input_image = await PDFNet.Image.createFromObj(obj);
15			// Process only gray-scale images
16			if (await input_image.getComponentNum() != 1)
17				continue;
18			if (await input_image.getBitsPerComponent() != 1) // Recompress only 1 BPC images
19				continue;
20
21			// Skip images that are already compressed using JBIG2
22			itr = await obj.find("Filter");
23			if (await itr.hasNext()) {
24				const value = await itr.value();
25				if (await value.isName() && await value.getName() === "JBIG2Decode") continue;
26			}
27
28			const filter = await obj.getDecodedStream();
29			const reader = await PDFNet.FilterReader.create(filter);
30
31			const hint_set = await PDFNet.ObjSet.create();
32			const hint = await hint_set.createArray();
33
34			hint.pushBackName("JBIG2");
35			hint.pushBackName("Lossless");
36
37			const new_image = await PDFNet.Image.createFromStream(cos_doc, reader, await input_image.getImageWidth(),
38				await input_image.getImageHeight(), 1, await PDFNet.ColorSpace.createDeviceGray(), hint);
39
40			const new_img_obj = await new_image.getSDFObj();
41			itr = await obj.find("Decode");
42			if (await itr.hasNext())
43				new_img_obj.put("Decode", await itr.value());
44			itr = await obj.find("ImageMask");
45			if (await itr.hasNext())
46				new_img_obj.put("ImageMask", await itr.value());
47			itr = await obj.find("Mask");
48			if (await itr.hasNext())
49				new_img_obj.put("Mask", await itr.value());
50
51			await cos_doc.swap(i, await new_img_obj.getObjNum());
52		}
53	}
54}
55PDFNet.runWithCleanup(main);
1PTPDFDoc *doc = [[PTPDFDoc alloc] initWithFilepath: filename];
2PTSDFDoc *cos_doc = [pdf_doc GetSDFDoc];
3int num_objs = [cos_doc XRefSize];
4for(int i=1; i<num_objs; ++i) 
5{
6	PTObj * obj = [cos_doc GetObj: i];
7	if(!obj || [obj IsFree] || ![obj IsStream]) 
8		continue;
9	
10	// Process only images
11	PTDictIterator *itr = [obj Find: @"Subtype"];
12	if(![itr HasNext] || !([[[itr Value] GetName] isEqualToString:@"Image"]))
13		continue;
14	
15	PTImage *input_image = [[PTImage alloc] initWithImage_xobject: obj];
16
17	// Process only gray-scale images
18	if([input_image GetComponentNum] != 1)
19		continue;
20
21	int bpc = [input_image GetBitsPerComponent];
22	if(bpc != 1)	// Recompress only 1 BPC images
23		continue;
24
25	// Skip images that are already compressed using JBIG2
26	itr = [obj Find: @"Filter"];
27	if ([itr HasNext] && [[itr Value] IsName] && [[[itr Value] GetName] isEqualToString:@"JBIG2Decode"]) 
28		continue;
29
30	PTFilter *filter=[obj GetDecodedStream];
31	PTFilterReader *reader = [[PTFilterReader alloc] initWithFilter: filter];
32
33	PTObjSet *hint_set = [[PTObjSet alloc] init]; 	// A hint to image encoder to use JBIG2 compression
34	PTObj * hint=[hint_set CreateArray];
35
36	[hint PushBackName: @"JBIG2"];
37	[hint PushBackName: @"Lossless"];
38
39	PTImage *new_image = [PTImage CreateWithFilterData: cos_doc 
40											image_data: reader 
41												 width: [input_image GetImageWidth] 
42												height: [input_image GetImageHeight] 
43												   bpc: 1 
44										   color_space: [PTColorSpace CreateDeviceGray] 
45										 encoder_hints: hint];
46	[cos_doc Swap: i obj_num2: [[pdf_doc GetSDFDoc] GetObjNum]];
47}
1$doc = new PDFDoc($filename);
2$cos_doc = $pdf_doc->GetSDFDoc();
3$num_objs = $cos_doc->XRefSize();
4for($i = 1; $i < $num_objs; ++$i) 
5{
6	$obj = $cos_doc->GetObj($i);
7	if(!$obj || $obj->IsFree() || !$obj->IsStream())
8		continue; 
9
10	// Process only images
11	$itr = $obj->Find("Subtype");
12	if(!$itr->HasNext() || $itr->Value()->GetName() != "Image")
13		continue;
14	
15	$input_image = new Image($obj);
16
17	// Process only gray-scale images
18	if($input_image->GetComponentNum() != 1)
19		continue;
20
21	$bpc = $input_image->GetBitsPerComponent();
22	if($bpc != 1)	// Recompress only 1 BPC images
23		continue;
24
25	// Skip images that are already compressed using JBIG2
26	$itr = $obj->Find("Filter");
27	if ($itr->HasNext() && $itr->Value()->IsName() && $itr->Value()->GetName() == "JBIG2Decode") continue; 
28
29	$filter=$obj->GetDecodedStream();
30	$reader = new FilterReader($filter);
31
32	$hint_set = new ObjSet(); 	// A hint to image encoder to use JBIG2 compression
33	$hint=$hint_set->CreateArray();
34	
35	$hint->PushBackName("JBIG2");
36	$hint->PushBackName("Lossless");
37
38	$new_image = Image::Create(
39		$cos_doc, 
40		$reader, 
41		$input_image->GetImageWidth(), 
42		$input_image->GetImageHeight(), 
43		1, 
44		ColorSpace::CreateDeviceGray(), 
45		$hint
46	);
47	$cos_doc->Swap($i, $new_img->GetSDFDoc()->GetObjNum());
48}
1doc = PDFDoc(filename)
2cos_doc = pdf_doc.GetSDFDoc()
3num_objs = cos_doc.XRefSize()
4
5i = 1
6while i < num_objs:
7	obj = cos_doc.GetObj(i)
8	if obj is None or obj.IsFree() or not obj.IsStream():
9		i = i + 1
10		continue
11
12	# Process only images
13	itr = obj.Find("Subtype")
14	if not itr.HasNext() or not itr.Value().GetName() == "Image":
15		i = i + 1
16		continue
17		
18	input_image = Image(obj)
19
20	# Process only gray-scale images
21	if input_image.GetComponentNum() != 1:
22		i = i + 1
23		continue
24		
25	# Skip images that are already compressed using JBIG2
26	itr = obj.Find("Filter")
27	if (itr.HasNext() and itr.Value().IsName() and itr.Value().GetName() == "JBIG2Decode"):
28		i = i + 1
29		continue
30		
31	filter = obj.GetDecodedStream()
32	reader = FilterReader(filter)
33	
34	hint_set = ObjSet()     # hint to image encoder to use JBIG2 compression
35	hint = hint_set.CreateArray()
36	
37	hint.PushBackName("JBIG2")
38	hint.PushBackName("Lossless")
39	
40	new_image = Image.Create(
41		cos_doc, 
42		reader, 
43		input_image.GetImageWidth(), 
44		input_image.GetImageHeight(), 
45		1, 
46		ColorSpace.CreateDeviceGray(), 
47		hint
48	)
49	cos_doc.Swap(i, new_img.GetSDFDoc().GetObjNum())
50	i = i + 1
1doc = PDFDoc.new(filename)
2cos_doc = pdf_doc.GetSDFDoc
3num_objs = cos_doc.XRefSize
4i = 1
5while i < num_objs do
6	obj = cos_doc.GetObj(i)
7	if obj.nil? or obj.IsFree or !obj.IsStream
8		i = i + 1
9		next
10	end
11
12	# Process only images
13	itr = obj.Find("Subtype")
14	if !itr.HasNext or !itr.Value.GetName == "Image"
15		i = i + 1
16		next
17	end
18	
19	input_image = Image.new(obj)
20
21	# Process only gray-scale images
22	if input_image.GetComponentNum != 1
23		i = i + 1
24		next
25	end			
26
27	# Skip images that are already compressed using JBIG2
28	itr = obj.Find("Filter")
29	if itr.HasNext and itr.Value.IsName and itr.Value.GetName == "JBIG2Decode"
30		i = i + 1
31		next
32	end
33	
34	filter = obj.GetDecodedStream
35	reader = FilterReader.new(filter)
36	
37	hint_set = ObjSet.new	 # hint to image encoder to use JBIG2 compression
38	hint = hint_set.CreateArray
39	
40	hint.PushBackName("JBIG2")
41	hint.PushBackName("Lossless")
42	
43	new_image = Image.Create(
44		cos_doc, 
45		reader, 
46		input_image.GetImageWidth, 
47		input_image.GetImageHeight, 
48		1, 
49		ColorSpace.CreateDeviceGray, 
50		hint
51	)	
52	cos_doc.Swap(i, new_img.GetSDFDoc.GetObjNum)
53	i = i + 1
54end
1Dim doc As PDFDoc = New PDFDoc(filename)
2Dim cos_doc As SDFDoc = pdfdoc.GetSDFDoc()
3Dim num_objs As Integer = cos_doc.XRefSize()
4
5For i As Integer = 1 To num_objs - 1
6	Dim obj As Obj = cos_doc.GetObj(i)
7	If Not (obj Is Nothing Or obj.IsFree()) Then
8		' Process only images
9		If obj.IsStream() Then
10			Dim itr As DictIterator = obj.Find("Subtype")
11			If itr.HasNext() Then
12				If itr.Value().GetName() = "Image" Then
13					Dim input_image As pdftron.PDF.Image = New pdftron.PDF.Image(obj)
14					Dim new_image As pdftron.PDF.Image = Nothing
15
16					' Process only gray-scale images
17					If input_image.GetComponentNum() = 1 Then
18						Dim bpc As Integer = input_image.GetBitsPerComponent()
19						If bpc = 1 Then
20							Dim reader As FilterReader = New FilterReader(obj.GetDecodedStream())
21
22							Dim hint_set As ObjSet = New ObjSet
23							Dim hint As Obj = hint_set.CreateArray()
24							hint.PushBackName("JBIG2")
25							
26							' hint.PushBackName("Lossless")
27							hint.PushBackName("Threshold")
28							hint.PushBackNumber(0.4)
29							hint.PushBackName("SharePages")
30							hint.PushBackNumber(10000)
31
32							new_image = pdftron.PDF.Image.Create(
33								cos_doc, 
34								reader, 
35								input_image.GetImageWidth(), 
36								input_image.GetImageHeight(), 
37								1, 
38								ColorSpace.CreateDeviceGray(), 
39								hint
40							)
41							cos_doc.Swap(i, new_image.GetSDFObj().GetObjNum())
42						End If
43					End If
44				End If
45			End If
46		End If
47	End If
48Next
PDF image JBIG2 compression - Full Sample
Full sample code which illustrates how to recompress bitonal (black and white) images in existing PDF documents using JBIG2 compression.  Samples available in Python, C# (.Net), C++, Go, Java, Node.js (JavaScript), PHP, Ruby, VB.
Did you find this helpful?
Trial setup questions?
Ask experts on DiscordNeed other help?
Contact SupportPricing or product questions?
Contact Sales