posts: fix incorrect exif rotation for PNGs.
Fix a bug where where PNG images could be incorrectly detected as exif-rotated. This would happen when a PNG contained the IFD0:Orientation flag. It's technically possible for a PNG to contain this flag, but it's ignored by libvips and by browsers. post #3762340 (nsfw) is an example of a PNG like this. The fix is to use `autorot` to let libvips apply the rotation instead of trying to interpret the exif data ourselves. Note that libvips-8.9 has a bug where it doesn't strip the orientation flag after applying `autorot`, which leads to the image being incorrectly rotated a second time when generating the thumbnail. Use libvips-8.11 instead.
This commit is contained in:
@@ -11,23 +11,11 @@ class MediaFile::Image < MediaFile
|
||||
CROP_OPTIONS = { crop: :attention, linear: false }
|
||||
|
||||
def dimensions
|
||||
[width, height]
|
||||
image.size
|
||||
rescue Vips::Error
|
||||
[0, 0]
|
||||
end
|
||||
|
||||
def width
|
||||
is_rotated? ? image.height : image.width
|
||||
rescue Vips::Error
|
||||
0
|
||||
end
|
||||
|
||||
def height
|
||||
is_rotated? ? image.width : image.height
|
||||
rescue Vips::Error
|
||||
0
|
||||
end
|
||||
|
||||
def is_corrupt?
|
||||
image.stats
|
||||
false
|
||||
@@ -81,14 +69,9 @@ class MediaFile::Image < MediaFile
|
||||
file_ext == :png && metadata.fetch("PNG:AnimationFrames", 1) > 1
|
||||
end
|
||||
|
||||
# https://exiftool.org/TagNames/EXIF.html
|
||||
def is_rotated?
|
||||
metadata["IFD0:Orientation"].in?(["Rotate 90 CW", "Rotate 270 CW"])
|
||||
end
|
||||
|
||||
# @return [Vips::Image] the Vips image object for the file
|
||||
def image
|
||||
Vips::Image.new_from_file(file.path, fail: true)
|
||||
Vips::Image.new_from_file(file.path, fail: true).autorot
|
||||
end
|
||||
|
||||
memoize :image, :dimensions, :is_corrupt?, :is_animated_gif?, :is_animated_png?
|
||||
|
||||
@@ -49,7 +49,7 @@ class MediaAsset < ApplicationRecord
|
||||
|
||||
# https://exiftool.org/TagNames/EXIF.html
|
||||
def is_rotated?
|
||||
metadata["IFD0:Orientation"].in?(["Rotate 90 CW", "Rotate 270 CW", "Rotate 180"])
|
||||
file_ext == "jpg" && metadata["IFD0:Orientation"].in?(["Rotate 90 CW", "Rotate 270 CW", "Rotate 180"])
|
||||
end
|
||||
|
||||
# Some animations technically have a finite loop count, but loop for hundreds
|
||||
|
||||
Reference in New Issue
Block a user