Skip to content

Commit

Permalink
Adds reading from an IO object
Browse files Browse the repository at this point in the history
  • Loading branch information
sdsykes committed Sep 30, 2011
1 parent f1ba3f1 commit d007cb4
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 20 deletions.
2 changes: 1 addition & 1 deletion MIT_LICENCE
@@ -1,4 +1,4 @@
Copyright (c) 2008 Stephen Sykes
Copyright (c) 2008-2011 Stephen Sykes

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
Expand Down
4 changes: 2 additions & 2 deletions README
Expand Up @@ -31,7 +31,7 @@ Installation

h4. Gem

sudo gem install sdsykes-fastimage -s http://gems.github.com
gem install fastimage

h4. Rails

Expand All @@ -40,7 +40,7 @@ Install the gem as above, and configure it in your environment.rb file as below:
...
Rails::Initializer.run do |config|
...
config.gem "sdsykes-fastimage", :lib=>"fastimage"
config.gem "fastimage", :lib=>"fastimage"
...
end
...
Expand Down
14 changes: 9 additions & 5 deletions README.textile
Expand Up @@ -8,14 +8,17 @@ Your app needs to find the size or type of an image. This could be for adding w

But the image is not locally stored - it's on another asset server, or in the cloud - at Amazon S3 for example.

You don't want to download the entire image to your app server - it could be many tens of kilobytes, or even megabytes just to get this information. For most image types, the size of the image is simply stored at the start of the file. For JPEG files it's a little bit more complex, but even so you do not need to fetch most of the image to find the size.
You don't want to download the entire image to your app server - it could be many tens of kilobytes, or even megabytes just to get this information. For most image types, the size of the image is simply stored at the start of the file. For JPEG files it's a little bit more complex, but even so you do not need to fetch much of the image to find the size.

FastImage does this minimal fetch for image types GIF, JPEG, PNG and BMP. And it doesn't rely on installing external libraries such as RMagick (which relies on ImageMagick or GraphicsMagick) or ImageScience (which relies on FreeImage).

You only need supply the uri, and FastImage will do the rest.

Fastimage can also read local (and other) files, and uses the open-uri library to do so.

And new in v1.2.9, FastImage will automatically read from any object that responds to :read - for
instance an IO object if that is passed instead of a URI.

h2. Examples

<pre>
Expand All @@ -37,19 +40,19 @@ h4. Gem

<pre>
<code>
sudo gem install fastimage
gem install fastimage
</code>
</pre>

h4. Rails

Install the gem as above, and configure it in your environment.rb file as below:
Install the gem as above, and add it to your Gemfile if you are using bundler, or configure it in your environment.rb file as below:
<pre>
<code>
...
Rails::Initializer.run do |config|
...
config.gem "fastimage", :lib=>"fastimage"
config.gem "fastimage"
...
end
...
Expand Down Expand Up @@ -84,5 +87,6 @@ h2. References
* "http://www.anttikupila.com/flash/getting-jpg-dimensions-with-as3-without-loading-the-entire-file/":http://www.anttikupila.com/flash/getting-jpg-dimensions-with-as3-without-loading-the-entire-file/
* "http://imagesize.rubyforge.org/":http://imagesize.rubyforge.org/

h2. Licence

(c) 2009 Stephen Sykes
MIT, see file MIT_LICENCE
2 changes: 1 addition & 1 deletion VERSION.yml
@@ -1,5 +1,5 @@
---
:patch: 8
:patch: 9
:major: 1
:build:
:minor: 2
2 changes: 1 addition & 1 deletion fastimage.gemspec
@@ -1,6 +1,6 @@
Gem::Specification.new do |s|
s.name = %q{fastimage}
s.version = "1.2.8"
s.version = "1.2.9"

s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
s.authors = ["Stephen Sykes"]
Expand Down
36 changes: 26 additions & 10 deletions lib/fastimage.rb
Expand Up @@ -13,6 +13,9 @@
# it has enough. This is possibly a useful bandwidth-saving feature if the file is on a network
# attached disk rather than truly local.
#
# New in v1.2.9, FastImage will automatically read from any object that responds to :read - for
# instance an IO object if that is passed instead of a URI.
#
# === Examples
# require 'fastimage'
#
Expand All @@ -22,6 +25,8 @@
# => :png
# FastImage.type("/some/local/file.gif")
# => :gif
# File.open("/some/local/file.gif", "r") {|io| FastImage.type(io)}
# => :gif
#
# === References
# * http://snippets.dzone.com/posts/show/805
Expand Down Expand Up @@ -121,6 +126,8 @@ def self.size(uri, options={})
# => :jpeg
# FastImage.type("http://pennysmalls.com/does_not_exist")
# => nil
# File.open("/some/local/file.gif", "r") {|io| FastImage.type(io)}
# => :gif
#
# === Supported options
# [:timeout]
Expand All @@ -136,15 +143,20 @@ def initialize(uri, options={})
@property = options[:type_only] ? :type : :size
@timeout = options[:timeout] || DefaultTimeout
@uri = uri
begin
@parsed_uri = URI.parse(uri)
rescue URI::InvalidURIError
fetch_using_open_uri

if uri.respond_to?(:read)
fetch_using_read(uri)
else
if @parsed_uri.scheme == "http" || @parsed_uri.scheme == "https"
fetch_using_http
else
begin
@parsed_uri = URI.parse(uri)
rescue URI::InvalidURIError
fetch_using_open_uri
else
if @parsed_uri.scheme == "http" || @parsed_uri.scheme == "https"
fetch_using_http
else
fetch_using_open_uri
end
end
end
raise SizeNotFound if options[:raise_on_failure] && @property == :size && !@size
Expand Down Expand Up @@ -177,11 +189,15 @@ def setup_http
@http.read_timeout = @timeout
end

def fetch_using_read(readable)
while str = readable.read(LocalFileChunkSize)
break if parse_packet(str)
end
end

def fetch_using_open_uri
open(@uri) do |s|
while str = s.read(LocalFileChunkSize)
break if parse_packet(str)
end
fetch_using_read(s)
end
end

Expand Down
16 changes: 16 additions & 0 deletions test/test.rb
Expand Up @@ -100,6 +100,22 @@ def test_should_report_size_correctly_for_local_files
end
end

def test_should_report_type_correctly_for_ios
GoodFixtures.each do |fn, info|
File.open(File.join(FixturePath, fn), "r") do |io|
assert_equal info[0], FastImage.type(io)
end
end
end

def test_should_report_size_correctly_for_ios
GoodFixtures.each do |fn, info|
File.open(File.join(FixturePath, fn), "r") do |io|
assert_equal info[1], FastImage.size(io)
end
end
end

def test_should_report_size_correctly_for_local_files_with_path_that_has_spaces
Dir.chdir(PathHere) do
assert_equal GoodFixtures["test.bmp"][1], FastImage.size(File.join("fixtures", "folder with spaces", "test.bmp"))
Expand Down

0 comments on commit d007cb4

Please sign in to comment.