2012-05-08 32 views
13

Tôi muốn sử dụng jpegoptim hoặc optipng để nén hình ảnh do người dùng tải lên thông qua Paperclip.Quy trình đăng kẹp giấy - Cách nén hình ảnh bằng cách sử dụng jpegoptim/optpng

Tôi đã một mô hình Kẹp giấy cấu hình như:

has_attached_file :image, 
        :styles => {:thumb => '50x50>', :preview => '270x270>' }, 
        :url => "/system/:class/:attachment/:id/:basename_:style.:extension", 
        :path => ":rails_root/public/system/:class/:attachment/:id/:basename_:style.:extension" 

Câu hỏi 1: Có thể nén hình ảnh ban đầu được tải lên bởi người sử dụng, sau đó cho phép thay đổi kích thước Kẹp giấy nó, vì vậy chỉ có một quá trình nén? Và làm thế nào để làm điều đó?

Câu hỏi 2: Tôi sẽ làm điều đó thông qua after_post_process gọi lại, và tôi có thể nhận được tất cả các trường hợp của ba tập tin từ image.queued_for_write và tôi muốn để kích hoạt jpegoptim/optipng bởi phần mở rộng tập tin, nhưng khi tôi sử dụng current_format = File.extname(file.path) , Tôi nhận được một cái gì đó như: .jpg20120508-7991-cqcpf2. Có cách nào để lấy chuỗi mở rộng jpg? hoặc là nó an toàn mà tôi chỉ kiểm tra nếu chuỗi mở rộng được chứa trong chuỗi đó?

+0

bất kỳ tin tức về các vấn đề này? – CharlieMezak

+0

@CharlieMezak Tôi đã dán các câu trả lời của riêng mình làm câu trả lời vì không có câu trả lời nào khác. Tôi có thể không phải là người tốt nhất và tôi rất vui khi được nghe nếu bạn có bất kỳ ý kiến ​​về điều đó. Cảm ơn. – larryzhao

Trả lời

4

Vì không có câu trả lời nào khác, đây là cách tôi làm điều đó trong dự án của tôi và có vẻ như nó đang hoạt động tốt trong vài tháng.

class AttachedImage < ActiveRecord::Base 
    belongs_to :attachable, :polymorphic => true 

    validates_attachment_presence :image 
    validates_attachment_content_type :image, :content_type=>['image/jpeg', 'image/png', 'image/gif'] 

    has_attached_file :image, 
        :styles => {:thumb => '50x50>', :preview => '270x270>' }, 
        # :processors => [:image_compressor], 
        :url => "/system/:class/:attachment/:id/:basename_:style.:extension", 
        :path => ":rails_root/public/system/:class/:attachment/:id/:basename_:style.:extension" 


    after_post_process :compress 

    private 
    def compress 
    current_format = File.extname(image.queued_for_write[:original].path) 

    image.queued_for_write.each do |key, file| 
     reg_jpegoptim = /(jpg|jpeg|jfif)/i 
     reg_optipng = /(png|bmp|gif|pnm|tiff)/i 

     logger.info("Processing compression: key: #{key} - file: #{file.path} - ext: #{current_format}") 

     if current_format =~ reg_jpegoptim 
     compress_with_jpegoptim(file) 
     elsif current_format =~ reg_optipng 
     compress_with_optpng(file) 
     else 
     logger.info("File: #{file.path} is not compressed!") 
     end 
    end 
    end 

    def compress_with_jpegoptim(file) 
    current_size = File.size(file.path) 
    Paperclip.run("jpegoptim", "-o --strip-all #{file.path}") 
    compressed_size = File.size(file.path) 
    compressed_ratio = (current_size - compressed_size)/current_size.to_f 
    logger.debug("#{current_size} - #{compressed_size} - #{compressed_ratio}") 
    logger.debug("JPEG family compressed, compressed: #{ '%.2f' % (compressed_ratio * 100) }%") 
    end 

    def compress_with_optpng(file) 
    current_size = File.size(file.path) 
    Paperclip.run("optipng", "-o7 --strip=all #{file.path}") 
    compressed_size = File.size(file.path) 
    compressed_ratio = (current_size - compressed_size)/current_size.to_f 
    logger.debug("#{current_size} - #{compressed_size} - #{compressed_ratio}") 
    logger.debug("PNG family compressed, compressed: #{ '%.2f' % (compressed_ratio * 100) }%") 
    end        
end 
1

Có thể là sự thỏa hiệp hiệu suất nhưng tôi có hình ảnh được nén tốt hơn với FFMPEG hoặc AVCONV.

sudo apt-get install ffmpeg 

= initializer

Paperclip.options[:command_path] = "/usr/bin/" # see `which ffmpeg` 

= Modal

after_save :compress_with_ffmpeg 

def compress_with_ffmpeg 
    [:thumb, :original, :medium].each do |type| 
    img_path = self.avtar.path(type) 
    Paperclip.run("ffmpeg", " -i #{img_path} #{img_path}") 
    end 
end 

tôi bị ảnh 1.7MB nén để 302.9KB !!!

Các vấn đề liên quan