# \[ANN\] SuperImage plugin

**URL:** <https://www.ruby-forum.com/t/ann-superimage-plugin/94256>\
**Category:** Rails\
**Created:** [April 27, 2006, 3:33am UTC](https://www.ruby-forum.com/t/ann-superimage-plugin/94256 "2006-04-27T03:33:26Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![squeegy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/dec6dc/32.png) [@squeegy](https://www.ruby-forum.com/u/squeegy)\
**Post date:** [April 27, 2006, 3:33am UTC](https://www.ruby-forum.com/t/ann-superimage-plugin/94256/1 "2006-04-27T03:33:26Z")

</div>

Greetings all,

This is the first release of the SuperImage plugin. The idea is you  
upload images to the database, and then pull them out at any size you  
want. Combine this with caching and it will stay light and fast.

More info and instructions are here:  
[http://beautifulpixel.textdriven.com/articles/2006/04/27/superimage-plugin-making-resizeable-uploaded-images-easy](http://beautifulpixel.textdriven.com/articles/2006/04/27/superimage-plugin-making-resizeable-uploaded-images-easy)

svn: [http://beautifulpixel.textdriven.com/svn/plugins/super\_image/](http://beautifulpixel.textdriven.com/svn/plugins/super_image/)

That’s all well and good and useable, but there are 2 things I would  
like to improve. I am stuck on them, however.

First, the included migration is an ugly hack

def self.up  
create\_table :super\_images, :force =\> true do |t|  
t.column :data, :binary, :size =\> 10000000, :null =\> false  
t.column :created\_at, :datetime  
end  
execute “ALTER TABLE `super_images` MODIFY `data` MEDIUMBLOB”  
end

I just could not get the ruby definition for :data to create a  
MEDIUMBLOB on mysql. The size parameter seems to have been completely  
disregarded. The clomun sets up as BLOB with a size limit of 16K, which  
is far to small for most image uploading needs.

Second, the “show\_image” action is currently included in via “include  
SuperImagePlugin::Show”

This works, but it means the action name that performs the image  
retrieval is locked in to be “show\_image”. I would like to have it  
works this way:

class MyImagesController \< …  
image\_action :foo  
end

Then you can access the images via “/my\_images/foo/12”. Sadly though,  
metaprogramming like this still makes my head spin.

If anyone has ideas about alleviating these 2 points, it sure would be  
appreciated.

---

<div class="post-metadata">

**Author:** ![squeegy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/dec6dc/32.png) [@squeegy](https://www.ruby-forum.com/u/squeegy)\
**Post date:** [April 27, 2006, 7:35pm UTC](https://www.ruby-forum.com/t/ann-superimage-plugin/94256/2 "2006-04-27T19:35:09Z")

</div>

Hey Ezra, you tha man !

---

<div class="post-metadata">

**Author:** ![squeegy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/dec6dc/32.png) [@squeegy](https://www.ruby-forum.com/u/squeegy)\
**Post date:** [April 27, 2006, 7:38pm UTC](https://www.ruby-forum.com/t/ann-superimage-plugin/94256/3 "2006-04-27T19:38:26Z")

</div>

Peter wrote:

> Hey Ezra, you tha man !

How rude of me.

Thank you Alex W…

---

<div class="post-metadata">

**Author:** ![squeegy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/dec6dc/32.png) [@squeegy](https://www.ruby-forum.com/u/squeegy)\
**Post date:** [April 28, 2006, 4:24am UTC](https://www.ruby-forum.com/t/ann-superimage-plugin/94256/4 "2006-04-28T04:24:26Z")

</div>

Now published at [http://agilewebdevelopment.com/plugins/show/102](http://agilewebdevelopment.com/plugins/show/102). 🙂

–  
Benjamin C.  
[http://www.tesly.com/](http://www.tesly.com/) – Collaborative test case management  
[http://www.agilewebdevelopment.com/](http://www.agilewebdevelopment.com/) – Resources for the Rails community

---

<div class="post-metadata">

**Author:** ![squeegy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/dec6dc/32.png) [@squeegy](https://www.ruby-forum.com/u/squeegy)\
**Post date:** [April 28, 2006, 2:21pm UTC](https://www.ruby-forum.com/t/ann-superimage-plugin/94256/5 "2006-04-28T14:21:10Z")

</div>

this is nice, _but_ isn’t it quite dangerous in regards on generating  
a huge load, while automatically GET /show\_image?size=$autoincrement  
-robert

2006/4/28, Benjamin C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

---

<div class="post-metadata">

**Author:** ![squeegy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/dec6dc/32.png) [@squeegy](https://www.ruby-forum.com/u/squeegy)\
**Post date:** [April 27, 2006, 5:24pm UTC](https://www.ruby-forum.com/t/ann-superimage-plugin/94256/6 "2006-04-27T17:24:20Z")

</div>

Hi!

On Apr 26, 2006, at 6:33 PM, Alex W. wrote:

> svn: [textdriven.com&nbsp;-&nbsp;textdriven Resources and Information.](http://beautifulpixel.textdriven.com/svn/plugins/super_image/)

Nice idea.

> ```
> t.column :created_at, :datetime
> 
> ```

Not sure there is a prettier way to handle this part.

> end
> 
> Then you can access the images via “/my\_images/foo/12”. Sadly though,  
> metaprogramming like this still makes my head spin.
> 
> If anyone has ideas about alleviating these 2 points, it sure would be  
> appreciated.

I have taken the liberty of implementing image\_action :foo for you.  
And I also made the data= method on ActiveRecord::Base in a different  
way. I commented the way this stuff works so you can learn how to do it.

This code is untested so it may need some slight adjustment, but  
hopefully not 😉

----init.rb—  
require ‘super\_image’  
require ‘RMagick’

ActionController::Base.send :include, SuperImagePlugin::Show  
ActiveRecord::Base.send :include, SuperImagePlugin::SetImage

–super\_image.rb----

module SuperImagePlugin  
module Show  
# when we get included into the ApplicationController in init.rb  
# we extend that class with the methods in our ClassMethods module  
def self.included(base)  
base.extend(ClassMethods)  
end

```
 module ClassMethods
   # The image_action method will become a class method of
   # ApplicationController. This allows it to be used as a
   # macro like before_filter & friends. It takes one symbol
   # or string and uses define_method to create an instance
   # method that is in the same scope as controller actions.
   # You can use it in any controller class to define and

```

image\_method:  
# image\_action :show  
def image\_action(meth)  
define\_method(meth) {  
@headers[‘Cache-Control’] = ‘public’  
img = SuperImage.find(params[:id])  
if img  
if params[:size]  
data = Magick::Image.from\_blob(img.data)[0]  
data.change\_geometry!(“#{params[:size]}x#{(params  
[:size]).to\_i}”) do  
|cols, rows, img|  
img.resize!(cols, rows)  
end  
else  
data = Magick::Image.from\_blob(img.data)[0]  
end

```
         send_data data.to_blob,
                   :type => 'image/jpeg',
                   :disposition => 'inline'
       else
         render :text => 'Image Disabled!'
       end
       GC.start
     }
   end

 end # ClassMethods

```

end # Show

module SetImage  
# when we get included into ActiveRecord::Base, a data= method  
# is defined.  
def self.included(base)  
base.include(ModelMethods)  
end

```
 module ModelMethods
   def data=(file)
     if file.size > 0
       img = Magick::Image.from_blob(file.read)[0]
       img.format = 'JPG'
       self[:data] = img.to_blob
     end
     GC.start
   end
 end # InstanceMethods

```

end # SetImage  
end # SuperImagePlugin

I removed your comments just to make it clear what I did. Just add  
them back if this works for you. I haven’t looked at the rest of it  
yet, but this should get you started.

Cheers-  
-Ezra

---

<div class="post-metadata">

**Author:** ![squeegy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/dec6dc/32.png) [@squeegy](https://www.ruby-forum.com/u/squeegy)\
**Post date:** [April 28, 2006, 2:57pm UTC](https://www.ruby-forum.com/t/ann-superimage-plugin/94256/7 "2006-04-28T14:57:55Z")

</div>

On 4/27/06, Alex W. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Greetings all,
> 
> This is the first release of the SuperImage plugin. The idea is you  
> upload images to the database, and then pull them out at any size you  
> want. Combine this with caching and it will stay light and fast.

Why use the database as image store and not the file system? I rather  
agree with these arguments:  
[http://mysqldump.azundris.com/archives/36-Serving-Images-From-A-Database.html](http://mysqldump.azundris.com/archives/36-Serving-Images-From-A-Database.html)  
linked from the lighttpd blog  
([http://blog.lighttpd.net/articles/2006/03/10/serving-images-from-a-database](http://blog.lighttpd.net/articles/2006/03/10/serving-images-from-a-database))

Raph

---

<div class="post-metadata">

**Author:** ![squeegy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/dec6dc/32.png) [@squeegy](https://www.ruby-forum.com/u/squeegy)\
**Post date:** [May 3, 2006, 7:08pm UTC](https://www.ruby-forum.com/t/ann-superimage-plugin/94256/8 "2006-05-03T19:08:36Z")

</div>

-----BEGIN PGP SIGNED MESSAGE-----  
Hash: SHA1

Hi Alex,

> I just could not get the ruby definition for :data to create a  
> MEDIUMBLOB on mysql. The size parameter seems to have been completely  
> disregarded. The clomun sets up as BLOB with a size limit of 16K,  
> which  
> is far to small for most image uploading needs.

I’ve been thinking about this for a while, and I don’t understand  
why Rails can’t be made to handle this sort of thing automatically.

Right now with Migrations Rails takes what you say literally, if  
you specify :binary its mapped onto a BLOB. If you sat :integer  
its mapped onto INT.

What I think _should_ happen is to use :binary as a reference  
to a _class_ of columns (BLOB, MEDIUMBLOB, etc), and the :limit  
parameter should be used to select the best column from the  
class – ideally the smallest column that will still fit whatever  
size of data :limit specifies.

The biggest place this would help is with integers. If I say I  
want :integer, with a :limit of 2, it should use TINYINT rather  
than INT. Its a waste to use something like an INT when a  
TINYINT will do.

This would require the connection adapters to know how to  
“negotiate” the correct column size, but I think it is doable.  
I’d be willing to write the MySQL logic if others were willing  
to do patches for other databases… drop me a line if you’re  
interested in collaborating on this.

We’d get two benefits with this approach: Space would be conserved  
and when it is needed (as in this case) and larger columns would be  
selected automatically based on the size needs specified.

* * *

Thanks,

Dan

* * *

Dan K.  
Autopilot Marketing Inc.

Email: removed\_email\_address@domain.invalid  
Phone: 1 (604) 820-0212  
Web: [http://autopilotmarketing.com/](http://autopilotmarketing.com/)  
vCard: [http://autopilotmarketing.com/~dan.kubb/vcard](http://autopilotmarketing.com/~dan.kubb/vcard)

* * *

-----BEGIN PGP SIGNATURE-----  
Version: GnuPG v1.4.2.2 (Darwin)

iD8DBQFEU4PE4DfZD7OEWk0RAv+SAJ9tUAHS5OFrk0JYdIztEZ1JVuDJrQCgrnXh  
VrIXKTIBhBGVFAxfol4vJkI=  
=t2xo  
-----END PGP SIGNATURE-----
