2010-03-16 37 views
9

Có cách nào để ném lỗi xác thực nếu người dùng cố tải lên cùng một ảnh hai lần lên ứng dụng Rails bằng Paperclip không? Paperclip dường như không cung cấp chức năng này ...Đường ray: Ngăn tải lên ảnh trùng lặp bằng kẹp giấy?

Tôi đang sử dụng Rails 2.3.5 và Paperclip (hiển nhiên).


GIẢI PHÁP: (hoặc một trong số họ, ít nhất)

Sử dụng gợi ý Beerlington, tôi quyết định đi với một sự so sánh MD5 Checksum:

class Photo < ActiveRecord::Base 
    #... 
    has_attached_file :image #, ... 

    before_validation_on_create :generate_md5_checksum 
    validate :unique_photo 
    #... 

    def generate_md5_checksum 
    self.md5_checksum = Digest::MD5.hexdigest(image.to_file.read) 
    end 

    def unique_photo 
    photo_digest = self.md5_checksum 
    errors.add_to_base "You have already uploaded that file!" unless User.find(self.user_id).photos.find_by_md5_checksum(photo_digest).nil? 
    end 

    # ... 
end 

Sau đó, tôi chỉ cần thêm một cột để bảng photos của tôi có tên là md5_checksum và thì đấy! Bây giờ ứng dụng của tôi ném lỗi xác thực nếu bạn cố gắng tải lên cùng một ảnh!

Không có ý tưởng về hiệu quả/không hiệu quả như thế nào, vì vậy hãy tiếp tục tái cấu trúc!

Cảm ơn!

+0

nếu bạn xem trực tuyến thuật toán so sánh hình ảnh, bạn sẽ tìm thấy một số tệp dll (do phần mềm Bolide phát hành) có thể biết hai hình ảnh giống nhau nhưng không được sử dụng nhiều trong ứng dụng đường ray. Bạn có thể có thể thử và viết alogrithm của riêng bạn mặc dù tôi không biết nếu nó sẽ có giá trị rắc rối. – stephenmurdoch

Trả lời

10

Còn việc thực hiện MD5 trên tệp hình ảnh thì sao? Nếu đó là chính xác cùng một tệp, băm MD5 sẽ giống nhau cho cả hai hình ảnh.

+0

Điều này hoạt động giống như một sự quyến rũ! Cảm ơn; không nghĩ về điều này! – neezer

+1

Cẩn thận ở đây! Bạn đang vẽ dấu vân tay _one_ biểu diễn nhị phân. Thường có hàng triệu tệp nhị phân sẽ hiển thị trên màn hình máy tính giống hệt nhau. Từ idiotic: Tôi đã thay đổi hình ảnh (thay đổi siêu dữ liệu) chỉ đơn giản bằng cách mở và đóng tệp trong phần mềm chỉnh sửa ảnh. Với phần mềm độc hại: Chỉ cần thay đổi một số siêu dữ liệu hoặc thêm một số byte vào cuối (phần mềm bị bỏ qua nhiều nhất) hoặc thay đổi kích thước hoặc định lại mẫu và hình ảnh có thể được tải lên lại và lặp lại. –

0

Như Stephen đã nêu, vấn đề lớn nhất của bạn là cách xác định xem tệp có trùng lặp hay không và không có câu trả lời rõ ràng cho việc này.

Nếu đây là những ảnh được chụp bằng máy ảnh kỹ thuật số, bạn sẽ muốn so sánh dữ liệu EXIF. Nếu dữ liệu EXIF ​​khớp với nhau thì ảnh có nhiều khả năng trùng lặp nhất. Nếu nó là một bản sao thì bạn có thể thông báo cho người dùng về điều này. Bạn sẽ phải chấp nhận tải lên ban đầu để bạn kiểm tra dữ liệu EXIF.

Tôi nên đề cập rằng EXIFR là đá quý ruby ​​đẹp để kiểm tra dữ liệu EXIF.

10

Đối với bất kỳ ai khác đang cố gắng thực hiện việc này. Paperclip bây giờ có md5 băm được xây dựng in Nếu bạn có một [đính kèm] _fingerprint trong mô hình của bạn, kẹp giấy sẽ cư này với MD5.

Kể từ khi tôi đã có một cột tên là hash_value, tôi đã thực hiện một thuộc tính 'ảo' được gọi là vân tay

#Virtual attribute to have paperclip generate the md5 
def picture_fingerprint 
    self.hash_value 
end 

def picture_fingerprint=(md5Hash) 
    self.hash_value=md5Hash 
end 

Và, với rails3, sử dụng sexy_validations, tôi đã có thể chỉ đơn giản là thêm video này vào đầu mô hình của mình để đảm bảo rằng hash_value là duy nhất trước khi lưu mô hình:

validates :hash_value, :uniqueness => { :message => "Image has already been uploaded." } 
3

Bạn có thể gặp sự cố khi hình ảnh của bạn đã sửa đổi siêu dữ liệu EXIF. Điều này đã xảy ra với tôi, và tôi đã phải trích xuất các giá trị pixel và tính MD5 ra khỏi chúng, để bỏ qua những thay đổi được thực hiện bởi Wordpress vv Bạn có thể đọc về nó trên blog của chúng tôi: http://www.amberbit.com/blog/2013/12/20/similar-images-detection-in-ruby-with-phash/ nhưng về cơ bản bạn muốn lấy dữ liệu pixel ra khỏi hình ảnh một số công cụ (như RMagick), concatinate nó vào chuỗi, và tính toán MD5 ra khỏi đó.

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