Paperclip - własna akcja przy upload/edit

Witam,

Skrobię sobie aplikację i mam mały problem. Nie mogę znaleźć punktu zaczepienia. Potrzebuję wykonać pewną akcję podczas dodawani zdjęcia; policzyć ilość pikseli danego koloru. Następnie do modelu - który posiada załącznik - przekazać te informacje przed zapisaniem na bazę. Z tego co ogarnąłem. Powinienem napisać sobie processor który będzie się odpalał przy ładowaniu?

Pozdrawiam,
Janek

Możesz po prostu użyć before_save na modelu. To nie musi być paperclipowy processor.

Ok, to może być wystarczające rozwiązanie. Pytanie tylko jak teraz w modelu stworzyć instancję Image? próbowałem coś takiego ale niestety nie działa. Oczywiście mam rmagic.

[code]class Photo < ActiveRecord::Base
attr_accessible :user_id, :image, :red, :green, :blue
has_attached_file :image

before_save :count_colors

private
def count_colors
img = Magic::Image.read(self.image)
(0…img.columns).each do |x|
(0…img.rows).each do |y|
pix = img.pixel_color(x, y)
self.red += pix.red
self.green += pix.green
self.blue += pix.blue
end
end

self.red /= (img.colums * img.rows)
self.blue /= (img.columns * img.rows)
self.green /= (img.columns * img.rows)

end
end[/code]

Nie używałem dużo RMagicka, ale może tutaj znajdziesz odpowiedź? http://www.imagemagick.org/RMagick/doc/usage.html

Powinienes podejsc do tego od strony paperclip poprzez processor, przyklad: http://matthewhutchinson.net/2010/10/25/editing-file-uploads-with-a-paperclip-processor

mozesz uzyc lambdy albo napisac wlasny processor a w nim co tam chcesz

troche tez stare jak powyzszy link, ale: http://railscasts.com/episodes/182-cropping-images tez uzywa processora

Wydaje mi się, że processory powinny być wykorzystywane w przypadku, kiedy chcemy w jakiś sposób modyfikować/przetwarzać/generować obrazy (tak jak domyślny Paperclip::Thumbnail). W przypadku odczytania informacji z obrazka i zapisania jej w modelu, bardziej będzie chyba pasować callback. Mógłby to być standardowy before_save, jednak warto przyjrzeć się tym, które dostarcza paperclip: https://github.com/thoughtbot/paperclip#events . Wywołując np. taki after_post_process mamy pewność, że obrazki zostały już przetworzone (istnieją na serwerze) i można na nich wykonywać jakieś operacje, np. odczyt kolorów :slight_smile:

Dzięki wszystkim za podpowiedzi.
Z tego co widzę to problem tkwi w samym RMagic. Realizuję zadanie w momencie after_post_process.
Wołam ->

Magic::Image.read(self.image.path).first

Wywala ->

uninitialized constant Photo::Magic

Oczywiście RMagic działa. Na pewno istnieje image.path już podczas wołania metody. Pojęcia nie mam co jeszcze może być piknięte.
Ktoś może miał już podobne problemy? :wink:

EDIT
Problem udało się rozwiązać. Dopiero w after_save zdjęcie znajduje się na dysku i da się go załadować. Całość kody dla modelu wygląda tak:

[code]require ‘rubygems’
require ‘RMagick’
require ‘win32ole’

class Photo < ActiveRecord::Base
attr_accessible :user_id, :image, :red, :green, :blue
has_attached_file :image

attr_accessor :flash_notice

after_save :count_colors

private
def count_colors
if !image.path.nil?
self.flash_notice = image.path(:oryginal)
img = Magick::Image.read(image.path).first
total = 0
avg = { :r => 0.0, :g => 0.0, :b => 0.0 }
img.quantize.color_histogram.each { |c, n|
avg[:r] += n * c.red
avg[:g] += n * c.green
avg[:b] += n * c.blue
total += n
}
[:r, :g, :b].each { |comp| avg[comp] /= total * 65535 }

		photo = Photo.find(id)
		photo.update_column(:red, avg[:r] * 255)
		photo.update_column(:green, avg[:g] * 255)
		photo.update_column(:blue, avg[:b] * 255)
end

end
end[/code]
Dzięki wszystkim za pomoc.
Pozdrawiam serdecznie :slight_smile: