2010-03-15 33 views

Trả lời

2

libimage-size là một thư viện Ruby cho việc tính toán kích thước hình ảnh cho một loạt các định dạng đồ họa. Đá quý có sẵn hoặc bạn có thể tải xuống tệp tarball nguồn và giải nén tệp image_size.rb.

+1

Tôi không nghĩ rằng điều này làm việc với ruby ​​1.9 – Jonathan

26

Bạn có thể thử này (chưa được kiểm tra):

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 
+3

Ooo, ngọt, goin 'sau byte trực tiếp! Trường cũ! –

+0

Ruby 1.9 đã phá vỡ lớp JPEG bạn trích dẫn ở đây; Tôi đã gửi một câu trả lời bổ sung với sửa đổi của tôi của lớp đó để làm việc cả dưới Ruby 1.8.7 và Ruby 1.9. – matt

+0

@matt: cảm ơn bạn đã bình luận, bạn đã nhận được ý kiến ​​của mình! – ChristopheD

14

Có một phương pháp tiện dụng trong viên ngọc kẹp giấy:

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

chỉ này hoạt động nếu identify được cài đặt. Nếu không, nếu PHP được cài đặt, bạn có thể làm một cái gì đó như thế này:

system(%{php -r '$w = getimagesize("#{path}"); echo("${w[0]}x${w[1]}");'}) 
# eg returns "200x100" (width x height) 
+0

Đây là giải pháp tuyệt vời, tuy nhiên nó dựa trên công cụ 'ident' của ImageMagick được cài đặt –

+0

Điểm tốt, được cập nhật bằng phương pháp thay thế. – Zubin

7

Cuối cùng tôi đã tìm thấy một cách nhanh chóng để có được kích thước của hình ảnh. Bạn nên sử dụng 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] 
+5

Sử dụng ImageMagick mà người đăng tải yêu cầu không sử dụng. – jcalvert

+0

Ít nhất nó đã giúp tôi vào năm 2018 <3 –

26

Ngoài ra còn có một thư viện mới (tháng 7 năm 2011) mà không có mặt vào thời điểm câu hỏi ban đầu được hỏi: các Dimensions rubygem (mà dường như được tác giả cùng Sam Stephenson chịu trách nhiệm về byte-thao tác kỹ thuật cũng đề nghị ở đây.)

Dưới đây mẫu mã từ README của dự án

require 'dimensions' 

Dimensions.dimensions("upload_bird.jpg") # => [300, 225] 
Dimensions.width("upload_bird.jpg")  # => 300 
Dimensions.height("upload_bird.jpg")  # => 225 
+0

Viên ngọc này đã làm việc rất tốt cho tôi. Trên bề mặt nó không làm nhiều nhưng các lớp bên trong rất linh hoạt và được viết tốt. – bloudermilk

41

Tính đến tháng năm 2012, FastImage mà "thấy kích thước hoặc loại một hình ảnh cho uri của nó bằng cách lấy ít nhất là cần thiết" là một lựa chọn tốt. Nó hoạt động với các hình ảnh cục bộ và các hình ảnh trên các máy chủ từ xa.

Một ví dụ IRB từ readme:

require 'fastimage' 

FastImage.size("http://stephensykes.com/images/ss.com_x.gif") 
=> [266, 56] # width, height 

phân mảng tiêu chuẩn trong một kịch bản:

require 'fastimage' 

size_array = FastImage.size("http://stephensykes.com/images/ss.com_x.gif") 

puts "Width: #{size_array[0]}" 
puts "Height: #{size_array[1]}" 

Hoặc, sử dụng nhiều phân trong một kịch bản:

require 'fastimage' 

width, height = FastImage.size("http://stephensykes.com/images/ss.com_x.gif") 

puts "Width: #{width}" 
puts "Height: #{height}" 
+1

tôi nghĩ rằng đây là giải pháp tốt – seapy

+1

Điều này hoạt động tốt. – Matt

3

Dưới đây là một phiên bản của lớp JPEG từ câu trả lời của ChristopheD hoạt động trong cả Ruby 1.8.7 và Ruby 1.9. Điều này cho phép bạn có được chiều rộng và chiều cao của tệp hình ảnh JPEG (.jpg) bằng cách xem trực tiếp các bit. (Hoặc, chỉ cần sử dụng đá quý Thứ nguyên, như được đề xuất trong câu trả lời khác.)

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 
Các vấn đề liên quan