Я изменил pdfdraw mupdf для поддержки рисования в режиме наилучшего соответствия, поэтому я могу утверждать, что вывод должен быть максимально 128x128, и он будет соответствовать выводу в окне, сохраняя соотношение сторон. До того, как я это сделал, единственным способом было использовать pdfinfo, чтобы получить размер страницы, а затем выполнить вычисления, чтобы уместить ее в поле, а затем попросить pdfdraw нарисовать ее с этим масштабным коэффициентом (точек на дюйм).
Что ж, после этого длинного рассказа процесс сделать это довольно прост:
получить размер страницы для отображения (в терминах pdf - медиа-блок), это можно сделать через pdfinfo и grep и отобразить в точках (точки, 1/72 дюйма) или через pdf-библиотеку, такую как pyPDF, например:
import pyPdf
p = pyPdf.PdfFileReader(file("/home/dan/Desktop/Sieve-JFP.pdf", "rb"))
x,y,w,h = p.pages[0]['/MediaBox']
для коробки подходят dpi = min( A/(w/72.), B/(h/72.) )
где A
- максимальная ширина, а B
- максимальная высота; w
и h
- ширина и высота страницы.
- передайте
dpi
для convert -density $dpi
и, как и требовалось, слегка обманутый git commit diff:
commit 0000000000000000000000000000000000000000
Author: Dan D.
Date: Thu Jul 28 16:33:33 2011 -0400
add options to pdfdraw to limit the output's width and height
note that scaling must occur before rotation
diff --git a/apps/pdfdraw.c b/apps/pdfdraw.c
index 0000000..1234567 100644
--- a/apps/pdfdraw.c
+++ b/apps/pdfdraw.c
@@ -12,8 +12,10 @@
#endif
char *output = NULL;
-float resolution = 72;
+float resolution = -1;
float rotation = 0;
+float width = -1;
+float height = -1;
int showxml = 0;
int showtext = 0;
@@ -47,6 +49,8 @@ static void usage(void)
"\t\tsupported formats: pgm, ppm, pam, png, pbm\n"
"\t-p -\tpassword\n"
"\t-r -\tresolution in dpi (default: 72)\n"
+ "\t-w -\tmaximum width (default: no limit)\n"
+ "\t-h -\tmaximum height (default: no limit)\n"
"\t-A\tdisable accelerated functions\n"
"\t-a\tsave alpha channel (only pam and png)\n"
"\t-b -\tnumber of bits of antialiasing (0 to 8)\n"
@@ -150,13 +154,39 @@ static void drawpage(pdf_xref *xref, int pagenum)
if (output || showmd5 || showtime)
{
- float zoom;
+ float zoom = 1.0;
fz_matrix ctm;
fz_bbox bbox;
fz_pixmap *pix;
+ float W, H;
- zoom = resolution / 72;
- ctm = fz_translate(0, -page->mediabox.y1);
+ ctm = fz_identity;
+ ctm = fz_concat(ctm, fz_translate(0, -page->mediabox.y1));
+ ctm = fz_concat(ctm, fz_rotate(page->rotate));
+ ctm = fz_concat(ctm, fz_rotate(rotation));
+ bbox = fz_round_rect(fz_transform_rect(ctm, page->mediabox));
+
+ W = bbox.x1 - bbox.x0;
+ H = bbox.y1 - bbox.y0;
+ if (resolution != -1)
+ zoom = resolution / 72;
+ if (width != -1)
+ {
+ if (resolution != -1)
+ zoom = MIN(zoom, width/W);
+ else
+ zoom = width/W;
+ }
+ if (height != -1)
+ {
+ if (resolution != -1 || width != -1)
+ zoom = MIN(zoom, height/H);
+ else
+ zoom = height/H;
+ }
+
+ ctm = fz_identity;
+ ctm = fz_concat(ctm, fz_translate(0, -page->mediabox.y1));
ctm = fz_concat(ctm, fz_scale(zoom, -zoom));
ctm = fz_concat(ctm, fz_rotate(page->rotate));
ctm = fz_concat(ctm, fz_rotate(rotation));
@@ -295,7 +325,7 @@ int main(int argc, char **argv)
fz_error error;
int c;
- while ((c = fz_getopt(argc, argv, "o:p:r:R:Aab:dgmtx5")) != -1)
+ while ((c = fz_getopt(argc, argv, "o:p:r:R:w:h:Aab:dgmtx5")) != -1)
{
switch (c)
{
@@ -303,6 +333,8 @@ int main(int argc, char **argv)
case 'p': password = fz_optarg; break;
case 'r': resolution = atof(fz_optarg); break;
case 'R': rotation = atof(fz_optarg); break;
+ case 'w': width = atof(fz_optarg); break;
+ case 'h': height = atof(fz_optarg); break;
case 'A': accelerate = 0; break;
case 'a': savealpha = 1; break;
case 'b': alphabits = atoi(fz_optarg); break;
@@ -321,6 +353,10 @@ int main(int argc, char **argv)
if (fz_optind == argc)
usage();
+ if (width+height == -2)
+ if (resolution == -1)
+ resolution = 72;
+
if (!showtext && !showxml && !showtime && !showmd5 && !output)
{
printf("nothing to do\n");