Rails 7 中如何在图像上传或更改后使用 MiniMagick 自动更新图像的主色?

问题描述 投票:0回答:1

我正在开发 Rails 7 应用程序,我正在尝试实现一个功能,每当上传或更改事件图像时,我都会计算和更新事件图像的主颜色。我正在使用 MiniMagick 处理图像,并且我想将主色存储在事件表中的dominant_color 列中。

我想要实现的目标:

  • 我想在上传新图像或因事件更改现有图像时自动更新图像的主色。
  • dominant_color 应存储为十六进制颜色代码(例如,#ff5733)。
  • 我想确保这是有效的,并且仅在必要时发生,避免不必要的数据库更新或回调。

到目前为止我所实施的:

我在事件表中创建了一个dominant_color列,并在事件模型中编写了以下代码,以在附加或更改图像时计算和存储主颜色:

# app/models/event.rb

require 'mini_magick'

class Event < ApplicationRecord
   # Change to after_commit and use a different detection method
  after_commit :check_and_update_dominant_color, on: [:create, :update]

  private

  def should_update_dominant_color?
    image.attached? && 
    (saved_change_to_attribute?('image_attachment_id') || image.attachment&.saved_change_to_blob_id?)
  end

  def update_dominant_color
    return unless image.attached?

    # Ensure we're working with the actual blob data
    image.open do |tempfile|
      img = MiniMagick::Image.read(tempfile)
      img.resize '1x1'
      pixel = img.get_pixels[0][0]
      hex_color = rgb_to_hex(pixel)
      
      # Use update_column to avoid callbacks
      update_column(:dominant_color, hex_color)
    end
  end

  def rgb_to_hex(rgb_array)
    "#" + rgb_array[0..2].map { |c| c.to_s(16).rjust(2, '0') }.join
  end
end

问题:

  • 我使用 after_commit 来确保保存图像后更新主色。但是,当我上传或更新图像时,颜色似乎没有正确更新。
  • 方法should_update_dominant_color?旨在检查图像是否已更改,但它可能无法正确检测更改,从而导致主色在应该更新时未更新。

我尝试过的:

  • 我已经使用 after_save 和 after_commit 进行了测试,但是当附加或更改图像时,这两种方法似乎都无法正确触发更新。
  • 我使用 update_column 来避免触发额外的回调,这可能会导致不必要的副作用。

我的问题:

  1. 是否有更有效或更可靠的方法来检测图像附件的更改,以保证主色正确更新?
  2. 使用 after_commit 是最好的方法吗,还是我应该考虑不同的回调?
  3. 关于优化此流程或处理图像删除或更新等边缘情况有什么建议吗?

我真的很感激任何反馈,特别是来自那些使用过 MiniMagick 或已经实现了类似功能的人的反馈。谢谢!

编辑:在控制台中手动测试颜色提取有效

event = Event.find(3)
event.send(:update_dominant_color)
event.reload.dominant_color
ruby-on-rails ruby minimagick
1个回答
0
投票

检查为什么这不起作用

  def should_update_dominant_color?
    image.attached? && 
    (saved_change_to_attribute?('image_attachment_id') || image.attachment&.saved_change_to_blob_id?)
  end

也许还有其他方法可以检查图像是否已更改。

您可以尝试使用其他回调,例如“before_save”,并检查图像是否已更改并设置一些标志。然后使用“after_commit”和该标志来运行您的逻辑。

总的来说,我认为你的代码应该可以工作,但很难说为什么不可以。您使用什么宝石作为附件?

© www.soinside.com 2019 - 2024. All rights reserved.