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
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
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_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_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