Is there a simple way to get image dimensions in Ruby?

前端 未结 8 899
隐瞒了意图╮
隐瞒了意图╮ 2020-12-14 06:57

I\'m looking for an easy way to get width and height dimensions for image files in Ruby without having to use ImageMagick or ImageScience (running Snow Leapard).

相关标签:
8条回答
  • 2020-12-14 07:04

    libimage-size is a Ruby library for calculating image sizes for a wide variety of graphical formats. A gem is available, or you can download the source tarball and extract the image_size.rb file.

    0 讨论(0)
  • 2020-12-14 07:07

    There's a handy method in the paperclip gem:

    >> Paperclip::Geometry.from_file("/path/to/image.jpg")
    => 180x180
    

    This only works if identify is installed. If it isn't, if PHP is installed, you could do something like this:

    system(%{php -r '$w = getimagesize("#{path}"); echo("${w[0]}x${w[1]}");'})
    # eg returns "200x100" (width x height)
    
    0 讨论(0)
  • 2020-12-14 07:13

    For PNGs I got this modified version of ChristopeD's method to work.

    File.binread(path, 64)[0x10..0x18].unpack('NN')
    
    0 讨论(0)
  • 2020-12-14 07:16

    You could try these (untested):

    http://snippets.dzone.com/posts/show/805

    PNG:

    IO.read('image.png')[0x10..0x18].unpack('NN')
    => [713, 54]
    

    GIF:

    IO.read('image.gif')[6..10].unpack('SS')
    => [130, 50]
    

    BMP:

    d = IO.read('image.bmp')[14..28]
    d[0] == 40 ? d[4..-1].unpack('LL') : d[4..8].unpack('SS')
    

    JPG:

    class JPEG
      attr_reader :width, :height, :bits
    
      def initialize(file)
        if file.kind_of? IO
          examine(file)
        else
          File.open(file, 'rb') { |io| examine(io) }
        end
      end
    
    private
      def examine(io)
        raise 'malformed JPEG' unless io.getc == 0xFF && io.getc == 0xD8 # SOI
    
        class << io
          def readint; (readchar << 8) + readchar; end
          def readframe; read(readint - 2); end
          def readsof; [readint, readchar, readint, readint, readchar]; end
          def next
            c = readchar while c != 0xFF
            c = readchar while c == 0xFF
            c
          end
        end
    
        while marker = io.next
          case marker
            when 0xC0..0xC3, 0xC5..0xC7, 0xC9..0xCB, 0xCD..0xCF # SOF markers
              length, @bits, @height, @width, components = io.readsof
              raise 'malformed JPEG' unless length == 8 + components * 3
            when 0xD9, 0xDA:  break # EOI, SOS
            when 0xFE:        @comment = io.readframe # COM
            when 0xE1:        io.readframe # APP1, contains EXIF tag
            else              io.readframe # ignore frame
          end
        end
      end
    end
    
    0 讨论(0)
  • 2020-12-14 07:17

    I have finally found a nice quick way to get dimensions of an image. You should use MiniMagick.

    require 'mini_magick'
    
    image = MiniMagick::Image.open('http://www.thetvdb.com/banners/fanart/original/81189-43.jpg')
    assert_equal 1920, image[:width]
    assert_equal 1080, image[:height]
    
    0 讨论(0)
  • 2020-12-14 07:22

    Here's a version of the JPEG class from ChristopheD's answer that works in both Ruby 1.8.7 and Ruby 1.9. This allows you to get the width and height of a JPEG (.jpg) image file by looking directly at the bits. (Alternatively, just use the Dimensions gem, as suggested in another answer.)

    class JPEG
      attr_reader :width, :height, :bits
      def initialize(file)
        if file.kind_of? IO
          examine(file)
        else
          File.open(file, 'rb') { |io| examine(io) }
        end
      end
    private
      def examine(io)
        if RUBY_VERSION >= "1.9"
          class << io
            def getc; super.bytes.first; end
            def readchar; super.bytes.first; end
          end
        end
        class << io
          def readint; (readchar << 8) + readchar; end
          def readframe; read(readint - 2); end
          def readsof; [readint, readchar, readint, readint, readchar]; end
          def next
            c = readchar while c != 0xFF
            c = readchar while c == 0xFF
            c
          end
        end
        raise 'malformed JPEG' unless io.getc == 0xFF && io.getc == 0xD8 # SOI
        while marker = io.next
          case marker
            when 0xC0..0xC3, 0xC5..0xC7, 0xC9..0xCB, 0xCD..0xCF # SOF markers
              length, @bits, @height, @width, components = io.readsof
              raise 'malformed JPEG' unless length == 8 + components * 3
            # colons not allowed in 1.9, change to "then"
            when 0xD9, 0xDA then  break # EOI, SOS
            when 0xFE then        @comment = io.readframe # COM
            when 0xE1 then        io.readframe # APP1, contains EXIF tag
            else                  io.readframe # ignore frame
          end
        end
      end
    end
    
    0 讨论(0)
提交回复
热议问题