2010-10-13 2 views
2

J'utilise actuellement Paperclip pour télécharger une image et générer automatiquement une vignette. Maintenant, je voudrais aussi ajouter un second style qui génère une image d'un pixel à l'aide de la colonne de pixels la plus à gauche de l'image téléchargée (elle devrait également avoir la même hauteur que l'image originale). Je vais utiliser l'image d'un pixel de large comme arrière-plan répétitif via CSS.Recadrage personnalisé dans Rails avec Trombone

Est-il possible de générer cette image de fond à l'aide du processeur Thumbnail par défaut de Paperclip, ou devrais-je créer mon propre processeur personnalisé? J'ai déjà essayé de créer un processeur personnalisé qui sous-classe le Paperclip::Processor, mais je n'ai pas compris comment utiliser correctement la méthode Paperclip.run. Maintenant, je suis en train de sous-classe Paperclip::Thumbnail basée sur Railcast ici Ryan Bate: http://railscasts.com/episodes/182-cropping-images, mais est de lancer cette erreur:

NoMethodError (You have a nil object when you didn't expect it! 
You might have expected an instance of Array. 
The error occurred while evaluating nil.[]): 
app/controllers/images_controller.rb:11:in `create' 

Ligne 11 de images_controller.rb:

@image = @review.images.build(params[:image]) 

Ligne 11 de images_controller. rb fonctionne bien si je n'essaie pas d'utiliser le processeur personnalisé Autobackground, donc l'erreur doit être le code dans le processeur.

Voici mon code à ce jour:

#/app/models/image.rb 
class Image < ActiveRecord::Base 
    belongs_to :review 

    has_attached_file :image, :styles => { 
     :thumb => "32x32#", 
     :auto_bg => { :processors => [:autobackground] } 
    } 
end 

#/lib/paperclip_processors/Autobackground.rb 
module Paperclip 
    class Autobackground < Thumbnail 
     def transformation_command 
     if crop_command 
      crop_command + super.sub(/ -crop \S+/, '') 
     else 
      super 
     end 
     end 

     def crop_command 
     target = @attachment.instance 
     if target.cropping? 
      " -crop '1x#{target.height}+0+0'" 
     end 
     end 
    end 
end 

Répondre

2

Si quelqu'un est intéressé, j'ai réussi à obtenir ce travail. La seule chose qui m'a vraiment aidé à résoudre ce problème était la console de débogage de Rails (que j'ai finalement commencé à utiliser correctement) qui m'a permis de regarder de plus près les variables de la classe Paperclip::Thumbnail dont hérite ma classe Autobackground.

Voici ce que j'ai fait: J'ai changé le style :auto_bg pour pointer vers une chaîne spéciale que j'ai pu identifier dans mon processeur. Étant donné que mon processeur est sous-classé de Paperclip::Thumbnail, la chaîne vers laquelle pointe le style est enregistrée dans @options[:geometry]. Tout ce que j'ai à faire dans la méthode transformation_command est de vérifier si @options[:geometry] est réglé sur la chaîne spéciale auto_bg, puis d'exécuter ma méthode create_auto_bg au lieu de laisser la classe Thumbnail faire ce qui est habituel. Ma vieille méthode create_auto_bg ne créait pas correctement le tableau de chaînes que Thumbnail doit créer la commande ImageMagick, donc j'ai réécrit cela et utilisé la variable @current_geometry pour trouver la hauteur de l'image originale au lieu de la méthode target = @attachment.instance que j'avais copiée Le railcast de Ryan Bate (je ne sais pas comment cela fonctionne dans son code).

Je suis sûr qu'il existe une solution plus élégante à cela, mais je suis encore tout à fait nouveau à Ruby et RoR, donc cela devra faire pour l'instant. J'espère que cela aidera tous ceux qui font face à un défi similaire :)

#/app/models/image.rb 
class Image < ActiveRecord::Base 
    belongs_to :review 
    has_attached_file :image, :styles => { :thumb => "32x32#", :auto_bg => "auto_bg" }, :processors => [:autobackground] 
end 

#/lib/paperclip_processors/Autobackground.rb 
module Paperclip 
    class Autobackground < Thumbnail 
     def transformation_command 
     if @options[:geometry] == "auto_bg" 
      create_auto_bg 
     else 
      super 
     end 
     end 

     def create_auto_bg 
     #debugger 
     height = @current_geometry.height.to_i.to_s 
     trans = [] 
     trans << "-crop" << "1x#{height}+0+0" 
     trans 
     end 
    end 
end 
1

Je vous suggère d'écrire une méthode d'assistance et d'appeler avec un filtre ...

il existe plusieurs outils qui peuvent faire la magie pour ya ...

un autre commentaire sur le style de codage ...

Je préférerais écrire le style rubis de code comme

def crop_command 
    target = @attachment.instance 
    if target.cropping? 
     " -crop '1x#{target.height}+0+0'" 
    end 
end 

à

def crop_command 
    target = @attachment.instance 
    " -crop '1x#{target.height}+0+0'" if target.cropping? 
end 

partout où il est possible, s'il vous plaît utiliser le style spécifique rubis ...

Questions connexes