Merge pull request #32 from insales/exif_orientation

Попытка бекпорта автоориентации по exif
This commit is contained in:
Vasily Fedoseyev
2021-05-27 11:35:02 +03:00
committed by GitHub
2 changed files with 36 additions and 4 deletions

View File

@@ -4,8 +4,18 @@ module Paperclip
class Geometry
attr_accessor :height, :width, :modifier
EXIF_ROTATED_ORIENTATION_VALUES = [5, 6, 7, 8]
# Gives a Geometry representing the given height and width
def initialize width = nil, height = nil, modifier = nil
if width.is_a?(Hash)
options = width
@height = options[:height].to_f
@width = options[:width].to_f
@modifier = options[:modifier]
@orientation = options[:orientation].to_i
return
end
@height = height.to_f
@width = width.to_f
@modifier = modifier
@@ -16,7 +26,7 @@ module Paperclip
def self.from_file file
file = file.path if file.respond_to? "path"
geometry = begin
Paperclip.run("identify", %Q[-format "%wx%h" "#{file}"[0]])
Paperclip.run("identify", %Q[-format "%wx%h,%[exif:orientation]" "#{file}"[0]])
rescue PaperclipCommandLineError => e
""
end
@@ -26,8 +36,21 @@ module Paperclip
# Parses a "WxH" formatted string, where W is the width and H is the height.
def self.parse string
if match = (string && string.match(/\b(\d*)x?(\d*)\b([\>\<\#\@\%^!])?/i))
Geometry.new(*match[1,3])
if match = (string && string.match(/\b(\d*)x?(\d*)\b(?:,(\d?))?([\>\<\#\@\%^!])?/i))
Geometry.new(
width: match[1],
height: match[2],
orientation: match[3],
modifier: match[4]
)
end
end
# Swaps the height and width if necessary
def auto_orient
if EXIF_ROTATED_ORIENTATION_VALUES.include?(@orientation)
@height, @width = @width, @height
@orientation -= 4
end
end

View File

@@ -3,6 +3,7 @@ module Paperclip
class Thumbnail < Processor
attr_accessor :current_geometry, :target_geometry, :format, :whiny, :convert_options
attr_accessor :source_file_options, :auto_orient
# Creates a Thumbnail object set to work on the +file+ given. It
# will attempt to transform the image into one defined by +target_geometry+
@@ -18,8 +19,13 @@ module Paperclip
@target_geometry = Geometry.parse geometry
@current_geometry = Geometry.from_file @file
@convert_options = options[:convert_options]
@source_file_options = options[:source_file_options]
@whiny = options[:whiny].nil? ? true : options[:whiny]
@format = options[:format]
@auto_orient = options[:auto_orient].nil? ? true : options[:auto_orient]
if @auto_orient && @current_geometry.respond_to?(:auto_orient)
@current_geometry.auto_orient
end
@current_format = File.extname(@file.path)
@basename = File.basename(@file.path, @current_format)
@@ -44,6 +50,7 @@ module Paperclip
dst.binmode
command = <<-end_command
#{ source_file_options }
"#{ File.expand_path(src.path) }[0]"
#{ transformation_command }
#{ gamma_correction_if_needed }
@@ -63,7 +70,9 @@ module Paperclip
# into the thumbnail.
def transformation_command
scale, crop = @current_geometry.transformation_to(@target_geometry, crop?)
trans = "-resize \"#{scale}\""
trans = String.new
trans << "-auto-orient " if auto_orient
trans << "-resize \"#{scale}\"" unless scale.nil? || scale.empty?
trans << " -crop \"#{crop}\" +repage" if crop
trans << " #{convert_options}" if convert_options?
trans