2013-05-20 43 views
5

Tôi cần tạo các phiên bản khác nhau của hình ảnh được tải lên có điều kiện. Tôi biết Carrierwave hỗ trợ tính năng này. Nhưng yêu cầu của tôi hơi phức tạp một chút.Thay đổi kích thước hình ảnh có điều kiện bằng Carrierwave

Đối với mỗi hình ảnh được tải lên, tôi cần phải tạo 2 phiên bản và cần phải mở rộng hình ảnh gốc dựa trên điều kiện.

Dưới mã sẽ cung cấp cho bạn ý tưởng tốt hơn những gì tôi đang cố gắng để làm:

version :leftright, :if => :image? do 
    process :resize_to_fill => [667*2, 778*2] ,:if => :is_retina_resolution? 
    process :resize_to_fill => [667, 778] ,:if => !:is_retina_resolution? 
end 

version :updown, :if => :image? do 
    process :resize_to_fill => [1024*2, 487*2] ,:if => :is_retina_resolution? 
    process :resize_to_fill => [1024, 487] ,:if => !:is_retina_resolution? 
end 

#resize the original image 
process :resize_to_fill => [1024*2, 768*2] ,:if => :is_retina_resolution? 
process :resize_to_fill => [1024, 768] ,:if => !:is_retina_resolution? 

def is_retina_resolution?(new_file) 
    image = MiniMagick::Image.open(new_file.file) 
    true if image[:height] >= 1536 and image[:width] >= 2048 
end 

Rõ ràng đây không hoạt động. Carrierwave ném lỗi này:

Errno::ENOENT - No such file or directory - #<ActionDispatch::Http::UploadedFile:0xe41d508>

Và tôi đã cố gắng một biến thể:

version :leftright, :if => :image? do 
    if :is_retina_resolution? 
    process :resize_to_fill => [667*2, 778*2] 
    else 
    process :resize_to_fill => [667, 778] 
    end 
end 

version :updown, :if => :image? do 
    if :is_retina_resolution? 
    process :resize_to_fill => [1024*2, 487*2] 
    else 
    process :resize_to_fill => [1024, 487] 
    end 
end 

def is_retina_resolution?(new_file) 
    image = MiniMagick::Image.open(new_file) 
    true if image[:height] >= 1536 and image[:width] >= 2048 
end 

này không ném bất kỳ lỗi. Nhưng nó luôn luôn tạo ra các hình ảnh trong retina size (điều kiện 1)

Vì vậy, tôi cố gắng thêm một biến thể:

version :leftright, :if => :image? && :is_retina_resolution do 
    process :resize_to_fill => [667*2, 778*2] 
end 

version :leftright, :if => :image? && !:is_retina_resolution do 
    process :resize_to_fill => [667, 778] 
end 

version :updown, :if => :image? && :is_retina_resolution do 
    process :resize_to_fill => [1024*2, 487*2]  
end 

version :updown, :if => :image? && !:is_retina_resolution do 
    process :resize_to_fill => [1024, 487] 
end 

Điều này không ném bất kỳ lỗi và cũng không tạo ra bất kỳ phiên bản.

Ai đó có thể giúp tôi không?

Cập nhật:

Dựa trên đề nghị bởi @DMKE, tôi thực hiện thay đổi này, bây giờ nó hoạt động tốt

version :leftright, :if => :image? do 
    process :resize_to_fill => [667*2, 778*2] ,:if => :is_retina_resolution? 
    process :resize_to_fill => [667, 778] ,:if => :is_not_retina_resolution? 
end 

version :updown, :if => :image? do 
    process :resize_to_fill => [1024*2, 487*2] ,:if => :is_retina_resolution? 
    process :resize_to_fill => [1024, 487] ,:if => :is_not_retina_resolution?  
end 

#resize the original image 
process :resize_to_fill => [1024*2, 768*2] ,:if => :image_and_retina? 
process :resize_to_fill => [1024, 768] ,:if => :image_and_not_retina? 
process :if => :not_image? 

def image_and_retina?(img) 
    is_img = image? img 
    return false unless is_img 
    return is_retina_resolution?(img) 
end 

def image_and_not_retina?(img) 
    is_img = image? img 
    return false unless is_img 
    return !is_retina_resolution?(img) 
end 

# returns true if image file 
def image?(new_file) 
    self.file.content_type.include? 'image' 
end 

def not_image?(new_file) 
    !self.file.content_type.include? 'image' 
end 

def is_retina_resolution?(new_file) 
    image = MiniMagick::Image.open(self.file.file) 
    true if image[:height] >= 1536 and image[:width] >= 2048 
end 

def is_not_retina_resolution?(new_file) 
    image = MiniMagick::Image.open(self.file.file) 
    true if image[:height] < 1536 and image[:width] < 2048 
end 

Trả lời

7

Mặc dù không phải là một lỗi cú pháp, mã này có một lỗ hổng ngữ nghĩa:

version :updown, :if => :image? && !:is_retina_resolution do 
    # ... 
end 

Ở đây, :image? && !:is_retina_resolutionluôn luôn đánh giá sai (thử !:foo trong thiết bị đầu cuối IRb), do đó phiên bản :updownkhông bao giờ được tạo. Lời giải thích cũng áp dụng cho process foo: [sx,sy], if: !:bar?

Kể từ CarrierWave không hỗ trợ một tùy chọn :unless (như xa như tôi có thể nói), cách duy nhất để đạt được mục tiêu của bạn là một số định nghĩa phương pháp trong CarrierWave::Uploader::Base phân lớp của bạn:

process resize_to_fill: [667*2, 778*2], if: :image_and_retina? 
process resize_to_fill: [667, 778],  if: :image_and_not_retina? 

def image_and_retina?(img) 
    image?(img) && is_retina_resolution(img) 
end 

def image_and_not_retina?(img) 
    image?(img) && !is_retina_resolution(img) 
end 
+1

Cảm ơn @DMKE, dựa trên đề xuất của bạn, tôi đã thực hiện một số thay đổi và nó hoạt động tốt ngay bây giờ. – RameshVel

+3

Một điều rất vui được phục vụ. – DMKE