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
相关推荐
Dicky-_-zhang3 小时前
消息队列Kafka/RocketMQ选型与高可用架构:从单体到100万TPS的演进
java·jvm
晨曦中的暮雨3 小时前
4.15腾讯 CSIG云服务产线 一面
java·开发语言
fake_ss1983 小时前
AI时代学习全栈项目开发的新范式
java·人工智能·学习·架构·个人开发·学习方法
asdzx673 小时前
使用 Python 为 PDF 添加页码 (详细教程)
python·pdf·页码
茉莉玫瑰花茶3 小时前
工作流的常见模式 [ 1 ]
java·服务器·前端
未若君雅裁4 小时前
Spring AOP、日志切面与声明式事务原理
java·后端·spring
No8g攻城狮4 小时前
【人大金仓】wsl2+ubuntu22.04安装人大金仓数据库V9
java·数据库·spring boot·非关系型数据库
小婷资料库4 小时前
2025年新高考二卷数学真题试卷及答案解析电子版PDF
pdf·高考
xiaoerbuyu12334 小时前
开源Java 邮箱 基于SpringBoot+Vue前后端分离的电子邮件
java·开发语言