# Another IO.popen question

**URL:** <https://rubytalk.org/t/another-io-popen-question/33005>\
**Category:** ruby-talk\
**Created:** [16 November 2006 22:03 UTC](https://rubytalk.org/t/another-io-popen-question/33005 "2006-11-16T22:03:38Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![Adam\_Groves](https://avatars.discourse-cdn.com/v4/letter/a/e0b2c6/32.png) [@Adam\_Groves](https://rubytalk.org/u/Adam_Groves)\
**Post date:** [16 November 2006 22:03 UTC](https://rubytalk.org/t/another-io-popen-question/33005/1 "2006-11-16T22:03:38Z")

</div>

Hi,

I'm wanting to create thumbnails of pdfs in png format and send them off  
to be saved. I've come up with this so far:

&nbsp;&nbsp;&nbsp;&nbsp;IO.popen("curl #{some\_uri} | convert -resize 700x700 pdf:-[0]  
png:-") {|f| do\_something\_with\_this\_file}

Which works a treat. (In case you didn't know, convert is a command line  
tool for ImageMagick).

What I'd really like to do though is pass on a File object to convert:

file = File.open("mypdf.pdf")

&nbsp;&nbsp;&nbsp;&nbsp;IO.popen("#{file} | convert -resize 700x700 pdf:-[0] png:-") {|f|  
do\_something\_with\_this\_file}

This obviously doesn't work but I hope illustrates what I'm wanting to  
acheive - namely to pass 'file' to convert it to a png which is read  
back into ruby and uploaded to my file repository on S3.

By the way, this IS for a rails application, but it seems basically like  
a pure ruby question to me.

Regards

Adam

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

---

<div class="post-metadata">

**Author:** ![Joel\_VanderWerf1](https://avatars.discourse-cdn.com/v4/letter/j/94ad74/32.png) [@Joel\_VanderWerf1](https://rubytalk.org/u/Joel_VanderWerf1)\
**Post date:** [16 November 2006 22:09 UTC](https://rubytalk.org/t/another-io-popen-question/33005/2 "2006-11-16T22:09:37Z")

</div>

Adam Groves wrote:

> Hi,
> 
> I'm wanting to create thumbnails of pdfs in png format and send them off to be saved. I've come up with this so far:
> 
> &nbsp;&nbsp;&nbsp;&nbsp;IO.popen("curl #{some\_uri} | convert -resize 700x700 pdf:-[0] png:-") {|f| do\_something\_with\_this\_file}
> 
> Which works a treat. (In case you didn't know, convert is a command line tool for ImageMagick).
> 
> What I'd really like to do though is pass on a File object to convert:
> 
> file = File.open("mypdf.pdf")
> 
> &nbsp;&nbsp;&nbsp;&nbsp;IO.popen("#{file} | convert -resize 700x700 pdf:-[0] png:-") {|f| do\_something\_with\_this\_file}

would this work?

file = "mypdf.pdf"  
IO.popen("cat #{file} | ...")

or simply

IO.popen("convert -resize 700x700 #{file} png:-")

> **···**
>
> --  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

---

<div class="post-metadata">

**Author:** ![Tim\_Hunter4](https://avatars.discourse-cdn.com/v4/letter/t/ea5d25/32.png) [@Tim\_Hunter4](https://rubytalk.org/u/Tim_Hunter4)\
**Post date:** [16 November 2006 22:16 UTC](https://rubytalk.org/t/another-io-popen-question/33005/3 "2006-11-16T22:16:19Z")

</div>

Adam Groves wrote:

> Hi,
> 
> I'm wanting to create thumbnails of pdfs in png format and send them off to be saved. I've come up with this so far:
> 
> &nbsp;&nbsp;&nbsp;&nbsp;IO.popen("curl #{some\_uri} | convert -resize 700x700 pdf:-[0] png:-") {|f| do\_something\_with\_this\_file}
> 
> Which works a treat. (In case you didn't know, convert is a command line tool for ImageMagick).
> 
> What I'd really like to do though is pass on a File object to convert:
> 
> file = File.open("mypdf.pdf")
> 
> &nbsp;&nbsp;&nbsp;&nbsp;IO.popen("#{file} | convert -resize 700x700 pdf:-[0] png:-") {|f| do\_something\_with\_this\_file}
> 
> This obviously doesn't work but I hope illustrates what I'm wanting to acheive - namely to pass 'file' to convert it to a png which is read back into ruby and uploaded to my file repository on S3.
> 
> By the way, this IS for a rails application, but it seems basically like a pure ruby question to me.
> 
> Regards
> 
> Adam

Consider RMagick: [http://rmagick.rubyforge.org](http://rmagick.rubyforge.org)

The Magick::Image.read method accepts an open Ruby file object as an argument.

[http://www.simplesystems.org/RMagick/doc/image1.html#read](http://www.simplesystems.org/RMagick/doc/image1.html#read)

---

<div class="post-metadata">

**Author:** ![Adam\_Groves](https://avatars.discourse-cdn.com/v4/letter/a/e0b2c6/32.png) [@Adam\_Groves](https://rubytalk.org/u/Adam_Groves)\
**Post date:** [16 November 2006 22:22 UTC](https://rubytalk.org/t/another-io-popen-question/33005/4 "2006-11-16T22:22:33Z")

</div>

Hi Joel,

thanks for the speedy reply! The problem is, I need to pass on a file  
object (which has been uploaded from a web page form) to 'convert' and  
not just a path. I should have made this clearer in my original post.

Any ideas?

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

---

<div class="post-metadata">

**Author:** ![Adam\_Groves](https://avatars.discourse-cdn.com/v4/letter/a/e0b2c6/32.png) [@Adam\_Groves](https://rubytalk.org/u/Adam_Groves)\
**Post date:** [16 November 2006 22:30 UTC](https://rubytalk.org/t/another-io-popen-question/33005/5 "2006-11-16T22:30:08Z")

</div>

Timothy Hunter wrote:

> Adam Groves wrote:
> 
> > By the way, this IS for a rails application, but it seems basically like  
> > a pure ruby question to me.
> > 
> > Regards
> > 
> > Adam
> 
> Consider RMagick: [http://rmagick.rubyforge.org](http://rmagick.rubyforge.org)
> 
> The Magick::Image.read method accepts an open Ruby file object as an  
> argument.
> 
> [RMagick 1.15.0: class Image (class and instance methods, part 1)](http://www.simplesystems.org/RMagick/doc/image1.html#read)

hmm.. Maybe you're right Tim. I was just wanting to drop to the command  
line to do this and thought there must be a way of accomplishing this  
without resorting to RMagick. Not that I have anything against it.

Is there really no other way of passing on a Ruby file object  
imagemagick other than through RMagick?

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![Ara.T.Howard6](https://avatars.discourse-cdn.com/v4/letter/a/958977/32.png) [@Ara.T.Howard6](https://rubytalk.org/u/Ara.T.Howard6)\
**Post date:** [16 November 2006 22:39 UTC](https://rubytalk.org/t/another-io-popen-question/33005/6 "2006-11-16T22:39:41Z")

</div>

yeah - that's it alright

&nbsp;&nbsp;png = IO.popen("convert -resize 700x700 #{file} png:-"){|pipe| pipe.read}

dump it to stdout...

-a

> **···**
>
> On Fri, 17 Nov 2006, Joel VanderWerf wrote:
> 
> > would this work?
> > 
> > file = "mypdf.pdf"  
> > IO.popen("cat #{file} | ...")
> > 
> > or simply
> > 
> > IO.popen("convert -resize 700x700 #{file} png:-")
> 
> --  
> my religion is very simple. my religion is kindness. -- the dalai lama

---

<div class="post-metadata">

**Author:** ![Tim\_Hunter4](https://avatars.discourse-cdn.com/v4/letter/t/ea5d25/32.png) [@Tim\_Hunter4](https://rubytalk.org/u/Tim_Hunter4)\
**Post date:** [16 November 2006 22:35 UTC](https://rubytalk.org/t/another-io-popen-question/33005/7 "2006-11-16T22:35:49Z")

</div>

Adam Groves wrote:

> hmm.. Maybe you're right Tim. I was just wanting to drop to the command line to do this and thought there must be a way of accomplishing this without resorting to RMagick. Not that I have anything against it.
> 
> Is there really no other way of passing on a Ruby file object imagemagick other than through RMagick?  
> &nbsp;&nbsp;

Consider that the convert command only accepts string options. It knows nothing about Ruby.

---

<div class="post-metadata">

**Author:** ![Ara.T.Howard6](https://avatars.discourse-cdn.com/v4/letter/a/958977/32.png) [@Ara.T.Howard6](https://rubytalk.org/u/Ara.T.Howard6)\
**Post date:** [16 November 2006 22:48 UTC](https://rubytalk.org/t/another-io-popen-question/33005/8 "2006-11-16T22:48:22Z")

</div>

you can pass convert files on stdin. you need somthing like

&nbsp;&nbsp;&nbsp;stdin = file\_object.read

&nbsp;&nbsp;&nbsp;cmd = " convert - png:- " # input on stdin, output to stdout

&nbsp;&nbsp;&nbsp;stdout =  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IO.popen( cmd, 'r+' ) do |pipe|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pipe.write stdin  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pipe.close\_write  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pipe.read  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;abort "cmd \<#{ cmd }\> failed" unless $? == 0

&nbsp;&nbsp;&nbsp;open the\_png, 'w' do |f|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f.write stdout  
&nbsp;&nbsp;&nbsp;end

regards.

-a

> **···**
>
> On Fri, 17 Nov 2006, Adam Groves wrote:
> 
> > Hi Joel,
> > 
> > thanks for the speedy reply! The problem is, I need to pass on a file  
> > object (which has been uploaded from a web page form) to 'convert' and  
> > not just a path. I should have made this clearer in my original post.
> > 
> > Any ideas?
> 
> --  
> my religion is very simple. my religion is kindness. -- the dalai lama

---

<div class="post-metadata">

**Author:** ![Joel\_VanderWerf1](https://avatars.discourse-cdn.com/v4/letter/j/94ad74/32.png) [@Joel\_VanderWerf1](https://rubytalk.org/u/Joel_VanderWerf1)\
**Post date:** [16 November 2006 23:03 UTC](https://rubytalk.org/t/another-io-popen-question/33005/9 "2006-11-16T23:03:04Z")

</div>

Adam Groves wrote:

> Hi Joel,
> 
> thanks for the speedy reply! The problem is, I need to pass on a file object (which has been uploaded from a web page form) to 'convert' and not just a path. I should have made this clearer in my original post.
> 
> Any ideas?

Untested, but maybe something like this?

file = File.open("mypdf.pdf")  
IO.popen("convert -resize 700x700 pdf:-[0] png:-") do |f|  
&nbsp;&nbsp;&nbsp;while (data=file.read(N))  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f.write data  
&nbsp;&nbsp;&nbsp;end  
end

> **···**
>
> --  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

---

<div class="post-metadata">

**Author:** ![Joel\_VanderWerf1](https://avatars.discourse-cdn.com/v4/letter/j/94ad74/32.png) [@Joel\_VanderWerf1](https://rubytalk.org/u/Joel_VanderWerf1)\
**Post date:** [16 November 2006 23:09 UTC](https://rubytalk.org/t/another-io-popen-question/33005/10 "2006-11-16T23:09:15Z")

</div>

Joel VanderWerf wrote:

> Adam Groves wrote:
> 
> > Hi Joel,
> > 
> > thanks for the speedy reply! The problem is, I need to pass on a file object (which has been uploaded from a web page form) to 'convert' and not just a path. I should have made this clearer in my original post.
> > 
> > Any ideas?
> 
> Untested, but maybe something like this?
> 
> file = File.open("mypdf.pdf")  
> IO.popen("convert -resize 700x700 pdf:-[0] png:-") do |f|

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;^^^^^  
...this bit is the problem. So Ara's r+ pipe would be necessary, unless you can put a filename here instead.

Also, I forgot the "w" mode.

> **···**
>
> > &nbsp;&nbsp;while (data=file.read(N))  
> > &nbsp;&nbsp;&nbsp;&nbsp;f.write data  
> > &nbsp;&nbsp;end  
> > end
> 
> --  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

---

<div class="post-metadata">

**Author:** ![Ara.T.Howard6](https://avatars.discourse-cdn.com/v4/letter/a/958977/32.png) [@Ara.T.Howard6](https://rubytalk.org/u/Ara.T.Howard6)\
**Post date:** [16 November 2006 23:44 UTC](https://rubytalk.org/t/another-io-popen-question/33005/11 "2006-11-16T23:44:08Z")

</div>

careful, if you don't read the child will block when the pipe becomes full i  
think. you might need to add

&nbsp;&nbsp;&nbsp;file = File.open("mypdf.pdf")

&nbsp;&nbsp;&nbsp;png =  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IO.popen("convert -resize 700x700 pdf:-[0] png:-") do |f|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while (data=file.read(N))  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f.write data  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f.close\_write  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f.read  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end

not sure if that was obvious or not... sorry if it was.

-a

> **···**
>
> On Fri, 17 Nov 2006, Joel VanderWerf wrote:
> 
> > Adam Groves wrote:
> > 
> > > Hi Joel,
> > > 
> > > thanks for the speedy reply! The problem is, I need to pass on a file object (which has been uploaded from a web page form) to 'convert' and not just a path. I should have made this clearer in my original post.
> > > 
> > > Any ideas?
> > 
> > Untested, but maybe something like this?
> > 
> > file = File.open("mypdf.pdf")  
> > IO.popen("convert -resize 700x700 pdf:-[0] png:-") do |f|  
> > while (data=file.read(N))  
> > &nbsp;&nbsp;&nbsp;f.write data  
> > end  
> > end
> 
> --  
> my religion is very simple. my religion is kindness. -- the dalai lama

---

<div class="post-metadata">

**Author:** ![Joel\_VanderWerf1](https://avatars.discourse-cdn.com/v4/letter/j/94ad74/32.png) [@Joel\_VanderWerf1](https://rubytalk.org/u/Joel_VanderWerf1)\
**Post date:** [17 November 2006 00:52 UTC](https://rubytalk.org/t/another-io-popen-question/33005/12 "2006-11-17T00:52:32Z")

</div>

I was confused in several respects: I was thinking of a one-way pipe (but I forgot the "w"), in which case blocking wouldn't be a problem. But the one-way pipe would only be useful if the OP could put a filename in place of the "png:-".

The one-way pipe has the advantage that you can read(N) instead of read(), and keep memory bounded. Maybe it's not an issues for the OP, though.

> **···**
>
> ara.t.howard@noaa.gov wrote:
> 
> > On Fri, 17 Nov 2006, Joel VanderWerf wrote:
> > 
> > > Adam Groves wrote:
> > > 
> > > > Hi Joel,
> > > > 
> > > > thanks for the speedy reply! The problem is, I need to pass on a file object (which has been uploaded from a web page form) to 'convert' and not just a path. I should have made this clearer in my original post.
> > > > 
> > > > Any ideas?
> > > 
> > > Untested, but maybe something like this?
> > > 
> > > file = File.open("mypdf.pdf")  
> > > IO.popen("convert -resize 700x700 pdf:-[0] png:-") do |f|  
> > > while (data=file.read(N))  
> > > &nbsp;&nbsp;&nbsp;f.write data  
> > > end  
> > > end
> > 
> > careful, if you don't read the child will block when the pipe becomes full i  
> > think. you might need to add
> > 
> > &nbsp;&nbsp;file = File.open("mypdf.pdf")
> > 
> > &nbsp;&nbsp;png =  
> > &nbsp;&nbsp;&nbsp;&nbsp;IO.popen("convert -resize 700x700 pdf:-[0] png:-") do |f|  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while (data=file.read(N))  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f.write data  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f.close\_write  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f.read  
> > &nbsp;&nbsp;&nbsp;&nbsp;end
> > 
> > not sure if that was obvious or not... sorry if it was.
> 
> --  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

---

<div class="post-metadata">

**Author:** ![Ara.T.Howard6](https://avatars.discourse-cdn.com/v4/letter/a/958977/32.png) [@Ara.T.Howard6](https://rubytalk.org/u/Ara.T.Howard6)\
**Post date:** [17 November 2006 03:14 UTC](https://rubytalk.org/t/another-io-popen-question/33005/13 "2006-11-17T03:14:42Z")

</div>

huh. never really thought of it that way - good reason to do

&nbsp;&nbsp;&nbsp;require 'tempfile'

&nbsp;&nbsp;&nbsp;t = Tempfile.new Process.pid.to\_s  
&nbsp;&nbsp;&nbsp;t.close

&nbsp;&nbsp;&nbsp;cmd = "convert ... \> #{ t.path }"

&nbsp;&nbsp;&nbsp;# etc

cheers.

-a

> **···**
>
> On Fri, 17 Nov 2006, Joel VanderWerf wrote:
> 
> > I was confused in several respects: I was thinking of a one-way pipe (but I  
> > forgot the "w"), in which case blocking wouldn't be a problem. But the  
> > one-way pipe would only be useful if the OP could put a filename in place of  
> > the "png:-".
> 
> > The one-way pipe has the advantage that you can read(N) instead of read(), and keep memory bounded. Maybe it's not an issues for the OP, though.
> 
> --  
> my religion is very simple. my religion is kindness. -- the dalai lama
