Class: Media::GraphicsMagickTransmogrifier

Inherits:
Transmogrifier show all
Defined in:
lib/media/transmogrifiers/graphicsmagick.rb

Instance Attribute Summary

Attributes inherited from Transmogrifier

#command_output, #input, #input_file, #input_type, #name, #options, #output, #output_file, #output_type

Instance Method Summary collapse

Methods inherited from Transmogrifier

add, #command_available?, #converts_from?, #converts_to?, find_class, inherited, #initialize, input_map, list, output_map, #run_command

Constructor Details

This class inherits a constructor from Media::Transmogrifier

Instance Method Details

#available?Boolean

Returns:

  • (Boolean)


36
37
38
# File 'lib/media/transmogrifiers/graphicsmagick.rb', line 36

def available?
  command_available?(GRAPHICSMAGICK_COMMAND)
end

#average_color(filename) ⇒ Object

returns the average color of an image, as represented by an array of red, green, blue values, integers in the range 0..255

note: it is important that the geometry is “1x1!” … without the ! this function might die a fiery death.



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/media/transmogrifiers/graphicsmagick.rb', line 113

def average_color(filename)
  if available?
    args = [gm_command, 'convert', '-resize', '1x1!', filename, 'text:-']
    color = nil
    status = run_command(*args) do |output|
      color = output
    end
    if status == :success
      match = color.match(/^0,0: \(\s*(?<red>\d+),\s*(?<green>\d+),\s*(?<blue>\d+)\)/)
      if match
        return [match['red'].to_i, match['green'].to_i, match['blue'].to_i]
      end
    end
  end
  #if something goes wrong, assume white:
  return [256,256,256]
end

#convert(input = input_file.to_s, &block) ⇒ Object



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
# File 'lib/media/transmogrifiers/graphicsmagick.rb', line 58

def convert(input = input_file.to_s, &block)
  # +profile '*' will remove all the image profiles, which will save
  # space (sometimes) and are not useful for thumbnails
  arguments = [gm_command, 'convert', '+profile', "*"]
  if options[:size]
    # handle multiple size options, if it is an array.
    sizes = options[:size].is_a?(Array) ? options[:size] : [options[:size]]
    sizes.each do |size|
      if version_less_than?(1,3,6)
        size = size.sub('^','!')
      end
      arguments << '-geometry' << size
    end
  end
  if options[:background]
    # http://superuser.com/questions/213336/using-graphicsmagick-or-imagemagick-how-do-i-replace-transparency-with-a-fill-c
    arguments << '-background' << options[:background] << '-extent' << '0x0'
  end
  if options[:crop]
    # we add '+0+0' because we don't want tiles, just a single image
    arguments << '-crop' << options[:crop]+'+0+0'
  end
  arguments << input << output_file
  run_command(*arguments, &block)
end

#dimensions(filename) ⇒ Object

try to detect the dimensions of the first page. fallback to detecting dimensions of all pages.



86
87
88
89
# File 'lib/media/transmogrifiers/graphicsmagick.rb', line 86

def dimensions(filename)
  run_dimensions(filename.to_s + '[0]') ||
    run_dimensions(filename.to_s)
end

#gm_commandObject

this override is just used for test, at the moment.



132
133
134
# File 'lib/media/transmogrifiers/graphicsmagick.rb', line 132

def gm_command
  GRAPHICSMAGICK_COMMAND
end

#input_typesObject



21
22
23
24
25
# File 'lib/media/transmogrifiers/graphicsmagick.rb', line 21

def input_types
  %w( application/pdf application/bzpdf application/gzpdf
    application/postscript application/xpdf image/jpeg image/pjpeg image/gif
    image/png image/x-png image/jpg image/tiff )
end

#output_typesObject

def input_types

self.class.input_types

end



31
32
33
34
# File 'lib/media/transmogrifiers/graphicsmagick.rb', line 31

def output_types
  %w( application/pdf image/jpeg image/pjpeg
    image/gif image/png image/jpg image/tiff )
end

#run(&block) ⇒ Object

gm has an option -monitor that will spit out the progress. this could be interesting. we would need to use getc instead of gets on the pipe, since the progress is updated on a single line.



45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/media/transmogrifiers/graphicsmagick.rb', line 45

def run(&block)
  # try converting first page only
  status = convert(input_file.to_s + '[0]', &block)
  # retry with full file if result was empty
  if File.size(output_file.to_s) == 0
    # reset filenames to the state before run
    set_temporary_outfile
    status = convert(&block)
  end
  FileUtils.chmod 0644, output_file.to_s if File.exist? output_file.to_s
  return status
end

#run_dimensions(filename) ⇒ Object



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/media/transmogrifiers/graphicsmagick.rb', line 91

def run_dimensions(filename)
  if available?
    args = [gm_command, 'identify', '-format', '%m %w %h', filename]
    dimensions = nil
    status = run_command(*args) do |output|
      dimensions = output
    end
    if status == :success
      type, width, height = dimensions.split /\s/
      return [width,height]
    else
      return nil
    end
  end
end

#version_less_than?(major, minor, tiny) ⇒ Boolean

Returns:

  • (Boolean)


136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/media/transmogrifiers/graphicsmagick.rb', line 136

def version_less_than?(major,minor,tiny)
  installed_major, installed_minor, installed_tiny = GRAPHICSMAGICK_VERSION
  if installed_major < major
    true
  elsif (installed_major == major)
    if (installed_minor < minor)
      true
    elsif (installed_minor == minor) && (installed_tiny < tiny)
      true
    else
      false
    end
  else
    false
  end
end