71 lines
1.7 KiB
Ruby
71 lines
1.7 KiB
Ruby
|
class TitreIdentiteWatermarkJob < ApplicationJob
|
||
|
queue_as :active_storage_watermark
|
||
|
|
||
|
MAX_IMAGE_SIZE = 1500
|
||
|
SCALE = 0.9
|
||
|
WATERMARK = Rails.root.join('app/assets/images/watermark.png')
|
||
|
|
||
|
def perform(blob)
|
||
|
blob.open do |file|
|
||
|
watermark = resize_watermark(file)
|
||
|
processed = watermark_image(file, watermark)
|
||
|
|
||
|
blob.metadata[:watermark] = true
|
||
|
blob.upload(processed)
|
||
|
blob.save
|
||
|
end
|
||
|
end
|
||
|
|
||
|
private
|
||
|
|
||
|
def watermark_image(file, watermark)
|
||
|
ImageProcessing::MiniMagick
|
||
|
.source(file)
|
||
|
.convert("png")
|
||
|
.resize_to_limit(MAX_IMAGE_SIZE, MAX_IMAGE_SIZE)
|
||
|
.composite(watermark, mode: "over", gravity: "center")
|
||
|
.call
|
||
|
end
|
||
|
|
||
|
def resize_watermark(file)
|
||
|
metadata = image_metadata(file)
|
||
|
|
||
|
width = [metadata[:width], MAX_IMAGE_SIZE].min * SCALE
|
||
|
height = [metadata[:height], MAX_IMAGE_SIZE].min * SCALE
|
||
|
diagonal = Math.sqrt(height**2 + width**2)
|
||
|
angle = Math.asin(height / diagonal) * 180 / Math::PI
|
||
|
|
||
|
ImageProcessing::MiniMagick
|
||
|
.source(WATERMARK)
|
||
|
.resize_to_limit(diagonal, diagonal / 2)
|
||
|
.rotate(-angle, background: :transparent)
|
||
|
.call
|
||
|
end
|
||
|
|
||
|
def image_metadata(file)
|
||
|
read_image(file) do |image|
|
||
|
if rotated_image?(image)
|
||
|
{ width: image.height, height: image.width }
|
||
|
else
|
||
|
{ width: image.width, height: image.height }
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def read_image(file)
|
||
|
require "mini_magick"
|
||
|
image = MiniMagick::Image.new(file.path)
|
||
|
|
||
|
if image.valid?
|
||
|
yield image
|
||
|
else
|
||
|
logger.info "Skipping image analysis because ImageMagick doesn't support the file"
|
||
|
{}
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def rotated_image?(image)
|
||
|
['RightTop', 'LeftBottom'].include?(image["%[orientation]"])
|
||
|
end
|
||
|
end
|