class ImageSize

Constants

JpegCodeCheck

Public Class Methods

new(img_data, img_type = nil) click to toggle source

receive image & make size argument 1 is image String, StringIO or IO argument 2 is type(ImageSize::Type::GIF and so on.) or nil

   # File lib/image_size.rb
40   def initialize(img_data, img_type = nil)
41     @img_data = img_data.dup
42     @img_width  = nil
43     @img_height = nil
44     @img_type   = nil
45 
46     if @img_data.is_a?(IO)
47       img_top = @img_data.read(1024)
48       img_io = def_read_o(@img_data)
49     elsif @img_data.is_a?(StringIO)
50       img_top = @img_data.read(1024)
51       img_io = def_read_o(@img_data)
52     elsif @img_data.is_a?(String)
53       img_top = @img_data[0, 1024]
54 #      img_io = StringIO.open(@img_data){|sio| io = def_read_o(sio); io }
55       img_io = StringIO.open(@img_data)
56       img_io = def_read_o(img_io)
57     else
58       raise "argument class error!! #{img_data.type}"
59     end
60     
61     if @img_type.nil?
62       @img_type = check_type(img_top)
63     else
64       type = Type.constants.find{|t| img_type == t }
65       raise("type is failed. #{img_type}\n") if !type
66       @img_type = img_type
67     end
68 
69     if @img_type != Type::OTHER
70       @img_width, @img_height = self.__send__("measure_#{@img_type}", img_io)
71     else
72       @img_width, @img_height = [nil, nil]
73     end
74     
75     if @img_data.is_a?(String)
76       img_io.close
77     end
78   end
type_list() click to toggle source

image type list

   # File lib/image_size.rb
33 def ImageSize.type_list
34   Type.constants 
35 end

Public Instance Methods

get_height() click to toggle source

get image height

   # File lib/image_size.rb
85 def get_height
86   if @img_type == Type::OTHER then nil else @img_height end
87 end
Also aliased as: height, h
get_size() click to toggle source

get image width and height(Array)

   # File lib/image_size.rb
95 def get_size
96   [self.get_width, self.get_height]
97 end
Also aliased as: size
get_type() click to toggle source

get image type ex. “GIF”, “PNG”, “JPEG”

   # File lib/image_size.rb
82 def get_type; @img_type; end
get_width() click to toggle source

get image width

   # File lib/image_size.rb
90 def get_width
91   if @img_type == Type::OTHER then nil else @img_width end
92 end
Also aliased as: width, w
h()
Alias for: get_height
height()
Alias for: get_height
size()
Alias for: get_size
w()
Alias for: get_width
width()
Alias for: get_width

Private Instance Methods

check_type(img_top) click to toggle source
    # File lib/image_size.rb
123 def check_type(img_top)
124   if img_top.force_encoding(Encoding::ASCII_8BIT) =~ /^GIF8[7,9]a/n 
125     then Type::GIF
126   elsif img_top[0, 8] == "\x89PNG\x0d\x0a\x1a\x0a" then Type::PNG
127   elsif img_top[0, 2] == "\xFF\xD8"                then Type::JPEG
128   elsif img_top[0, 2] == 'BM'                      then Type::BMP
129   elsif img_top =~ /^P[1-7]/n                       then Type::PPM
130   elsif img_top =~ /\#define\s+\S+\s+\d+/n          then Type::XBM
131   elsif img_top[0, 4] == "MM\x00\x2a"              then Type::TIFF
132   elsif img_top[0, 4] == "II\x2a\x00"              then Type::TIFF
133   elsif img_top =~ /\/\* XPM \*\//n                 then Type::XPM
134   elsif img_top[0, 4] == "8BPS"                    then Type::PSD
135   elsif img_top[1, 2] == "WS"                      then Type::SWF
136   elsif img_top[0] == 10                           then Type::PCX
137   else Type::OTHER
138   end
139 end
def_read_o(io) click to toggle source

define read_o

    # File lib/image_size.rb
111 def def_read_o(io)
112   io.seek(0, 0)
113   # define Singleton-method definition to IO (byte, offset)
114   def io.read_o(length = 1, offset = nil)
115     self.seek(offset, 0) if offset
116     ret = self.read(length)
117     raise "cannot read!!" unless ret
118     ret
119   end
120   io
121 end
measure_BMP(img_io) click to toggle source
    # File lib/image_size.rb
167 def measure_BMP(img_io)
168   img_io.read_o(26).unpack("x18VV");
169 end
measure_GIF(img_io) click to toggle source
    # File lib/image_size.rb
141 def measure_GIF(img_io)
142   img_io.read_o(6)
143   img_io.read_o(4).unpack('vv')
144 end
measure_JPEG(img_io) click to toggle source
    # File lib/image_size.rb
152 def measure_JPEG(img_io)
153   c_marker = "\xFF"   # Section marker.
154   img_io.read_o(2)
155   while(true)
156     marker, code, length = img_io.read_o(4).unpack('aan')
157     raise "JPEG marker not found!" if marker != c_marker
158 
159     if JpegCodeCheck.include?(code)
160       height, width = img_io.read_o(5).unpack('xnn')
161       return([width, height])
162     end
163     img_io.read_o(length - 2)
164   end
165 end
measure_PBM(img_io)
Alias for: measure_PPM
measure_PCX(img_io) click to toggle source
    # File lib/image_size.rb
256 def measure_PCX(img_io)
257   header = img_io.read_o(128)
258   head_part = header.unpack('C4S4')
259   width = head_part[6] - head_part[4] + 1
260   height = head_part[7] - head_part[5] + 1
261   [width, height]
262 end
measure_PGM(img_io)
Alias for: measure_PPM
measure_PNG(img_io) click to toggle source
    # File lib/image_size.rb
146 def measure_PNG(img_io)
147   img_io.read_o(12)
148   raise "This file is not PNG." unless img_io.read_o(4) == "IHDR"
149   img_io.read_o(8).unpack('NN')
150 end
measure_PPM(img_io) click to toggle source
    # File lib/image_size.rb
171   def measure_PPM(img_io)
172     header = img_io.read_o(1024)
173     header.gsub!(/^\#[^\n\r]*/m, "")
174     header =~ /^(P[1-6])\s+?(\d+)\s+?(\d+)/m
175     width = $2.to_i; height = $3.to_i
176     case $1
177       when "P1", "P4" then @img_type = "PBM"
178       when "P2", "P5" then @img_type = "PGM"
179       when "P3", "P6" then @img_type = "PPM"
180 #     when "P7"
181 #       @img_type = "XV"
182 #       header =~ /IMGINFO:(\d+)x(\d+)/m
183 #       width = $1.to_i; height = $2.to_i
184     end
185     [width, height]
186   end
Also aliased as: measure_PGM, measure_PBM
measure_PSD(img_io) click to toggle source
    # File lib/image_size.rb
207 def measure_PSD(img_io)
208   img_io.read_o(26).unpack("x14NN")
209 end
measure_SWF(img_io) click to toggle source
    # File lib/image_size.rb
264 def measure_SWF(img_io)
265   header = img_io.read_o(9)
266   
267   sig1 = header[0,1]
268   sig2 = header[1,1]
269   sig3 = header[2,1]
270 
271   if !((sig1 == 'F' || sig1 == 'C') && sig2 == 'W' && sig3 == 'S')
272     raise("This file is not SWF.")
273   end
274 
275   bit_length = Integer("0b#{header.unpack('@8B5')}")
276   header << img_io.read_o(bit_length*4/8+1)
277   str = header.unpack("@8B#{5+bit_length*4}")[0]
278   last = 5
279   x_min = Integer("0b#{str[last,bit_length]}")
280   x_max = Integer("0b#{str[(last += bit_length),bit_length]}")
281   y_min = Integer("0b#{str[(last += bit_length),bit_length]}")
282   y_max = Integer("0b#{str[(last += bit_length),bit_length]}")
283   width = (x_max - x_min)/20
284   height = (y_max - y_min)/20
285   [width, height]
286 end
measure_TIFF(img_io) click to toggle source
    # File lib/image_size.rb
211   def measure_TIFF(img_io)
212     endian = if (img_io.read_o(4) =~ /II\x2a\x00/o) then 'v' else 'n' end
213 # 'v' little-endian   'n' default to big-endian
214 
215     packspec = [
216       nil,           # nothing (shouldn't happen)
217       'C',           # BYTE (8-bit unsigned integer)
218       nil,           # ASCII
219       endian,        # SHORT (16-bit unsigned integer)
220       endian.upcase, # LONG (32-bit unsigned integer)
221       nil,           # RATIONAL
222       'c',           # SBYTE (8-bit signed integer)
223       nil,           # UNDEFINED
224       endian,        # SSHORT (16-bit unsigned integer)
225       endian.upcase, # SLONG (32-bit unsigned integer)
226     ]
227 
228     offset = img_io.read_o(4).unpack(endian.upcase)[0] # Get offset to IFD
229 
230     ifd = img_io.read_o(2, offset)
231     num_dirent = ifd.unpack(endian)[0]                   # Make it useful
232     offset += 2
233     num_dirent = offset + (num_dirent * 12);             # Calc. maximum offset of IFD
234 
235     ifd = width = height = nil
236     while(width.nil? || height.nil?)
237       ifd = img_io.read_o(12, offset)                 # Get first directory entry
238       break if (ifd.nil? || (offset > num_dirent))
239       offset += 12
240       tag = ifd.unpack(endian)[0]                       # ...and decode its tag
241       type = ifd[2, 2].unpack(endian)[0]                # ...and the data type
242 
243      # Check the type for sanity.
244       next if (type > packspec.size + 0) || (packspec[type].nil?)
245       if tag == 0x0100                                  # Decode the value
246         width = ifd[8, 4].unpack(packspec[type])[0]
247       elsif tag == 0x0101                               # Decode the value
248         height = ifd[8, 4].unpack(packspec[type])[0]
249       end
250     end
251 
252     raise "#{if width.nil? then 'width not defined.' end} #{if height.nil? then 'height not defined.' end}" if width.nil? || height.nil?
253     [width, height]
254   end
measure_XBM(img_io) click to toggle source
    # File lib/image_size.rb
191 def measure_XBM(img_io)
192   img_io.read_o(1024) =~ /^\#define\s*\S*\s*(\d+)\s*\n\#define\s*\S*\s*(\d+)/mi
193   [$1.to_i, $2.to_i]
194 end
measure_XPM(img_io) click to toggle source
    # File lib/image_size.rb
196 def measure_XPM(img_io)
197   width = height = nil
198   while(line = img_io.read_o(1024))
199     if line =~ /"\s*(\d+)\s+(\d+)(\s+\d+\s+\d+){1,2}\s*"/m
200       width = $1.to_i; height = $2.to_i
201       break
202     end
203   end
204   [width, height]
205 end