Class: HexaPDF::CLI::Image2PDF

Inherits:
Command
  • Object
show all
Defined in:
lib/hexapdf/cli/image2pdf.rb

Overview

Converts one or more images into a PDF file.

Instance Method Summary collapse

Methods included from Command::Extensions

#help, #help_banner

Constructor Details

#initializeImage2PDF

:nodoc:



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/hexapdf/cli/image2pdf.rb', line 45

def initialize #:nodoc:
  super('image2pdf', takes_commands: false)
  short_desc("Convert one or more images into a PDF file")
  long_desc(<<~EOF)
    This command converts one or more images into a single PDF file. The various options allow
    setting a page size, scaling the images and defining margins.
  EOF

  options.on("-p", "--page-size SIZE", "The PDF page size. Either auto which chooses a " \
             "size based on the image size or a valid page size like A4, A4-landscape " \
             "or 595x842. Default: auto") do |page_size|
    @media_box = case page_size
                 when 'auto'
                   :auto
                 when /(\d+(?:\.\d+)?)x(\d+(?:\.\d+)?)/
                   [0, 0, $1.to_f, $2.to_f]
                 else
                   orientation = :portrait
                   if page_size.end_with?('-landscape')
                     orientation = :landscape
                     page_size.delete_suffix!('-landscape')
                   end
                   page_size = page_size.capitalize.to_sym
                   HexaPDF::Type::Page.media_box(page_size, orientation: orientation)
                 end
  end
  options.on("--[no-]auto-rotate", "Automatically rotate pages based on image dimesions. " \
             "Default: true") do |auto_rotate|
    @auto_rotate = auto_rotate
  end
  options.on("-s", "--scale SCALE", Integer, "Defines how the images should be scaled. " \
             "Either fit to fit the image to the page size or a number specifying the " \
             "minimum pixels per inch. Default: fit") do |scale|
    @scale = case scale
             when 'fit' then :fit
             else scale.to_f
             end
  end
  options.on("-m", "--margins MARGINS", Array, "Defines the margins around the image, " \
             "either with a single number or four numbers (top, right, bottom, left) " \
             "separated by commas. Default: 0") do |margins|
    @margins = case margins.size
               when 1 then margins.map!(&:to_f) * 4
               when 4 then margins.map!(&:to_f)
               else
                 raise OptionParser::InvalidArgument, "#{margins.join(',')} (1 or 4 " \
                   "numbers needed)"
               end
  end
  define_optimization_options
  define_encryption_options

  @media_box = :auto
  @auto_rotate = true
  @scale = :fit
  @margins = [0, 0, 0, 0]
end

Instance Method Details

#execute(*images, out_file) ⇒ Object

:nodoc:



103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/hexapdf/cli/image2pdf.rb', line 103

def execute(*images, out_file) #:nodoc:
  maybe_raise_on_existing_file(out_file)

  out = HexaPDF::Document.new

  images.each do |image_file|
    image = out.images.add(image_file)
    iw = image.width.to_f
    ih = image.height.to_f
    if @scale != :fit
      iw *= 72 / @scale
      ih *= 72 / @scale
    end

    media_box = (@media_box == :auto ? [0, 0, iw, ih] : @media_box.dup)
    if @auto_rotate && (ih > iw) != (media_box[3] > media_box[2]) &&
        (iw > media_box[2] || ih > media_box[3])
      media_box[2], media_box[3] = media_box[3], media_box[2]
    end
    page = out.pages.add(media_box)

    pw = page.box(:media).width.to_f - @margins[1] - @margins[3]
    ph = page.box(:media).height.to_f - @margins[0] - @margins[2]
    if @scale == :fit || iw > pw || ih > ph
      ratio = [pw / iw, ph / ih].min
      iw, ih = iw * ratio, ih * ratio
    end
    x, y = @margins[3] + (pw - iw) / 2, @margins[2] + (ph - ih) / 2
    page.canvas.image(image, at: [x, y], width: iw, height: ih)
  end

  apply_encryption_options(out)
  apply_optimization_options(out)
  write_document(out, out_file)
end