แปลงภาพเป็น pdf: วิธีทำให้หน้า PDF มีขนาดเท่ากัน


45

ฉันทำอะไรที่ชอบ

convert -page A4 -compress A4 *.png CH00.pdf

แต่หน้าแรกนั้นใหญ่กว่าหน้าต่อ ๆ ไป สิ่งนี้เกิดขึ้นแม้ว่าขนาดของภาพจะคล้ายกัน รูปภาพเหล่านี้ถูกสแกน & ครอบตัดดังนั้นอาจมีความแตกต่างของขนาดเล็กน้อย

ฉันคิดว่า-page A4ควรแก้ไขขนาดของหน้า?

คำตอบ:


60

ครั้งสุดท้ายที่ฉันใช้งานconvertดังกล่าวฉันระบุขนาดของปลายทางอย่างชัดเจนด้วยการปรับขนาด:

$ i=150; convert a.png b.png -compress jpeg -quality 70 \
      -density ${i}x${i} -units PixelsPerInch \
      -resize $((i*827/100))x$((i*1169/100)) \
      -repage $((i*827/100))x$((i*1169/100)) multipage.pdf

convertคำสั่งไม่เคยใช้DPIความหนาแน่นเริ่มต้น / ยูนิตรูปแบบหน้าทำให้เราระบุอย่างชัดเจน DPI กับ-unitsตัวเลือก (มิฉะนั้นคุณอาจได้รับผลลัพธ์ที่แตกต่างกับรุ่นที่แตกต่างกัน / การผสมรูปแบบการป้อน) ขนาดใหม่ (ระบุผ่าน-resize) คือขนาดของหน้า DIN A4 เป็นพิกเซล อาร์กิวเมนต์ปรับขนาดระบุขนาดหน้าสูงสุด ความละเอียดและคุณภาพในการเลือกขึ้นอยู่กับกรณีการใช้งาน - ฉันเลือก 150 DPIและคุณภาพเฉลี่ยเพื่อประหยัดพื้นที่ในขณะที่ไม่ได้ดูแย่เกินไปเมื่อพิมพ์บนกระดาษ

โปรดทราบว่าconvertโดยค่าเริ่มต้นจะไม่เปลี่ยนอัตราส่วนภาพด้วยการดำเนินการปรับขนาด:

ปรับขนาดจะพอดีกับภาพในขนาดที่ร้องขอ มันไม่ได้เติมขนาดกล่องที่ร้องขอ

( คู่มือ ImageMagick )

ขึ้นอยู่กับเวอร์ชั่นของ ImageMagick และรูปแบบอินพุตที่เกี่ยวข้องอาจไม่-repageสามารถเลือกได้ แต่บางครั้งก็จำเป็นและไม่มีตัวเลือกส่วนหัว PDF อาจมีขนาดเล็กเกินไป ไม่ว่าในกรณีใด-repageไม่ควรเจ็บตัว

การคำนวณใช้เลขคณิตจำนวนเต็มเนื่องจากbashสนับสนุนเท่านั้น ด้วยzshการแสดงออกได้ง่าย - $((i*8.27))x$((i*11.69))แทนที่คือมี

รูปภาพ Lineart

หาก PNG ไฟล์ที่มีสองระดับ (สีดำและสีขาวอาคา lineart) ภาพแล้วimg2pdfเครื่องมือให้ผลลัพธ์ที่เหนือกว่า convertImageMagick นั่นหมายความว่าimg2pdfเร็วขึ้นและให้ PDF ที่เล็กลง

ตัวอย่าง:

$ img2pdf -o multipage.pdf a.png b.png

หรือ:

$ img2pdf --pagesize A4 -o multipage.pdf a.png b.png

2
เมื่อใช้-repage a4ฉันจะได้รับinvalid argument for option '-repage': a4
Scolytus

1
@Scolytus บนระบบ Fedora 19 ฉันพบปัญหาคล้าย ๆ กัน - ดูเหมือนว่า-repageจะไม่รองรับชื่อ a4 อีกต่อไป ฉันได้แก้ไขสิ่งนี้ผ่านการคำนวณทางคณิตศาสตร์ของเชลล์:-repage $((150*8.27))x$((150*11.69))
maxschlepzig

ฉันคิดว่าตัวเลขเวทย์มนตร์นั้นมีความละเอียด 150dpi และ A4 แสดงเป็นหน่วยดั้งเดิมหรือไม่
Michael Scheper

@MichaelScheper ใช่ dpi และนิ้ว
maxschlepzig

ขอบคุณช่วยด้วย จริงๆแล้วการ-density 150โต้เถียงเป็นสิ่งสำคัญที่จะเพิ่ม
dma_k

23

สิ่งที่คุณต้องการใช้คือ:

$ convert a.png b.png -compress jpeg -resize 1240x1753 \
                      -extent 1240x1753 -gravity center \
                      -units PixelsPerInch -density 150x150 multipage.pdf

-extentจริงขยายภาพที่จะเป็น 1240x1753 ในขณะที่-resizeช่วยให้อัตราส่วนของภาพที่เหมาะสมลงในทั้งสองหรือ1240x......x1753

-gravityพารามิเตอร์เป็นตัวเลือก แต่สามารถใช้ศูนย์ภาพเมื่อขยาย


1
ขอขอบคุณ! -extentเป็นสิ่งที่ฉันต้องการใช้จริง ๆ :) - ได้โปรดเพิ่มเครื่องหมายคำพูดซ้ายไว้ด้านหน้า - ข้อความขอบคุณ!
บราวน์

ขอบคุณฉันได้เพิ่มขีดที่หายไปในที่สุด! ;-)
caugner

9

นอกจากคำตอบของ caugner :

หลังจากติดตั้ง IM v6.6.9-7 แล้วฉันพบว่า-gravityพารามิเตอร์ต้องอยู่ระหว่าง-resizeและ-extentเพื่อให้มีผล

นอกจากนี้ (ไม่ได้เป็นส่วนหนึ่งของคำถาม op) ฉันพบว่าการตั้งค่าการดึงดูดสีพื้นหลังที่แตกต่างกันซึ่งจะส่งผลให้คำสั่งทั้งหมดของ

convert in.jpg -resize 1240x1750 -background black -compose Copy\
               -gravity center -extent 1240x1750\
               -units PixelsPerInch -density 150 out.pdf

รูปแบบที่มีประโยชน์อื่นที่ฉันมักจะใช้เมื่อฉันไม่ต้องการปรับขนาดภาพที่มีอัตราส่วนกว้างยาวที่ถูกต้องแล้ว แต่ยังคงความละเอียดของแต่ละบุคคลไว้

convert in.jpg -units PixelsPerInch -set density '%[fx:w/8.27]'\
               -repage a4 out.pdf

โดยที่ความหนาแน่นเป้าหมายจะถูกกำหนดแบบไดนามิกโดยการคำนวณความกว้างหารด้วย 8.27 (ซึ่งเป็นความกว้างเป็นนิ้วของหน้า A4) -repage a4พารามิเตอร์สามารถละเว้นมากที่สุดของเวลา แต่ฉันมีบางกรณีที่ .pdf ส่งผลให้จะมีรูปแบบที่แตกต่างกันออก sligtly ขนาด A4 ของ 210x297mm (8.27x11.6" )


2

ฉันพบว่าโค้ดของ Mikher มีประโยชน์มาก แต่มันก็วางไฟล์ PDF ทั้งหมดเหมือน Portrait หรือ Landscape ดังนั้นฉันจึงปรับเปลี่ยนเพื่อตรวจสอบเลย์เอาต์ของไฟล์อินพุตแต่ละไฟล์และจับคู่กับเอาต์พุต

ฉันไม่ได้รวมการแก้ไขของ Yotam เพราะมันไม่ทำงานบนกล่อง Ubuntu 15.04 ของฉัน

$#!/bin/bash

# Resizes files to A4 (or other size - change PaperWdthMetr and PaperHghtMetr below) and merges into a PDF

export LOCALE=C

[[ "${2}x" == "x" ]] && \
 { echo "Usage: $( basename $0 ) output.pdf extension"
   echo "       merges all files (*.extension) into a single PDF"
   echo "If files z_merged.pdf, z_temp.pdf or $1 exist, they will be overwritten"
 exit 1
 } || \
 OutName="$1"
 ext="$2"

# Set basic variables
unset Debug #; Debug="yes" # print extra messages
IMBackground="white"      # what colour for paper
IMQuality="91"            # JPEG compression level
PaperHghtMetr="297"       # milimeters, 297 for ISO A4
PaperWdthMetr="210"       # milimeters, 210 for ISO A4
PaperDens="200"           # maximum (wanted) dpi for a page
PaperHInch=$( echo scale=5\; $PaperHghtMetr / 2.54 / 10      | bc -l ) # Inch
PaperWInch=$( echo scale=5\; $PaperWdthMetr / 2.54 / 10      | bc -l ) # Inch
PaperRtio=$(     echo scale=5\; $PaperWdthMetr / $PaperHghtMetr | bc -l )

# Remove temporary files from prior run
rm -rf z_merged.pdf z_temp.pdf 2>/dev/null

# Process any $ext file in the current directory
find . -maxdepth 1 -name "*.${ext}" -print0 | sort -z | while read -d '' -r FName
do
  echo "Converting $FName"
  ImgIdentify=$( identify -format "%w %h" "$FName" )
  ImgWdthOrig=$( echo $ImgIdentify | cut -d" " -f1  )
  ImgHghtOrig=$( echo $ImgIdentify | cut -d" " -f2  )
  ImgRtio=$( echo "scale=5; $ImgWdthOrig / $ImgHghtOrig"  | bc -l )


# Match output page layout - Landscape or Portrait - to input file
  if (( $(echo "$ImgRtio > 1 && $PaperRtio > 1 || $ImgRtio < 1 && $PaperRtio < 1" |bc -l) )); then
    echo "Portrait"
    PaperHghtInch=$PaperHInch
    PaperWdthInch=$PaperWInch
  else
    echo "Landscape"
    PaperHghtInch=$PaperWInch
    PaperWdthInch=$PaperHInch
  fi


  [[ $( echo $ImgRtio'>'$PaperRtio | bc -l ) == 1 ]] \
    && ImgDens=$( echo scale=0\; $ImgWdthOrig / $PaperWdthInch | bc -l ) \
    || ImgDens=$( echo scale=0\; $ImgHghtOrig / $PaperHghtInch | bc -l )
  [[ $Debug ]] && echo "ImgDens1: $ImgDens"
  [[ $( echo $ImgDens'>'$PaperDens | bc -l ) == 1 ]] \
    && ImgDens=$PaperDens
  [[ $Debug ]] && echo "ImgDens2: $ImgDens"

  ImgWdth=$( echo $PaperWdthInch \* $ImgDens | bc -l ) # pixels
  ImgHght=$( echo $PaperHghtInch \* $ImgDens | bc -l ) # pixels

  [[ $Debug ]] && echo "ImgWdth: $ImgWdth".
  [[ $Debug ]] && echo "ImgHght: $ImgHght".

  convert "${FName}"                                 \
          -resize ${ImgWdth}x${ImgHght}              \
          -background $IMBackground -gravity center  \
          -extent ${ImgWdth}x${ImgHght}              \
          -units PixelsPerInch -set density $ImgDens \
          -repage ${ImgWdth}x${ImgHght}+0+0          \
          -compress JPEG                             \
          -quality $IMQuality                        \
          "${FName%.$ext}.pdf"

  # Merge new PDF page with prior pages
  [[ -f z_merged.pdf ]] && \
   { pdftk z_merged.pdf "${FName%.$ext}.pdf" cat output z_temp.pdf
     mv z_temp.pdf z_merged.pdf
   } || \
     cp "${FName%.$ext}.pdf" z_merged.pdf
  [[ $Debug ]] || rm -rf "${FName%.$ext}.pdf"
done

[[ -f z_merged.pdf ]] && mv z_merged.pdf "$OutName"
echo "Done."

2

ฉันพบว่าสคริปต์ต่อไปนี้สะดวกซึ่งรวมคำตอบที่ระบุไว้ที่นี่และปัญหาบางอย่างที่ฉันมีกับการคำนวณจุดลอยตัว:

endInputArgs=$(($#-1))

quoted_args="$(printf " %q" "${@:1:$endInputArgs}")"
output_arg="$(printf " %q" "${@:$#:1}")"

ratiox=$(echo "150*8.27" | bc -l)
ratioy=$(echo "150*11.69" | bc -l)

bash -c "convert $quoted_args -compress jpeg -resize 1240x1753 \
  -units PixelsPerInch -density 150x150 -repage ${ratiox}x${ratioy} $output_arg"

สคริปต์ถูกเรียกใช้ (บันทึกเป็นไฟล์ images2pdf)

images2pdf file\ 1.jpg file\ 2.jpg file\ 3.jpg output.pdf

/ แก้ไข: เพิ่มการตั้งค่าสถานะ "-l" ตามความคิดเห็นโดย tanius เพื่อความแม่นยำที่ดีขึ้น


คำแนะนำทั่วไป: $(echo "150*8.27" | bc)ยังไม่ดีสำหรับจุดลอย ทำงานที่นี่เพราะมันเป็นการคูณ สำหรับ$(echo "150/8.27" | bc)แม้ว่าผลที่ได้คือ18(ตัดทอนให้เป็นจำนวนเต็ม) แทนที่จะโทรbcกับที่สูงขึ้นscale: ผลคือ$(echo "150/8.27" | bc -l) 18.137847…
tanius

1

ฉันกำลังดิ้นรนกับสิ่งนั้นด้วย จากข้อมูลข้างต้นฉันเขียนสคริปต์ซึ่งเพิ่มไฟล์รูปภาพที่เรียงตามตัวอักษรลงในไฟล์ PDF เดียว

ตัวแปรบางตัวสามารถตั้งค่าได้ภายในสคริปต์ มันขึ้นอยู่กับ ImageMagick และ pdftk

หมายเหตุ: หากภาพที่ป้อนมีความละเอียดสูงกว่า (dpi) มากกว่าความละเอียดที่ต้องการของ output.pdf ภาพจะถูกเปลี่ยนเป็นความละเอียดที่ต่ำกว่า ไม่เช่นนั้นภาพจะไม่ถูกปรับรูปใหม่และขยายให้พอดีกับผืนผ้าใบของหน้ากระดาษ

#!/bin/bash

export LOCALE=C

[[ "${2}x" == "x" ]] && \
 { echo "Usage: $( basename $0 ) output.pdf extension"
   echo "       merges all files (*.extension) into a single PDF"
   echo "If files z_merged.pdf, z_temp.pdf or $1 exist, they will be overwritten"
 exit 1
 } || \
 OutName="$1"
 ext="$2"

# Set basic variables
unset Debug #; Debug="yes" # print extra messages
IMBackground="white"      # what colour for paper
IMQuality="91"            # JPEG compression level
PaperWdthMetr="210"       # milimeters, 210 for ISO A4
PaperHghtMetr="297"       # milimeters, 297 for ISO A4
PaperDens="200"           # maximum (wanted) dpi for a page
PaperWdthInch=$( echo scale=5\; $PaperWdthMetr / 2.54 / 10      | bc -l ) # Inch
PaperHghtInch=$( echo scale=5\; $PaperHghtMetr / 2.54 / 10      | bc -l ) # Inch
PaperRtio=$(     echo scale=5\; $PaperWdthMetr / $PaperHghtMetr | bc -l )

# Remove temporary files from prior run
rm -rf z_merged.pdf z_temp.pdf 2>/dev/null

# Process any $ext file in the current directory
find . -maxdepth 1 -name "*.${ext}" -print0 | sort -z | while read -d '' -r FName
do
  echo "Converting $FName"
  ImgIdentify=$( identify -format "%w %h" "$FName" )
  ImgWdthOrig=$( echo $ImgIdentify | cut -d" " -f1  )
  ImgHghtOrig=$( echo $ImgIdentify | cut -d" " -f2  )
  ImgRtio=$( echo "scale=5; $ImgWdthOrig / $ImgHghtOrig"  | bc -l )
  [[ $( echo $ImgRtio'>'$PaperRtio | bc -l ) == 1 ]] \
    && ImgDens=$( echo scale=0\; $ImgWdthOrig / $PaperWdthInch | bc -l ) \
    || ImgDens=$( echo scale=0\; $ImgHghtOrig / $PaperHghtInch | bc -l )
  [[ $Debug ]] && echo "ImgDens1: $ImgDens"
  [[ $( echo $ImgDens'>'$PaperDens | bc -l ) == 1 ]] \
    && ImgDens=$PaperDens
  [[ $Debug ]] && echo "ImgDens2: $ImgDens"

  ImgWdth=$( echo $PaperWdthInch \* $ImgDens | bc -l ) # pixels
  ImgHght=$( echo $PaperHghtInch \* $ImgDens | bc -l ) # pixels

  [[ $Debug ]] && echo "ImgWdth: $ImgWdth".
  [[ $Debug ]] && echo "ImgHght: $ImgHght".

  convert "${FName}"                                 \
          -resize ${ImgWdth}x${ImgHght}              \
          -background $IMBackground -gravity center  \
          -extent ${ImgWdth}x${ImgHght}              \
          -units PixelsPerInch -set density $ImgDens \
          -repage ${ImgWdth}x${ImgHght}+0+0          \
          -compress JPEG                             \
          -quality $IMQuality                        \
          "${FName%.$ext}.pdf"

  # Merge new PDF page with prior pages
  [[ -f z_merged.pdf ]] && \
   { pdftk z_merged.pdf "${FName%.$ext}.pdf" cat output z_temp.pdf
     mv z_temp.pdf z_merged.pdf
   } || \
     cp "${FName%.$ext}.pdf" z_merged.pdf
  [[ $Debug ]] || rm -rf "${FName%.$ext}.pdf"
done

[[ -f z_merged.pdf ]] && mv z_merged.pdf "$OutName"
echo "Done."

ในข้างต้นฉันต้องเปลี่ยน-set density $ImgDensเป็น-density $ImgDens
Yotam


0

ฉันเพิ่งใช้สิ่งที่คล้ายกับคำตอบ maxschlepzigs ภายใต้ Ubuntu 16.04 / ImageMagick

นอกจากนี้ยังรวมศูนย์ผลลัพธ์

i=300; convert a.png b.png -compress jpeg -quality 100 \
      -density ${i}x${i} -units PixelsPerInch \
      -resize $((i*827/100))x$((i*1169/100)) \
      -gravity center \
      -extent $((i*827/100))x$((i*1169/100)) multipage.pdf
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.