To optimize a PDF with default settings.
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 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.
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 code which illustrates how to recompress bitonal (black and white) images in existing PDF documents using JBIG2 compression.
Did you find this helpful?
Trial setup questions?
Ask experts on DiscordNeed other help?
Contact SupportPricing or product questions?
Contact Sales