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
相关推荐
霸道流氓气质1 分钟前
智能客服组件:分层意图识别、RAG Advisor 与人工转接状态机的 Vue3 + Spring AI 生产级实战
java·人工智能·spring
captain37633 分钟前
MyBatis操作数据库(入门2)
java·数据库·spring boot·后端·spring·mybatis
心中有你02141 小时前
Java实现Dijkstra最短路径算法(邻接表 + 优先队列)
java·数据库·算法
xiaolinudao1231 小时前
给pdf文件盖骑缝章的软件有哪些
pdf
步行cgn1 小时前
Spring MVC + Thymeleaf 模板解析失败:从 500 错误到页面正常显示
java·spring·mvc
lgcgkCQ2 小时前
【AI 转型实战 1】SpringAI 入门:搭建基础大模型对话能力
java·ai·agent·rag·spring ai·mcp·langchain4j
Wang's Blog2 小时前
Java 项目实战:交友项目 - 用户体系集成总结
java·开发语言·交友
学到老活到老2 小时前
第 24 集:配置文件写了 80,Spring Boot 为什么读到 90?
java·后端·spring
tongyiixiaohuang3 小时前
供应商主数据同步实战:从易快报到金蝶云星空的单一策略落地
java·网络·数据库
鱼宵3 小时前
取集合第一个元素,Java 为什么要写三种写法?
java·windows·python·java21