6 Stimmen

Miniaturansicht einer mehrseitigen PDF-Datei mit Büroklammer

Ich möchte, dass Paperclip für jede Seite einer mehrseitigen PDF-Datei, die hochgeladen wird, 2 Miniaturbilder erstellt.

Ich verwende Paperclip 2.3.1.1 und verwende dies in meinem Asset-Modell:

    has_attached_file :asset,
                  :styles => { :medium => "800x600>", :thumb => "100x100>" }

Wenn ich also eine 3-seitige PDF-Datei hochlade, hatte ich gehofft, dass dadurch 2 Thumbnails pro Seite erstellt werden (eines bei 800x600 und ein kleineres Bild bei 100x100). Stattdessen werden 3 Ordner erstellt (thumb, medium, original) - der Originalordner enthält die ursprüngliche PDF-Datei, während thumb und medium jeweils eine PDF-Datei mit nur der ersten Seite der verpixelten PDF-Datei enthalten.

Was muss ich tun, damit Paperclip 2 Daumen für jede Seite der PDF-Datei erstellt? Im Idealfall hätte ich gerne ein Bild pro Seite wie dieses (6 Bilder erstellt):


assets/1/medium/file-0.png

assets/1/medium/file-1.png

assets/1/medium/file-2.png

assets/1/thumb/file-0.png

assets/1/thumb/file-1.png

assets/1/thumb/file-2.png

Weiß jemand, wie man das macht? Brauche ich einen eigenen Prozessor? Wenn ja, wie würde der Prozessor aussehen?

Danke.

9voto

taro Punkte 5652

Hier sehen Sie, wie ich eine ähnliche Aufgabe umgesetzt habe.

Dokumentenmodell:

class Document < ActiveRecord::Base

  has_many :pages, :dependent => :destroy

  has_attached_file :asset

  after_asset_post_process :make_pages

  private

  def make_pages
    if valid?
      Paperclip.run('convert', "-quality #{Page::QUALITY} -density #{Page::DENSITY} #{asset.queued_for_write[:original].path} #{asset.queued_for_write[:original].path}%d.png")
      images = Dir.glob("#{asset.queued_for_write[:original].path}*.png").sort_by do |line|
        line.match(/(\d+)\.png$/)[1].to_i
      end

      images.each do |page_image|
        pages.build(:asset => File.open(page_image))
      end
      FileUtils.rm images
    end
  end
end

Seitenmodell:

class Page < ActiveRecord::Base

  belongs_to :document

  has_attached_file :asset

  QUALITY = 100
  DENSITY = '80x80'

end

3voto

jkrall Punkte 546

Ich habe eine halbwegs funktionierende Lösung für dieses Problem... aber sie ist nicht sehr elegant. Ich würde mir wirklich gerne etwas Besseres einfallen lassen, aber ich dachte, ich teile es trotzdem.

Ich habe damit begonnen, eine Reihe neuer Stile zu definieren, einen für jede Seite... bis zu der Anzahl von Seiten, die ich verwalten möchte. (dumm, ich weiß, aber ich weiß nicht, wie man den Pfad Interpolationen in Paperclip zugreifen, so dass jede Seite wird gespeichert/gelöscht in den Speicher richtig, es sei denn, es ist eine eindeutige Stil für jedes Bild)

{ ...
:page_0 =>    {:geometry=>'800[0]',   :format=>:png, :processors=>[:multipage_thumbnail]},
:page_1 =>    {:geometry=>'800[1]',   :format=>:png, :processors=>[:multipage_thumbnail]},
:page_2 =>    {:geometry=>'800[2]',   :format=>:png, :processors=>[:multipage_thumbnail]},
:page_3 =>    {:geometry=>'800[3]',   :format=>:png, :processors=>[:multipage_thumbnail]},
:page_4 =>    {:geometry=>'800[4]',   :format=>:png, :processors=>[:multipage_thumbnail]},
:page_5 =>    {:geometry=>'800[5]',   :format=>:png, :processors=>[:multipage_thumbnail]},
}

Dann... Ich habe einen benutzerdefinierten Prozessor, der Unterklassen von der Thumbnail-Prozessor, mit einigen zusätzlichen Logik für die Ausführung des Befehls convert mit der richtigen Seite #.

module Paperclip
  # Handles thumbnailing images that are uploaded.
  class MultipageThumbnail < Thumbnail

    # Creates a Thumbnail object set to work on the +file+ given. It
    # will attempt to transform the image into one defined by +target_geometry+
    # which is a "WxH"-style string. +format+ will be inferred from the +file+
    # unless specified. Thumbnail creation will raise no errors unless
    # +whiny+ is true (which it is, by default. If +convert_options+ is
    # set, the options will be appended to the convert command upon image conversion
    def initialize file, options = {}, attachment = nil
      @page = options[:geometry].match(/\[(\d+)\]/)[1] rescue 0
      @page ||= 0
      options[:geometry] = options[:geometry].sub(/\[\d+\]/, '')
      super
    end

    # Performs the conversion of the +file+ into a thumbnail. Returns the Tempfile
    # that contains the new image.
    def make
      return nil if @page >= page_count

      src = @file
      dst = Tempfile.new([@basename, @format].compact.join("."))
      dst.binmode

      begin
        options = [
          source_file_options,
          "#{ File.expand_path(src.path) }[#{@page}]",
          transformation_command,
          convert_options,
          "#{ File.expand_path(dst.path) }"
        ].flatten.compact

        success = Paperclip.run("convert", *options)
      rescue PaperclipCommandLineError => e
        raise PaperclipError, "There was an error processing the thumbnail for #{@basename}" if @whiny
      end

      dst
    end

    def page_count
      @page_count ||= begin
        files = Paperclip.run("identify", "#{@file.path}")
        files.split(/\n/).size
      rescue PaperclipCommandLineError
        1
      end
    end

  end
end

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X