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
相关推荐
好家伙VCC14 小时前
# MAUI 中的异步加载优化实战:从理论到高性能 UI 体验提升在现代跨平台移动开发中,*
java·python·ui
Full Stack Developme14 小时前
Java 弱引用与强引用
java·开发语言
1104.北光c°14 小时前
【重写优化 新增绘图】布谷鸟过滤器:布隆过滤器的更优缓存穿透解?
java·开发语言·后端·缓存·缓存穿透·布隆过滤器·布谷鸟过滤器
萧逸才15 小时前
【learn-claude-code】S06ContextCompact - 上下文压缩:上下文会满,你需要腾出空间
java·人工智能·ai
CCIE-Yasuo15 小时前
《永恒战士2-无双战神》无限金币版(提供apk下载)安卓Android逆向记录学习-Deepseek-AI辅助
android·java·学习·游戏
云泽野15 小时前
SpringBoot整合QQ邮箱发送邮件及微服务公共模块封装实战
java·spring boot·微服务
eSsO KERF15 小时前
MS SQL Server partition by 函数实战三 成绩排名
java
姗姗的鱼尾喵15 小时前
Java 并发编程高频面试题(含AQS/线程池/锁)
java·经验分享·面试
夫礼者15 小时前
【极简监控】选连接池送深度监控?用 Druid 补齐单体应用全局 SQL 统计的最后拼图
java·数据库·sql·druid
MyY_DO15 小时前
大麦pro 表结构分析
java