我在Ruby 2.4.0上,Ruby在Rails 4.2.8上。
我已经从mini_magick搬到了VIP,以在Ruby上的Rails上载器上处理图像。由于WKHTMLTOPDF不支持图像的EXIF数据,因此我必须在保存到存储时正确旋转它们。我在载波上传器上运行两个进程,一个用于旋转和剥离exif数据,另一个用于调整大小。
class ImageUploader < CarrierWave::Uploader::Base
include CarrierWave::Vips
process :fix_orientation
process resize_to_fit: [800, 800]
# Choose what kind of storage to use for this uploader:
storage :gcloud
# storage :file
# storage :fog
# Override the directory where uploaded files will be stored.
# This is a sensible default for uploaders that are meant to be mounted:
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
通话过程:我在Ruby上的Image Uploader在Rails上的Image Uploader上的Auto_orient(这是CarrierWave-VIPS提供的方法)不起作用。图像没有旋转,就像什么都没有发生。
我进入了CarrierWave-VIPS GEM,并将与Auto_erient相关的代码分解为我的fix_orientation。这是从该库中获取的代码 -
def auto_orient
manipulate! do |image|
o = image.get('exif-Orientation').to_i rescue nil
o ||= image.get('exif-ifd0-Orientation').to_i rescue 1
case o
when 1
# Do nothing, everything is peachy
when 6
image.rot270
when 8
image.rot180
when 3
image.rot90
else
raise('Invalid value for Orientation: ' + o.to_s)
end
image.set_type GObject::GSTR_TYPE, 'exif-Orientation', ''
image.set_type GObject::GSTR_TYPE, 'exif-ifd0-Orientation', ''
end
end
在处理它之后,我发现代码仅在剥离的最后一个部分时旋转图像EXIF数据输出:
image.set_type GObject::GSTR_TYPE, 'exif-Orientation',
image.set_type GObject::GSTR_TYPE, 'exif-ifd0-Orientation',
我尝试将函数分解为旋转图像的部分,然后将剥离数据的部分分解为以查看是否有效,所以类似的东西
process :fix_orientation #code checking exif data number and rotating image accordingly
process :fix_orientation_2 #the last two lines stripping the exif data from the image
使它不再起作用。图像实际上正确旋转的唯一距离是未调用Fix_Orientation_2的行。
这是非常令人困惑的行为,因为它直接来自载波库,我希望exif数据的剥离不会否定先前对旋转所做的事情。调整大小的处理似乎仍然很好,因此对整个过程堆栈的影响都不是
什么想法是什么想法导致这种行为?可能是Ruby版本吗?
I'm on Ruby 2.4.0 and Ruby on Rails 4.2.8.
I've moved from mini_magick to vips for handling images on my Ruby on Rails uploader. Due to wkhtmltopdf not supporting EXIF data for images, i have to correctly rotate them when they are saved to storage. I run two processes on the Carrierwave uploader, one to rotate and strip exif data, and another to resize.
class ImageUploader < CarrierWave::Uploader::Base
include CarrierWave::Vips
process :fix_orientation
process resize_to_fit: [800, 800]
# Choose what kind of storage to use for this uploader:
storage :gcloud
# storage :file
# storage :fog
# Override the directory where uploaded files will be stored.
# This is a sensible default for uploaders that are meant to be mounted:
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
Calling process :auto_orient (which is the method provided by Carrierwave-vips) on my image uploader in Ruby on Rails wasn't working. Images weren't being rotated, like nothing was happening.
I went into the Carrierwave-vips gem and broke out the code relating to auto_orient into my uploader as fix_orientation. This is the code taken from that library - https://github.com/eltiare/carrierwave-vips/blob/master/lib/carrierwave/vips.rb
def auto_orient
manipulate! do |image|
o = image.get('exif-Orientation').to_i rescue nil
o ||= image.get('exif-ifd0-Orientation').to_i rescue 1
case o
when 1
# Do nothing, everything is peachy
when 6
image.rot270
when 8
image.rot180
when 3
image.rot90
else
raise('Invalid value for Orientation: ' + o.to_s)
end
image.set_type GObject::GSTR_TYPE, 'exif-Orientation', ''
image.set_type GObject::GSTR_TYPE, 'exif-ifd0-Orientation', ''
end
end
After messing around with it, i found that the code only rotates the images if you take the last sections that are stripping the exif data out:
image.set_type GObject::GSTR_TYPE, 'exif-Orientation',
image.set_type GObject::GSTR_TYPE, 'exif-ifd0-Orientation',
I've tried breaking the function into the part that rotates the images, and into the part that strips the data, to see if that worked, so something like
process :fix_orientation #code checking exif data number and rotating image accordingly
process :fix_orientation_2 #the last two lines stripping the exif data from the image
Still, this makes it not work again. The only away that the images actually become correctly rotated is if the lines from fix_orientation_2 aren't called.
This is quite puzzling behaviour as it's coming straight from the Carrierwave library and i would expect the stripping of the exif data to not negate what was done previously with the rotation. The resize processing still seems to go through fine so it's not like the whole process stack is being reversed either
Any ideas as to what causes this behaviour? Might it be the Ruby version?
发布评论
评论(1)
尽管我想了解如何解决基本问题,但我确实通过不调用fix_orientation_2来解决这个
问题测试EXIF的图像:
发现carrierwave-vips auto_orient中的这种逻辑是不正确的:
要正确地上传1,6,8和3张图像,在该git上,正确的逻辑(至少对我来说)是:
Although i would like to understand how to fix the underlying issue, i did get around this by not calling fix_orientation_2 but instead calling the :strip function which is part of that library, this works fine:
Also, for me at least, using these example images to test the exif: https://github.com/recurser/exif-orientation-examples
Found that this logic in Carrierwave-vips auto_orient is incorrect:
To correctly upload the 1,6,8 and 3 images on that git, the correct logic (for me at least) was this: