Another IO.popen question ...

Discussion in 'Ruby' started by Adam Groves, Nov 16, 2006.

  1. Adam Groves

    Adam Groves Guest

    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:

    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")

    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/.
    Adam Groves, Nov 16, 2006
    #1
    1. Advertising

  2. 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:
    >
    > 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")
    >
    > 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:-")

    --
    vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407
    Joel VanderWerf, Nov 16, 2006
    #2
    1. Advertising

  3. 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:
    >
    > 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")
    >
    > 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

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

    http://www.simplesystems.org/RMagick/doc/image1.html#read
    Timothy Hunter, Nov 16, 2006
    #3
  4. Adam Groves

    Adam Groves Guest

    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/.
    Adam Groves, Nov 16, 2006
    #4
  5. Adam Groves

    Adam Groves Guest

    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
    >
    > The Magick::Image.read method accepts an open Ruby file object as an
    > argument.
    >
    > 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/.
    Adam Groves, Nov 16, 2006
    #5
  6. 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?
    >

    Consider that the convert command only accepts string options. It knows
    nothing about Ruby.
    Timothy Hunter, Nov 16, 2006
    #6
  7. Adam Groves

    Guest

    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:-")


    yeah - that's it alright

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

    dump it to stdout...

    -a
    --
    my religion is very simple. my religion is kindness. -- the dalai lama
    , Nov 16, 2006
    #7
  8. Adam Groves

    Guest

    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?


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

    stdin = file_object.read

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

    stdout =
    IO.popen( cmd, 'r+' ) do |pipe|
    pipe.write stdin
    pipe.close_write
    pipe.read
    end

    abort "cmd <#{ cmd }> failed" unless $? == 0

    open the_png, 'w' do |f|
    f.write stdout
    end

    regards.

    -a
    --
    my religion is very simple. my religion is kindness. -- the dalai lama
    , Nov 16, 2006
    #8
  9. 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))
    f.write data
    end
    end

    --
    vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407
    Joel VanderWerf, Nov 16, 2006
    #9
  10. 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|

    ^^^^^
    ...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.

    > while (data=file.read(N))
    > f.write data
    > end
    > end
    >



    --
    vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407
    Joel VanderWerf, Nov 16, 2006
    #10
  11. Adam Groves

    Guest

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

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

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

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

    -a
    --
    my religion is very simple. my religion is kindness. -- the dalai lama
    , Nov 16, 2006
    #11
  12. 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))
    >> 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
    >
    > file = File.open("mypdf.pdf")
    >
    > png =
    > IO.popen("convert -resize 700x700 pdf:-[0] png:-") do |f|
    > while (data=file.read(N))
    > f.write data
    > end
    > f.close_write
    > f.read
    > end
    >
    > not sure if that was obvious or not... sorry if it was.


    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.

    --
    vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407
    Joel VanderWerf, Nov 17, 2006
    #12
  13. Adam Groves

    Guest

    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.


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

    require 'tempfile'

    t = Tempfile.new Process.pid.to_s
    t.close

    cmd = "convert ... > #{ t.path }"

    # etc

    cheers.

    -a
    --
    my religion is very simple. my religion is kindness. -- the dalai lama
    , Nov 17, 2006
    #13
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jim Benson

    simple popen question

    Jim Benson, Apr 2, 2004, in forum: Python
    Replies:
    1
    Views:
    292
    Cameron Laird
    Apr 3, 2004
  2. Jim Benson

    Re: simple popen question

    Jim Benson, Apr 3, 2004, in forum: Python
    Replies:
    1
    Views:
    294
    Cameron Laird
    Apr 3, 2004
  3. Robin Siebler
    Replies:
    6
    Views:
    513
  4. Matthew K Jensen

    yet another os.popen quesion

    Matthew K Jensen, Sep 14, 2004, in forum: Python
    Replies:
    1
    Views:
    311
    David Bolen
    Sep 16, 2004
  5. File.popen/IO.popen

    , May 20, 2006, in forum: Ruby
    Replies:
    1
    Views:
    214
    Robert Klemme
    May 20, 2006
Loading...

Share This Page