有些工具还收费,没有苛刻的要求可以用交易一气呵成。
ruby
# frozen_string_literal: true
# encoding: utf-8
require 'prawn'
class Img2Pdf
A4_WIDTH = 595.28
A4_HEIGHT = 841.89
def initialize(output_path = 'output.pdf')
@output_path = output_path
end
def convert(image_paths)
raise ArgumentError, '请提供至少一张图片路径' if image_paths.empty?
image_paths = sort_image_paths(image_paths)
valid_images = []
image_paths.each do |image_path|
if File.exist?(image_path)
valid_images << image_path
else
warn "警告:图片不存在 - #{image_path}"
end
end
return unless valid_images.any?
doc = Prawn::Document.new(page_size: 'A4', page_layout: :portrait)
valid_images.each_with_index do |image_path, index|
begin
add_image_to_page(doc, image_path)
puts "已添加图片 #{index + 1}/#{valid_images.length}: #{File.basename(image_path)}"
rescue => e
warn "错误:无法处理图片 #{image_path} - #{e.message}"
end
end
doc.render_file(@output_path)
puts "PDF 文件已生成:#{@output_path}"
@output_path
end
private
def sort_image_paths(paths)
paths.sort_by do |path|
numbers = File.basename(path).scan(/\d+/).map(&:to_i)
numbers.empty? ? [0, path] : [numbers.first, path]
end
end
def add_image_to_page(doc, image_path)
page_width = A4_WIDTH
page_height = A4_HEIGHT
margin = 50
doc.image(image_path,
width: page_width - margin * 2,
position: :center,
vposition: :top)
end
end
if __FILE__ == $PROGRAM_NAME
if ARGV.empty?
puts "用法:ruby main.rb [图片路径 1] [图片路径 2] ... [-o 输出文件名]"
puts "示例:ruby main.rb img1.jpg img2.jpg img3.jpg"
puts " ruby main.rb *.png -o mypdf.pdf"
exit 1
end
output_file = 'output.pdf'
if (output_index = ARGV.index('-o'))
if output_index + 1 < ARGV.length
output_file = ARGV[output_index + 1]
ARGV.delete_at(output_index)
ARGV.delete_at(output_index)
end
end
image_paths = ARGV.select { |arg| !arg.start_with?('-') }
converter = Img2Pdf.new(output_file)
converter.convert(image_paths)
end