[ACCEPTED]-Ruby on Rails: How do you check if a file is an image?-ruby

Accepted answer
Score: 17

Please check it once

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

Score: 16

I would use the ruby-filemagic gem which is a Ruby binding 1 for libmagic.

Score: 13

One approach is to use the "magic number" convention 14 to read the first bits of a file.
http://www.astro.keele.ac.uk/oldusers/rno/Computing/File_magic.html

Examples:

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

Example 13 in 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

Why use this instead of the file 12 name extension or the filemagic module?

To 11 detect the data type before writing any 10 data to disk. For example, we can read upload 9 data stream before we write any data to 8 disk. If the magic number doesn't match 7 the web form content type, then we can immediately 6 report an error.

We implement our real-world 5 code slightly differently. We create a hash: each 4 key is a magic number string, each value 3 is a symbol like :bitmap, :gif, :jpeg, etc. If 2 anyone would like to see our real-world 1 code, feel free to contact me here.

Score: 7

Since you're using Paperclip, you can use 6 the built in "validates_attachment_content_type" method 5 in the model where "has_attached_file" is 4 used, and specify which file types you want 3 to allow.

Here's an example from an application 2 where users upload an avatar for their profile:

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"]

The 1 documentation is here http://dev.thoughtbot.com/paperclip/classes/Paperclip/ClassMethods.html

Score: 3

i honestly think this is way easier, use 4 mimemagic gem:

first install it

gem 'mimemagic'

open stream(bytes 3 of target image)

url="https://i.ebayimg.com/images/g/rbIAAOSwojpgyQz1/s-l500.jpg"
result = URI.parse(url).open

then check data-stream's 2 file type

for example:

MimeMagic.by_magic(result).type == "image/jpeg"

even though this might 1 be more elegant

%w(JPEG GIF TIFF PNG).include?(MimeMagic.by_magic(result).type)

Score: 1

imagemagick has a command called identity 3 that handles this - check w/ the paperclip 2 documentation - there's probably a way to 1 handle this from within your RoR app.

Score: 1

As an addition to Joel's answer, in Rails 2 5 I had to transform the comparison string 1 to a bytecode. Eg:

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

More Related questions