coherentgraphics / cpdf-binaries

PDF Command Line Tools binaries for Linux, Mac, Windows
GNU Affero General Public License v3.0
593 stars 42 forks source link

Introduce a built-in feature to uniformly scale all pages within a PDF document to a user-specified page size #89

Open cassiuscai opened 3 months ago

cassiuscai commented 3 months ago

It would be great to have a built-in option in your PDF scaling tool that combines the --scale-page and --scale-to-fit options with automatic calculation of the scale ratio based on the PDF's width and height. This new feature could be invoked using the following command:

cpdf --scale-page-to-fit x_pts y_pts input.pdf -o out.pdf

Below is a Fish shell script I've created that performs the same task; however, it relies on multiple dependencies, which can be cumbersome. I utilize this script to scale or adjust the zoom level of my PDF files, ensuring they perfectly fit the dimensions of my iPad's screen and eliminating any unsightly black borders.

# pdf-scale is a function with definition
# Defined in /Users/casc/.config/fish/functions/pdf-scale.fish @ line 1
function pdf-scale
  if test (count $argv) -gt 2
    set -f inputfile $argv[3]
    # Get pdf file origin size
    set -l dx (pdf-width  $inputfile | sed 's/^[ \t]*//')
    set -l dy (pdf-height $inputfile | sed 's/^[ \t]*//')

    # Calc scale ratio
    set -l tx (echo $argv[1] | sed 's/^[ \t]*//')
    set -l ty (echo $argv[2] | sed 's/^[ \t]*//')

    set -l sx (math $tx / $dx)
    set -l sy (math $ty / $dy)

    # Set output file and convert
    set -f outfile (echo $argv[1]x$argv[2] - (basename $inputfile .pdf).pdf)
    if test (count $argv) -gt 3
      set -f outfile $argv[4]
    end

    show-line '-'
    echo Origin Page Size\t \| $dx \tx\t $dy pts
    echo Scaled Page Size\t \| $tx \t\tx\t $ty pts
    echo Scaled Page Ratio\t \| $sx \tx\t $sy
    echo Scaled Output File\t \| $outfile

    set -f scalePageFile (echo $TMPDIR/'scale-page'-$inputfile)

    begin
      cpdf -scale-page "$sx $sy" $inputfile -o $scalePageFile
      cpdf -scale-to-fit "$argv[1] $argv[2]" $scalePageFile -o $outfile
      rm -rf $scalePageFile
    end &> /dev/null
    show-result "Scale File" $outfile
  else
    echo "Usage: pdf-scale <width_in_pts> <height_in_pts> <input.pdf> [output.pdf]"
  end
end
johnwhitington commented 3 months ago

Can you explain more about what this does? The existing -scale-to-fit does "automatic calculation of the scale ratio based on the PDF's width and height" so I'm not sure what is different here... Can you give an example?

cassiuscai commented 3 months ago

I'm demonstrating the significant variations in PDF content manipulation approaches using a square image as an example.

  1. Original PDF: The initial document has dimensions of 672x672 pixels, as shown below:
origin.pdf
  1. Scaling Issue: Using the command cpdf --scale-to-fit '820 1180' led to unintended results. The content was resized to fit within an 820x1180 bounding box; however, this introduced additional blank spaces above and below the original image, which was not the desired outcome:
scala-to-fit.png
  1. Custom Script Improvement: Implementing a custom script yielded a more favorable result. The script independently scales the image's width and height before resizing it to the final page size, effectively avoiding any unnecessary whitespace: scale and then fit page size
johnwhitington commented 3 months ago

Got it. Thanks.

strauhmanis commented 3 months ago

Attached is an example of terminology used in Affinity Publisher. Perhaps this may be helpful:

Affinity Publisher Screenshot