# Re: Creating images from pixel data (RMagick?)

**URL:** <https://www.ruby-forum.com/t/re-creating-images-from-pixel-data-rmagick/57003>\
**Category:** Ruby\
**Created:** [April 6, 2006, 1:57pm UTC](https://www.ruby-forum.com/t/re-creating-images-from-pixel-data-rmagick/57003 "2006-04-06T13:57:02Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Tim\_Blair](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/f9ae1b/32.png) [@Tim\_Blair](https://www.ruby-forum.com/u/Tim_Blair)\
**Post date:** [April 6, 2006, 1:57pm UTC](https://www.ruby-forum.com/t/re-creating-images-from-pixel-data-rmagick/57003/1 "2006-04-06T13:57:02Z")

</div>

Paul,

> If that won’t work, Imlib2-Ruby may be fast enough to do  
> what you want

Thanks for that. Unfortunately we’re looking for a cross-platform  
solution so using imlib2 appears to be out of the running.

However, I have managed to speed up the generation a lot by using the  
Rmagick Image#store\_pixels method instead of Draw#fill - we now have the  
512x384 image generating in \<5 seconds which is OK for what we’re doing  
(at least at the moment!). We’re now limited by the speed at which the  
flash player can glean the pixel data, rather than how fast the image  
can be generated. Code below.

Thanks again for the help. Maybe your imlib2 will come in useful when  
someone turns around and says “surely we can do that sooooo much  
quicker?!” 🙂

Cheers,

Tim.

require ‘RMagick’  
class RippedImage  
def initialize (job\_id, width, height)  
@job\_id = job\_id.to\_s;  
@width = width.to\_i;  
@height = height.to\_i;  
@canvas = Magick::Image.new(@width, @height)  
@pixels = []  
end  
def draw (c)  
# the colour is a 6 digit hex char which needs to  
# be converted to numeric values for RGB  
col = []  
c.scan(/…/).each { |bit| col \<\< bit.hex }  
@pixels \<\< Magick::Pixel.new(col[0], col[1], col[2], 0)  
end  
def finalize (type=“gif”)  
@canvas.store\_pixels(0, 0, @width, @height, @pixels)  
@canvas.write(“#{@job\_id}.#{type}”)  
end  
end

x = 512  
y = 384  
colours = [“ff0000”, “00ff00”, “0000ff”]  
img = RippedImage.new(1, x, y)  
(x\*y).times do  
img.draw(colours[rand(colours.length)])  
end  
img.finalize

## –

## TB: [http://tim.bla.ir/](http://tim.bla.ir/) Tech: [http://tech.badpen.com/](http://tech.badpen.com/)

```
 RAWNET LTD - independent digital media agency
 "We are big, we are funny and we are clever!"
            http://www.rawnet.com/

```

* * *

This message may contain information which is legally  
privileged and/or confidential. If you are not the  
intended recipient, you are hereby notified that any  
unauthorised disclosure, copying, distribution or use  
of this information is strictly prohibited. Such  
notification notwithstanding, any comments, opinions,  
information or conclusions expressed in this message  
are those of the originator, not of rawnet limited,  
unless otherwise explicitly and independently indicated  
by an authorised representative of rawnet limited.

---

<div class="post-metadata">

**Author:** ![Tim\_Blair](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/f9ae1b/32.png) [@Tim\_Blair](https://www.ruby-forum.com/u/Tim_Blair)\
**Post date:** [April 6, 2006, 4:13pm UTC](https://www.ruby-forum.com/t/re-creating-images-from-pixel-data-rmagick/57003/2 "2006-04-06T16:13:28Z")

</div>

Hi Tim,

See the thread starting at  
[http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/153656](http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/153656) -  
it talks about ImageMagick/RMagick specifically, and using mmap and  
NArray to quickly create large images from pixel data.

- Dimitri

---

<div class="post-metadata">

**Author:** ![Tim\_Blair](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/f9ae1b/32.png) [@Tim\_Blair](https://www.ruby-forum.com/u/Tim_Blair)\
**Post date:** [April 6, 2006, 7:46pm UTC](https://www.ruby-forum.com/t/re-creating-images-from-pixel-data-rmagick/57003/3 "2006-04-06T19:46:33Z")

</div>

On Thu, 6 Apr 2006, Tim Blair wrote:

> # the colour is a 6 digit hex char which needs to
> 
> x = 512  
> y = 384  
> colours = [“ff0000”, “00ff00”, “0000ff”]  
> img = RippedImage.new(1, x, y)  
> (x\*y).times do  
> img.draw(colours[rand(colours.length)])  
> end  
> img.finalize

are you really limited to using string pixel values? if not i would say  
you  
should be able to generate these images in **way** under 1s. even if  
you are,  
using import\_pixels will be tons faster:

your original:

```
 jib:~/eg/ruby > time ruby a.rb

 real 0m4.028s
 user 0m3.620s
 sys 0m0.070s

```

using import\_pixels:

jib:~/eg/ruby \> time ruby a.rb

real 0m0.829s  
user 0m0.810s  
sys 0m0.000s

jib:~/eg/ruby \> cat a.rb  
require ‘rubygems’  
require ‘RMagick’  
class RippedImage  
LITTLE\_ENDIAN = [42].pack(‘i’).unpack(‘c’).first.nonzero? ? true :  
false  
BIG\_ENDIAN = ! LITTLE\_ENDIAN  
MAP = BIG\_ENDIAN ? ‘ARGB’ : ‘BGRA’  
def initialize width, height  
@width = Integer width  
@height = Integer height  
@pixels = []  
end  
def \<\< c  
@pixels \<\< c.hex  
self  
end  
def draw path  
img = Magick::Image.new @width, @height  
img.import\_pixels 0, 0, @width, @height, MAP, @pixels.pack(‘i\*’),  
Magick::CharPixel  
img.opacity = 255 # because the pack leaves it 0 - totally  
transparent  
img.write path  
end  
end

x = 512  
y = 384  
colours = [“ff0000”, “00ff00”, “0000ff”]  
img = RippedImage.new x, y  
(x\*y).times{ img \<\< (colours[rand(colours.length)]) }  
img.draw “#{ 1 }.png”

so that’s a four times speed-up right there. i suspect 1s is a  
reasonable  
number too.

kind regards.

-a
