chuyển đổi hình ảnh thành pdf: Cách tạo các trang PDF có cùng kích thước


45

Tôi đã làm một cái gì đó như

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

Nhưng trang 1 lớn hơn nhiều so với các trang tiếp theo. Điều này xảy ra mặc dù kích thước hình ảnh là tương tự nhau. Những hình ảnh này được quét và cắt, do đó có thể có một chút khác biệt về kích thước

Tôi nghĩ -page A4nên sửa kích thước của các trang?

Câu trả lời:


60

Lần trước tôi đã sử dụng convertcho một nhiệm vụ như vậy, tôi đã chỉ định rõ ràng kích thước của điểm đến thông qua thay đổi kích thước:

$ 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

Các convertlệnh không luôn luôn sử dụng DPI như đơn vị dạng mật độ default / trang, do đó chúng tôi chỉ định rõ ràng DPI với -unitstùy chọn (nếu không bạn có thể nhận được kết quả khác nhau với các phiên bản khác nhau / định dạng đầu vào kết hợp). Kích thước mới (được chỉ định qua -resize) là kích thước của trang DIN A4 tính bằng pixel. Đối số thay đổi kích thước chỉ định kích thước trang tối đa. Độ phân giải và chất lượng để chọn chính xác tùy thuộc vào trường hợp sử dụng - Tôi đã chọn 150 DPI và chất lượng trung bình để tiết kiệm một số không gian trong khi nó trông không tệ lắm khi được in trên giấy.

Lưu ý rằng converttheo mặc định không thay đổi tỷ lệ khung hình với thao tác thay đổi kích thước:

Thay đổi kích thước sẽ phù hợp với hình ảnh vào kích thước yêu cầu. Nó KHÔNG điền, kích thước hộp yêu cầu.

( Hướng dẫn sử dụng ImageMagick )

Tùy thuộc vào phiên bản ImageMagick và các định dạng đầu vào có liên quan, có thể bỏ qua -repagetùy chọn này. Nhưng đôi khi, bắt buộc và không có tùy chọn đó, tiêu đề PDF có thể chứa kích thước quá nhỏ. Trong mọi trường hợp, -repagekhông nên làm tổn thương.

Các tính toán sử dụng số học số nguyên vì bashchỉ hỗ trợ điều đó. Với zshcác biểu thức có thể được đơn giản hóa - tức là thay thế bằng $((i*8.27))x$((i*11.69)).

Hình ảnh tuyến tính

Nếu các tệp PNG là hình ảnh hai cấp (đen & trắng aka lineart) thì img2pdfcông cụ mang lại kết quả vượt trội so với ImageMagick convert. Điều đó có nghĩa img2pdflà nhanh hơn và mang lại các tệp PDF nhỏ hơn.

Thí dụ:

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

hoặc là:

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

2
khi sử dụng, -repage a4tôi nhận được mộtinvalid argument for option '-repage': a4
Scolytus

1
@Scolytus, trên hệ thống Fedora 19 tôi đã quan sát thấy một vấn đề tương tự - có vẻ như nó -repagekhông còn hỗ trợ tên a4 nữa. Tôi đã làm việc xung quanh điều này thông qua số học shell:-repage $((150*8.27))x$((150*11.69))
maxschlepzig

Tôi giả sử những con số ma thuật đó là 150dpi, và A4 được biểu thị bằng đơn vị cũ?
Michael Scheper

@MichaelScheper, vâng, dpi và inch.
maxschlepzig

Cảm ơn, giúp tôi với. Trên thực tế, -density 150đối số là quan trọng để thêm.
dma_k

23

Những gì bạn thực sự muốn sử dụng là:

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

-extentthực sự mở rộng hình ảnh thành 1240x1753, trong khi -resizevẫn giữ tỷ lệ của hình ảnh, khớp với hình ảnh 1240x...hoặc ...x1753.

Các -gravitytham số là không bắt buộc nhưng có thể được sử dụng để tập trung các hình ảnh khi mở rộng.


1
Cảm ơn bạn! -extentthực sự là những gì tôi muốn sử dụng :) - xin vui lòng, thêm trích dẫn bên trái bị bỏ lỡ ở phía trước của -extent, cảm ơn!
Brownian

Cảm ơn bạn, cuối cùng tôi đã thêm dấu tích bị thiếu! ;-)
khai trương

9

Ngoài ra câu trả lời của caugner :

khi cài đặt IM v6.6.9-7 tôi phát hiện ra -gravitytham số cần được đặt ở giữa -resize-extentđể có hiệu lực.

ngoài ra (không phải là một phần của câu hỏi op) tôi thấy việc thiết lập một màu nền hấp dẫn khác nhau sẽ dẫn đến tổng lệnh của

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

một biến thể hữu ích khác mà tôi thường sử dụng khi tôi không muốn thay đổi tỷ lệ hình ảnh đã có tỷ lệ khung hình chính xác nhưng vẫn giữ độ phân giải riêng lẻ của nó là

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

trong đó mật độ mục tiêu được xác định động bằng cách tính chiều rộng chia cho 8,27 (là chiều rộng tính bằng inch của trang A4). các -repage a4tham số có thể được bỏ qua phần lớn thời gian, nhưng tôi đã có một vài trường hợp .pdf kết quả sẽ có một định dạng khác nhau sligtly tắt kích thước A4 210x297mm (8.27x11.6" )


2

Tôi thấy mã của Mikher rất hữu ích, tuy nhiên, nó hoàn toàn đưa ra PDF dưới dạng Chân dung hoặc Phong cảnh, vì vậy tôi đã sửa đổi nó để kiểm tra bố cục của từng tệp đầu vào và khớp với đầu ra.

Tôi đã không bao gồm chỉnh sửa của Yotam vì nó hoạt động mà không có nó trên hộp Ubuntu 15.04 của tôi.

$#!/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

Tôi thấy đoạn mã sau đây thuận tiện kết hợp các câu trả lời được liệt kê ở đây cũng như một số vấn đề tôi gặp phải với phép tính dấu phẩy động:

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"

Kịch bản được gọi (được lưu dưới dạng tệp hình ảnh2pdf)

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

/ chỉnh sửa: Đã thêm cờ "-l" theo nhận xét của tanius để có độ chính xác cao hơn.


Gợi ý chung: $(echo "150*8.27" | bc)vẫn không tuyệt vời cho điểm nổi. Hoạt động ở đây vì nó là một phép nhân. Cho $(echo "150/8.27" | bc)dù, kết quả là 18(bỏ bớt số nguyên). Thay vào đó, gọi bcvới cao hơn scale: $(echo "150/8.27" | bc -l), kết quả là 18.137847….
tanius

1

Tôi cũng đang vật lộn với những thứ đó. Dựa trên thông tin trên, tôi đã viết một tập lệnh thêm các tệp hình ảnh được sắp xếp theo thứ tự abc vào một tệp PDF.

Một số biến được giải quyết bên trong tập lệnh. Nó phụ thuộc vào ImageMagick và pdftk.

Lưu ý: Nếu hình ảnh đầu vào có độ phân giải (dpi) cao hơn độ phân giải mong muốn của output.pdf, hình ảnh sẽ được điều chỉnh lại thành độ phân giải thấp hơn. Mặt khác, hình ảnh không được ghép lại và nó chỉ được mở rộng để phù hợp với khung trang.

#!/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."

Ở trên, tôi phải đổi -set density $ImgDensthành-density $ImgDens
Yotam


0

Tôi chỉ sử dụng một cái gì đó tương tự như câu trả lời maxschlepzigs trong Ubuntu 16.04 / ImageMagick

Điều này cũng tập trung vào kết quả

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.