20 Getopt::Long::Configure("bundling");
23 my $usage = <<ENDUSAGE;
24 pdfstitch - Copyright (C) 2017 by Jakob Haufe <sur5r\@sur5r.net>
26 Usage: $0 [-hgpcs] [--genmeta] [--preview] [--crop] [--stitch] {PDF file|.stitch file}
28 -h, --help Display this message
29 -g, --genmeta Generate .stitch file for stitching based on given PDF
30 (default when called with a PDF)
31 -p, --preview Generate preview PDF containing overlays to analyze
33 -c, --crop Generate cropped PDF according to given .stitch
34 -s, --stitch Generate stitched PDF
35 (default when called with a .stitch file)
37 pdfstitch is free software under the GNU AGPL version 3. See LICENSE for details.
43 'g|genmeta' => \$genmeta,
44 'p|preview' => \$preview,
46 's|stitch' => \$stitch
47 ) or die "Call with --help to see available options.\n";
51 die "--genmeta can not be combined with other actions!\n" if($genmeta and ($preview or $crop or $stitch));
53 die "No input file specified!\n" unless $ARGV[0];
55 my $infile = $ARGV[0];
57 die "$infile does not exist!\n" unless -e $infile;
58 die "$infile is not readable!\n" unless -r $infile;
60 if(not ($genmeta or $preview or $crop or $stitch))
62 my $magic = File::LibMagic->new();
64 my $info = $magic->info_from_filename($infile);
65 if($info->{mime_type} eq "application/pdf")
67 print "Detected PDF, turning on --genmeta\n";
70 elsif ($info->{mime_type} eq "text/plain")
72 YAML::LoadFile($infile) or die "Failed to parse $infile as YAML!\n";
73 print "Detected YAML, turning on --stitch\n";
78 die "$infile has unsupported type: $info->{mime_type}\n";
84 print "Generating meta file for " . basename($infile) . ".\n";
85 my $outfile = basename($infile) . ".stitch";
87 die "$outfile exists, aborting!\n" if -e $outfile;
90 my $pdf = PDF::API2->open($infile);
92 my $page = $pdf->openpage(1);
93 my ($llx, $lly, $urx, $ury) = $page->get_mediabox;
96 input => basename($infile),
97 x => (($urx - $llx)*0.1)/2,
98 y => (($ury - $lly)*0.1)/2,
99 width => ($urx - $llx)*0.9,
100 height => ($ury - $lly)*0.9,
101 columns => int(sqrt($pdf->pages)),
102 rows => int(sqrt($pdf->pages)),
103 pageorder => [(1 .. $pdf->pages)],
106 foreach $page (1..$pdf->pages)
108 $meta->{pageoffsets}->{$page}->{x} = 0;
109 $meta->{pageoffsets}->{$page}->{y} = 0;
112 YAML::Bless($meta)->keys(['input','x','y','width','height','columns','rows', 'pageorder','pageoffsets']);
113 YAML::DumpFile($outfile,$meta);
117 my $meta = YAML::LoadFile($infile);
118 my $inpdf = PDF::API2->open($meta->{input});
120 if($preview or $crop)
122 my $previewpdf = PDF::API2->new() if $preview;
123 my $croppedpdf = PDF::API2->new() if $crop;
128 $transparency = $previewpdf->egstate();
129 $transparency->transparency(0.8);
132 foreach my $pagenr (@{$meta->{pageorder}})
134 next if $pagenr eq "blank";
136 my $llx = $meta->{x} + $meta->{pageoffsets}->{$pagenr}->{x};
137 my $lly = $meta->{y} + $meta->{pageoffsets}->{$pagenr}->{x};
138 my $urx = $meta->{width};
139 my $ury = $meta->{height};
143 my $previewpage = $previewpdf->import_page($inpdf, $pagenr, 0);
144 my $previewcontent = $previewpage->gfx();
145 $previewcontent->egstate($transparency);
146 $previewcontent->rect($llx, $lly, $urx, $ury);
147 $previewcontent->fillcolor('%F000');
148 $previewcontent->fill();
152 my $croppage = $croppedpdf->import_page($inpdf, $pagenr, 0);
153 $croppage->cropbox($llx, $lly, $llx + $urx, $lly + $ury);
157 $previewpdf->saveas(basename($infile, ('.pdf.stitch', '.stitch')) . '-preview.pdf') if $preview;
158 $croppedpdf->saveas(basename($infile, ('.pdf.stitch', '.stitch')) . '-cropped.pdf') if $crop;
163 my $width = $meta->{width} * $meta->{columns};
164 my $height = $meta->{height} * $meta->{rows};
166 my $stitchedpdf = PDF::API2->new();
168 my $page = $stitchedpdf->page();
169 $page->mediabox($width + 100, $height + 100);
171 my $content = $page->gfx();
175 foreach my $pagenr (@{$meta->{pageorder}})
177 if($pagenr ne "blank")
179 my $xo = $stitchedpdf->importPageIntoForm($inpdf, $pagenr);
181 my $llx = $meta->{x} + $meta->{pageoffsets}->{$pagenr}->{x};
182 my $lly = $meta->{y} + $meta->{pageoffsets}->{$pagenr}->{y};
183 my $urx = $llx + $meta->{width};
184 my $ury = $lly + $meta->{height};
186 $xo->bbox($llx, $lly, $urx, $ury);
188 my $xpos = ($column - 1) * $meta->{width};
189 my $ypos = $height - ($row * $meta->{height});
190 $content->formimage($xo, $xpos, $ypos);
193 if($column > $meta->{columns})
200 $stitchedpdf->saveas(basename($infile, ('.pdf.stitch','.stitch')) . '-stitched.pdf');