16 |
16 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
17 |
17 |
|
18 |
18 |
require 'fileutils'
|
19 |
|
require 'mimemagic'
|
|
19 |
|
|
20 |
begin
|
|
21 |
require 'fastimage/resize' unless defined? FastImage
|
|
22 |
rescue LoadError
|
|
23 |
# :thumbnails group not available
|
|
24 |
end
|
20 |
25 |
|
21 |
26 |
module Redmine
|
22 |
27 |
module Thumbnail
|
23 |
|
extend Redmine::Utils::Shell
|
24 |
|
|
25 |
|
CONVERT_BIN = (Redmine::Configuration['imagemagick_convert_command'] || 'convert').freeze
|
26 |
|
|
27 |
28 |
# Generates a thumbnail for the source image to target
|
28 |
29 |
def self.generate(source, target, size)
|
|
30 |
|
|
31 |
# Nothing we can do without the libraries
|
29 |
32 |
return nil unless convert_available?
|
30 |
|
unless File.exists?(target)
|
31 |
|
# Make sure we only invoke Imagemagick if this is actually an image
|
32 |
|
unless File.open(source) {|f| MimeMagic.by_magic(f).try(:image?)}
|
33 |
|
return nil
|
34 |
|
end
|
35 |
|
directory = File.dirname(target)
|
36 |
|
unless File.exists?(directory)
|
37 |
|
FileUtils.mkdir_p directory
|
38 |
|
end
|
39 |
|
size_option = "#{size}x#{size}>"
|
40 |
|
cmd = "#{shell_quote CONVERT_BIN} #{shell_quote source} -thumbnail #{shell_quote size_option} #{shell_quote target}"
|
41 |
|
unless system(cmd)
|
42 |
|
logger.error("Creating thumbnail failed (#{$?}):\nCommand: #{cmd}")
|
43 |
|
return nil
|
44 |
|
end
|
|
33 |
|
|
34 |
# Nothing to do, thumb was already created
|
|
35 |
return target if File.exists?(target)
|
|
36 |
|
|
37 |
fastimage = FastImage.new(source)
|
|
38 |
|
|
39 |
# Cannot read dimensions for source - it's probably not an image
|
|
40 |
return nil if fastimage.size.nil?
|
|
41 |
|
|
42 |
directory = File.dirname(target)
|
|
43 |
FileUtils.mkdir_p(directory) unless File.exists?(directory)
|
|
44 |
|
|
45 |
if fastimage.size.max <= size
|
|
46 |
FileUtils.cp(source, target)
|
|
47 |
elsif fastimage.size.first > fastimage.size.last
|
|
48 |
fastimage.resize(size, 0, :outfile => target, :jpeg_quality => 90)
|
|
49 |
else
|
|
50 |
fastimage.resize(0, size, :outfile => target, :jpeg_quality => 90)
|
45 |
51 |
end
|
|
52 |
|
46 |
53 |
target
|
|
54 |
|
|
55 |
rescue FastImage::FastImageException
|
|
56 |
logger.error("Creating thumbnail failed - #{$!.class.name}: #{$!.message}")
|
|
57 |
nil
|
47 |
58 |
end
|
48 |
59 |
|
49 |
60 |
def self.convert_available?
|
50 |
|
return @convert_available if defined?(@convert_available)
|
51 |
|
@convert_available = system("#{shell_quote CONVERT_BIN} -version") rescue false
|
52 |
|
logger.warn("Imagemagick's convert binary (#{CONVERT_BIN}) not available") unless @convert_available
|
53 |
|
@convert_available
|
|
61 |
!!defined?(FastImage)
|
54 |
62 |
end
|
55 |
63 |
|
56 |
64 |
def self.logger
|