2010-02-08 3 views
15

Как бы вы проверить, если файл является изображением? Я думаю, вы можете использовать такой метод:Ruby on Rails: Как вы проверяете, является ли файл изображением?

def image?(file) 
    file.to_s.include?(".gif") or file.to_s.include?(".png") or file.to_s.include?(".jpg") 
end 

Но это может быть немного неэффективным и неправильным. Есть идеи?

(я использую плагин скрепки, кстати, но я не вижу никаких методов, чтобы определить, является ли файл изображения в скрепке)

ответ

12

Я хотел бы использовать ruby-filemagic драгоценный камень, который является обязательным для рубина libmagic.

+0

Спасибо Синан за отличную ссылку! Я не знал, что это было. Спасибо. – sjsc

+0

Команда файла действительно хороша для этого, поэтому эта оболочка должна выполнять эту работу. – tadman

1

У imagemagick есть команда под названием identity, которая обрабатывает это - проверьте документацию скрепки - возможно, это способ справиться с этим из вашего RoR-приложения.

+0

Спасибо за отзыв Клода и Джона на личность. У меня будет чек. Большое вам спасибо за реферал. – sjsc

7

Поскольку вы используете Paperclip, вы можете использовать встроенный метод validates_attachment_content_type в модели, где используется «has_attached_file», и указать, какие типы файлов вы хотите разрешить.

Вот пример из приложения, где пользователи загрузить аватар для своего профиля:

has_attached_file :avatar, 
        :styles => { :thumb => "48x48#" }, 
        :default_url => "/images/avatars/missing_avatar.png", 
        :default_style => :thumb 

validates_attachment_content_type :avatar, :content_type => ["image/jpeg", "image/pjpeg", "image/png", "image/x-png", "image/gif"] 

Документация находится здесь http://dev.thoughtbot.com/paperclip/classes/Paperclip/ClassMethods.html

+0

Спасибо, Биэрлингтон! – sjsc

10

Один подход заключается в использовании «магическое число» соглашение, чтобы прочитать первый бит файла.
http://www.astro.keele.ac.uk/oldusers/rno/Computing/File_magic.html

Примеры:

 
    "BM" is a Bitmap image 
    "GIF8" is a GIF image 
    "\xff\xd8\xff\xe0" is a JPEG image 

Пример в Ruby:

 
    def bitmap?(data) 
    return data[0,2]=="MB" 
    end 

    def gif?(data) 
    return data[0,4]=="GIF8" 
    end 

    def jpeg?(data) 
    return data[0,4]=="\xff\xd8\xff\xe0" 
    end 

    def file_is_image?(filename) 
    f = File.open(filename,'rb') # rb means to read using binary 
    data = f.read(9)    # magic numbers are up to 9 bytes 
    f.close 
    return bitmap?(data) or gif?(data) or jpeg?(data) 
    end 

Зачем использовать это вместо того, чтобы расширение имени файла или filemagic модуля?

Чтобы определить тип данных перед записью любых данных на диск. Например, мы можем прочитать поток данных для загрузки, прежде чем писать какие-либо данные на диск. Если магическое число не соответствует типу содержимого веб-формы, мы можем немедленно сообщить об ошибке.

Мы реализуем наш код реального мира несколько иначе. Мы создаем хэш: каждый ключ представляет собой строку магического числа, каждое значение представляет собой символ: bitmap,: gif,: jpeg и т. Д. Если кто-то хочет увидеть наш код реального мира, не стесняйтесь связываться со мной здесь.

+2

Другим подходом при проверке 'jpeg?' Будет 'return data [0,3].bytes == [255, 216, 255] ' – n1313

7

Пожалуйста, проверьте его раз

MIME::Types.type_for('tmp/img1.jpg').first.try(:media_type) 
=> "image" 

MIME::Types.type_for('tmp/img1.jpeg').first.try(:media_type) 
=> "image" 

MIME::Types.type_for('tmp/img1.gif').first.try(:media_type) 
=> "image" 

MIME::Types.type_for('tmp/ima1.png').first.try(:media_type) 
=> "image" 
+0

Я не знаю, почему вы получили downvoted, но это отлично работает в Rails 5.0! Спасибо. – Vlad

0

В дополнение к ответу Иоиля, в Rails 5 я должен был преобразовать строку сравнения в байткод. Например:

def jpeg?(data) 
    return data[0,4]=="\xff\xd8\xff\xe0".b 
end 
Смежные вопросы