Ruby简单粗暴把图片合成PDF文档

有些工具还收费,没有苛刻的要求可以用交易一气呵成。

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
相关推荐
C+++Python1 小时前
详细介绍一下Java泛型的通配符
java·windows·python
2603_954138391 小时前
PDF 转 Word 工具深度评测:从参数解析到实战避坑
pdf·word
JosieBook2 小时前
【数据库】时序预测能力的分级进化:TimechoAI如何让每一类用户都能精准预见未来
java·开发语言·数据库
一生了无挂3 小时前
Java处理JSON技巧教学(从基础到高阶实战全覆盖)
java·开发语言·json
李白的天不白3 小时前
使用 SmartAdmin 进行前后端开发
java·前端
swordbob3 小时前
Spring 单例 Bean 是线程安全的吗?
java·开发语言
2601_951643774 小时前
Python第一,Java跌出前三,C语言杀回来了
java·c语言·python·编程语言排行·技术趋势
沉默王二5 小时前
LlamaIndex 开源 LiteParse,零云依赖搞定扫描件PDF
pdf·开源
IT 行者6 小时前
GitHub Spec Kit 实战(五):/speckit.tasks 怎么拆——Spec Kit 五部曲收官
java·ai编程·claude