libvips / php-vips

php binding for libvips
MIT License
618 stars 25 forks source link

Thumbnailing PDF - width parameter seems to be passed as height #168

Closed craig410 closed 2 years ago

craig410 commented 2 years ago

Firstly, I may be misunderstanding something as I'm relatively new to vips.

It seems as though when thumbnailing PDFs using the PHP wrapper, the width parameter is being passed as height. It doesn't matter if the output type is PNG or JPEG and it only seems to be affecting PDF inputs. Tested with several different single-page A4 PDFs and consistently get the same results. Example PDF attached

Running vips version vips-8.13.3-Tue Nov 1 09:09:54 UTC 2022

vipsthumbnail -s '1000x' input.pdf[dpi=150] -o output.png --vips-info

results in a thumbnail with a width of 1000px (expectedly)

VIPS-INFO: thumbnailing input.pdf[dpi=150]
VIPS-INFO: selected loader is VipsForeignLoadPdfFile
VIPS-INFO: input size is 1240 x 1754
VIPS-INFO: loading with factor 1.24 pre-shrink
VIPS-INFO: pre-shrunk size is 1000 x 1415
VIPS-INFO: converting to processing space srgb
VIPS-INFO: converting to output space srgb
VIPS-INFO: thumbnailing input.pdf[dpi=150] as ./output.png

while running with the PHP wrapper:

Image::thumbnail(__DIR__.'/input.pdf[dpi=150]', 1000)->writeToFile(__DIR__.'/output.png');

results in a thumbnail with a height of 1000px

debug: thumbnail {"instance":null,"arguments":["/var/www/input.pdf[dpi=150]",1000]}
debug: init {"library":"libvips.so.42"}
debug: init {"path":""}
debug: init {"vips_init":0}
debug: init {"libvips version":[8,13,3]}
debug: init ["binding ..."]
debug: init ["done"]
debug: thumbnail {"introspect":"thumbnail:\n  filename:\n    flags: 19\n      REQUIRED\n      CONSTRUCT\n      INPUT\n    blurb: Filename to read from\n    type: gchararray\n  out:\n    flags: 35\n      REQUIRED\n      CONSTRUCT\n      OUTPUT\n    blurb: Output image\n    type: VipsImage\n  width:\n    flags: 19\n      REQUIRED\n      CONSTRUCT\n      INPUT\n    blurb: Size to this width\n    type: gint\n  height:\n    flags: 18\n      CONSTRUCT\n      INPUT\n    blurb: Size to this height\n    type: gint\n  size:\n    flags: 18\n      CONSTRUCT\n      INPUT\n    blurb: Only upsize, only downsize, or both\n    type: VipsSize\n  no_rotate:\n    flags: 18\n      CONSTRUCT\n      INPUT\n    blurb: Don't use orientation tags to rotate image upright\n    type: gboolean\n  crop:\n    flags: 18\n      CONSTRUCT\n      INPUT\n    blurb: Reduce to fill target rectangle, then crop\n    type: VipsInteresting\n  linear:\n    flags: 18\n      CONSTRUCT\n      INPUT\n    blurb: Reduce in linear light\n    type: gboolean\n  import_profile:\n    flags: 18\n      CONSTRUCT\n      INPUT\n    blurb: Fallback import profile\n    type: gchararray\n  export_profile:\n    flags: 18\n      CONSTRUCT\n      INPUT\n    blurb: Fallback export profile\n    type: gchararray\n  intent:\n    flags: 18\n      CONSTRUCT\n      INPUT\n    blurb: Rendering intent\n    type: VipsIntent\n  auto_rotate:\n    flags: 82\n      CONSTRUCT\n      INPUT\n      DEPRECATED\n    blurb: Use orientation tags to rotate image upright\n    type: gboolean\n  fail_on:\n    flags: 18\n      CONSTRUCT\n      INPUT\n    blurb: Error level to fail on\n    type: VipsFailOn\nrequired input: filename, width\nrequired output: out\noptional input: height, size, no_rotate, crop, linear, import_profile, export_profile, intent, auto_rotate, fail_on\noptional output: \nmember_this: \nmethod args: filename, width\n"}
debug: set {"filename":"/var/www/input.pdf[dpi=150]"}
debug: set {"width":1000}
debug: get {"out":"Jcupitt\\Vips\\Image::__set_state(array(\n   'pointer' => \n  FFI\\CData::__set_state(array(\n  )),\n   'gObject' => \n  FFI\\CData::__set_state(array(\n  )),\n   'pointer' => \n  FFI\\CData::__set_state(array(\n  )),\n   'pointer' => \n  FFI\\CData::__set_state(array(\n  )),\n))"}
debug: thumbnail {"result":"Jcupitt\\Vips\\Image::__set_state(array(\n   'pointer' => \n  FFI\\CData::__set_state(array(\n  )),\n   'gObject' => \n  FFI\\CData::__set_state(array(\n  )),\n   'pointer' => \n  FFI\\CData::__set_state(array(\n  )),\n   'pointer' => \n  FFI\\CData::__set_state(array(\n  )),\n))"}
debug: VipsForeignSavePngFile {"instance":"{\"width\":707,\"height\":1000,\"bands\":4,\"format\":\"uchar\",\"interpretation\":\"srgb\"}","arguments":["/var/www/output.png",[]]}
debug: VipsForeignSavePngFile {"introspect":"VipsForeignSavePngFile:\n  in:\n    flags: 19\n      REQUIRED\n      CONSTRUCT\n      INPUT\n    blurb: Image to save\n    type: VipsImage\n  filename:\n    flags: 19\n      REQUIRED\n      CONSTRUCT\n      INPUT\n    blurb: Filename to save to\n    type: gchararray\n  compression:\n    flags: 18\n      CONSTRUCT\n      INPUT\n    blurb: Compression factor\n    type: gint\n  interlace:\n    flags: 18\n      CONSTRUCT\n      INPUT\n    blurb: Interlace image\n    type: gboolean\n  profile:\n    flags: 18\n      CONSTRUCT\n      INPUT\n    blurb: ICC profile to embed\n    type: gchararray\n  filter:\n    flags: 18\n      CONSTRUCT\n      INPUT\n    blurb: libpng row filter flag(s)\n    type: VipsForeignPngFilter\n  palette:\n    flags: 18\n      CONSTRUCT\n      INPUT\n    blurb: Quantise to 8bpp palette\n    type: gboolean\n  colours:\n    flags: 82\n      CONSTRUCT\n      INPUT\n      DEPRECATED\n    blurb: Max number of palette colours\n    type: gint\n  Q:\n    flags: 18\n      CONSTRUCT\n      INPUT\n    blurb: Quantisation quality\n    type: gint\n  dither:\n    flags: 18\n      CONSTRUCT\n      INPUT\n    blurb: Amount of dithering\n    type: gdouble\n  bitdepth:\n    flags: 18\n      CONSTRUCT\n      INPUT\n    blurb: Write as a 1, 2, 4, 8 or 16 bit image\n    type: gint\n  effort:\n    flags: 18\n      CONSTRUCT\n      INPUT\n    blurb: Quantisation CPU effort\n    type: gint\n  strip:\n    flags: 18\n      CONSTRUCT\n      INPUT\n    blurb: Strip all metadata from image\n    type: gboolean\n  background:\n    flags: 18\n      CONSTRUCT\n      INPUT\n    blurb: Background value\n    type: VipsArrayDouble\n  page_height:\n    flags: 18\n      CONSTRUCT\n      INPUT\n    blurb: Set page height for multipage save\n    type: gint\nrequired input: in, filename\nrequired output: \noptional input: compression, interlace, profile, filter, palette, colours, Q, dither, bitdepth, effort, strip, background, page_height\noptional output: \nmember_this: in\nmethod args: \n"}
debug: set {"in":"{\"width\":707,\"height\":1000,\"bands\":4,\"format\":\"uchar\",\"interpretation\":\"srgb\"}"}
debug: set {"filename":"/var/www/output.png"}
debug: VipsForeignSavePngFile {"result":"array (\n)"}

test_fonts.pdf

craig410 commented 2 years ago

I have just discovered https://github.com/libvips/ruby-vips/commit/54dab5a84ddb9d173ba018db7910d1832c83ec76 and the issues it was discussed in. There doesn't appear to be a similar constant in the PHP wrapper, however

Image::thumbnail(__DIR__.'/input.pdf[dpi=150]', 1000, ['height'=>10_000_000])->writeToFile(__DIR__.'/output.png');

has the desired effect and behaves like -s 1000x rather than -s 1000

jcupitt commented 2 years ago

Hi @craig410, that's right, just use a huge number for height.