Eu modifiquei o pdfdraw do mupdf para suportar desenho no modo de melhor ajuste, então eu poderia afirmar que a saída precisava ser no máximo 128x128 e caberia na saída na caixa enquanto mantinha a relação de aspecto. Antes de fazer isso, a única maneira era usar o pdfinfo para obter o tamanho da página e depois fazer os cálculos para ajustá-lo em uma caixa e, em seguida, pedir ao pdfdraw para desenhá-lo com esse fator de escala (pontos por polegada).
Bem, depois dessa longa história, o processo para fazer isso é bastante simples:
-
obtenha o tamanho de página da página para renderizar (em termos de pdf a caixa de mídia) isso pode ser feito via pdfinfo e grep e aparecerá em pts (pontos, 1/72 de polegada) ou via uma biblioteca de pdf como pyPDF como:
import pyPdf p = pyPdf.PdfFileReader(file("/home/dan/Desktop/Sieve-JFP.pdf", "rb")) x,y,w,h = p.pages[0]['/MediaBox']
-
para um ajuste de caixa do
dpi = min( A/(w/72.), B/(h/72.) )
ondeA
é a largura máxima eB
é a altura máxima;w
eh
são a largura e a altura da página. - passar
dpi
paraconvert -density $dpi
e conforme solicitado, um diff de confirmação do git ligeiramente falsificado:
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");