Skip to content

Instantly share code, notes, and snippets.

@KevinSia
Last active October 23, 2024 18:20
Show Gist options
  • Select an option

  • Save KevinSia/e3f3247a8c7a7422f93c32917b0b016c to your computer and use it in GitHub Desktop.

Select an option

Save KevinSia/e3f3247a8c7a7422f93c32917b0b016c to your computer and use it in GitHub Desktop.
module ImageProcessing
module MiniMagick
module Processing
extend ActiveSupport::Concern
included do
def watermark(scale: 0.15)
# ActiveStorage custom variant reference:
# https://stackoverflow.com/questions/71832729/how-do-i-create-a-non-trivial-activestorage-variant-for-watermarking-images
# https://round-tractor.medium.com/custom-image-variants-with-rails-active-storage-88d84ea007bc
#
# IM7 watermark solution: https://stackoverflow.com/questions/71599820/imagemagick-add-watermark-proportionally
#
# Watermark using IM6 syntax
# (We can only use IM6 syntax because the image_processing gem does not support mini_magick 5 yet)
# (https://github.com/janko/image_processing/issues/125)
# https://imagemagick.org/discourse-server/viewtopic.php?t=34883
#
# Couldn't find a way to offset the watermark in the original image by percentage.
# The geometry option can only accept pixels.
#
# Padding the watermark image instead would work, since the paddings will scale together with the
# watermark image during "distort".
#
# the watermark3x-padded image is the watermark3x image with padding 40
# https://onlinepngtools.com/add-padding-to-png
watermark_path = Rails.root.join('public', 'watermark3x-padded.png')
# magick convert car-sample.jpg public/watermark3x-padded.png \
# +distort affine "0,0 0,0 %[w],%[h] %[fx:t?v.w*(u.h/v.h*0.15):s.w],%[fx:t?v.h*(u.h/v.h*0.15):s.h]" \
# -shave 1 -gravity northeast -geometry +15+15 -composite output.png
magick << watermark_path
magick << "+distort"
magick << "affine"
magick << "0,0 0,0 %[w],%[h] %[fx:t?v.w*(u.h/v.h*#{scale}):s.w],%[fx:t?v.h*(u.h/v.h*#{scale}):s.h]"
magick.shave(1)
magick.gravity('northeast')
magick.geometry('+15+15')
magick.composite
end
end
end
end
end
ImageProcessing::MiniMagick::Processor.include(
ImageProcessing::MiniMagick::Processing
)
# in model
class Listing < ApplicationRecord
has_one_attached :image do |img|
img.variant :web, watermark: { scale: 0.1 }
end
after_commit :process_image
def process_image
if self.image.attached?
self.image.variant(:web).processed
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment