[QUIZ] Text Image (#50)

Discussion in 'Ruby' started by Ruby Quiz, Oct 7, 2005.

  1. Ruby Quiz

    Ruby Quiz Guest

    The three rules of Ruby Quiz:

    1. Please do not post any solutions or spoiler discussion for this quiz until
    48 hours have passed from the time on this message.

    2. Support Ruby Quiz by submitting ideas as often as you can:

    http://www.rubyquiz.com/

    3. Enjoy!

    -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

    This week's Ruby Quiz is to create a tool that will allow you to preview an
    image file at the command-line in pure text.

    Your program will need to read in an image, in whatever format you want to
    support, and respond with a text representation of the image that fits in the
    terminal.

    For example, given the image:

    http://rubyquiz.com/images/Ducky.png

    Your program might respond with something like:

    ........--**####**::::::::::::........
    ......--##oooooo\\**::::::::..........
    ......**oo==oooo\\\\::::..............
    ....--\\oooooooo\\$$**::..............
    ....**&&$$oooo\\$$$$%%................
    ....**\\oooo\\<<<<$$##................
    ....!!<<<<<<<<<<\\\\##..........::::::
    ....::%%<<<<<<<<\\$$^^....::**++**....
    ....^^%%<<<<<<<<$$$$##**""==++++==****
    ....**oo<<<<<<$$<<<<\\oo==++++++==""""
    ..!!==oo<<<<<<<<$$$$oo====++++==oo####
    ^^====oo\\<<$$\\oooooo==++======oo****
    **++++====oooo====++++======oooo\\^^^^
    ++====++++========++======oooooo**....
    ""====++++==========oooooooooo##--....
    ""==================oooooooooo^^......
    !!oo==oo======oooooooooo\\##^^::......
    ..""oooooooooooooooo\\oo""^^..........
    ..::**====oooooooooo==**::............
    ....::^^**""""""""!!..--::............
    ....::^^**""""""""!!..--::............

    Go for as much accuracy as you can possibly squeeze out of it.
     
    Ruby Quiz, Oct 7, 2005
    #1
    1. Advertising

  2. Ruby Quiz

    Jim Freeze Guest

    Ahh, a half-toning algorithm.

    On 10/7/05, Ruby Quiz <> wrote:
    > The three rules of Ruby Quiz:
    >
    > 1. Please do not post any solutions or spoiler discussion for this quiz =

    until
    > 48 hours have passed from the time on this message.
    >
    > 2. Support Ruby Quiz by submitting ideas as often as you can:
    >
    > http://www.rubyquiz.com/
    >
    > 3. Enjoy!
    >
    > -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=

    =3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D=
    -=3D-=3D-=3D
    >
    > This week's Ruby Quiz is to create a tool that will allow you to preview =

    an
    > image file at the command-line in pure text.
    >
    > Your program will need to read in an image, in whatever format you want t=

    o
    > support, and respond with a text representation of the image that fits in=

    the
    > terminal.
    >
    > For example, given the image:
    >
    > http://rubyquiz.com/images/Ducky.png
    >
    > Your program might respond with something like:
    >
    > ........--**####**::::::::::::........
    > ......--##oooooo\\**::::::::..........
    > ......**oo=3D=3Doooo\\\\::::..............
    > ....--\\oooooooo\\$$**::..............
    > ....**&&$$oooo\\$$$$%%................
    > ....**\\oooo\\<<<<$$##................
    > ....!!<<<<<<<<<<\\\\##..........::::::
    > ....::%%<<<<<<<<\\$$^^....::**++**....
    > ....^^%%<<<<<<<<$$$$##**""=3D=3D++++=3D=3D****
    > ....**oo<<<<<<$$<<<<\\oo=3D=3D++++++=3D=3D""""
    > ..!!=3D=3Doo<<<<<<<<$$$$oo=3D=3D=3D=3D++++=3D=3Doo####
    > ^^=3D=3D=3D=3Doo\\<<$$\\oooooo=3D=3D++=3D=3D=3D=3D=3D=3Doo****
    > **++++=3D=3D=3D=3Doooo=3D=3D=3D=3D++++=3D=3D=3D=3D=3D=3Doooo\\^^^=

    ^
    > ++=3D=3D=3D=3D++++=3D=3D=3D=3D=3D=3D=3D=3D++=3D=3D=3D=3D=3D=3Dooo=

    ooo**....
    > ""=3D=3D=3D=3D++++=3D=3D=3D=3D=3D=3D=3D=3D=3D=3Doooooooooo##--...=
     
    Jim Freeze, Oct 7, 2005
    #2
    1. Advertising

  3. Ruby Quiz

    Hal Fulton Guest

    Ruby Quiz wrote:
    > This week's Ruby Quiz is to create a tool that will allow you to preview an
    > image file at the command-line in pure text.
    >
    > Your program will need to read in an image, in whatever format you want to
    > support, and respond with a text representation of the image that fits in the
    > terminal.


    I never participate in these, but this one is tempting.

    What about ANSI color? ;)


    Hal
     
    Hal Fulton, Oct 8, 2005
    #3
  4. On Oct 7, 2005, at 6:24 PM, Hal Fulton wrote:

    > I never participate in these, but this one is tempting.


    Ah, why not? :) We do try to have a little fun.

    Perhaps that means you need to send in a problem *you* can't resist! ;)

    > What about ANSI color? ;)


    Very clever. I didn't think of that...

    James Edward Gray II
     
    James Edward Gray II, Oct 8, 2005
    #4
  5. Ruby Quiz

    James Britt Guest

    Hal Fulton wrote:
    > Ruby Quiz wrote:
    >
    >> This week's Ruby Quiz is to create a tool that will allow you to
    >> preview an
    >> image file at the command-line in pure text.
    >>
    >> Your program will need to read in an image, in whatever format you
    >> want to
    >> support, and respond with a text representation of the image that fits
    >> in the
    >> terminal.

    >
    >
    > I never participate in these, but this one is tempting.


    Might even make a few bucks, no?

    http://www.artima.com/forums/flat.jsp?forum=123&thread=130735

    James

    --

    http://www.ruby-doc.org - The Ruby Documentation Site
    http://www.rubyxml.com - News, Articles, and Listings for Ruby & XML
    http://www.rubystuff.com - The Ruby Store for Ruby Stuff
    http://www.jamesbritt.com - Playing with Better Toys
     
    James Britt, Oct 9, 2005
    #5
  6. Ruby Quiz

    Kero Guest

    Kero, Oct 9, 2005
    #6
  7. On Oct 9, 2005, at 7:26 AM, Kero wrote:

    >>> I never participate in these, but this one is tempting.
    >>>

    >>
    >> Might even make a few bucks, no?
    >>
    >> http://www.artima.com/forums/flat.jsp?forum=123&thread=130735
    >>

    >
    > do all contributors get a free sample?


    Contributors of quizzes and code used in the book will be contacted
    very soon now...

    James Edward Gray II
     
    James Edward Gray II, Oct 9, 2005
    #7
  8. [SOLUTION] Text Image (#50)

    Hi,

    here is my attempt of solving this weeks quiz:

    This solution uses the RMagick lib to read the image and
    to find edges because trying to find apropiate letters for
    halftoning is hard on all the different terminals.

    I had another version without the generator/enumerator
    stuff and it was a lot faster. But speed isn't an issue this
    week and it's so much smoother than fiddling with indexes.

    cheers

    Simon

    ----------------------------------------------------------------
    require 'RMagick'
    require 'generator'
    require 'enumerator'

    puts "Usage: #{$0} <img> [size]" or exit if !ARGV[0]

    img, size = Magick::ImageList.new(ARGV[0]), (ARGV[1]||40).to_f
    factor = [size*1.5/img.rows, size/img.columns].min

    img.resize!(img.columns*factor, 2*(img.rows*factor*0.75).round)
    img = img.edge.despeckle.despeckle.normalize.threshold(50)

    pixels = img.get_pixels(0, 0, img.columns, img.rows).map{|c| c.red.zero?}

    pixels.to_enum:)each_slice, img.columns).each_slice(2) do |l|
    puts SyncEnumerator.new(*l).map{|p1, p2|
    [' ', "'", ".", ":"] [(p1 ? 0 : 1) + (p2 ? 0 : 2)]}.join('')
    end
    ----------------------------------------------------------------

    sample output:

    .:'''''''.
    .: :.
    .: :.
    : :
    :' ':
    .: :
    : .':. ::
    :'.' : .. ':
    : :..' :' ': :
    :. ' : .: :
    ': '::'':.. ':' . :
    :: ''.. :' .:'':.
    :: . ': .: ..' . '.
    ': ''''' .: .:::::''' :.
    :: .:': :
    .: : .:' :
    .' '' '' :
    :' :
    : :
    ' :
    : ' :'
    : .:
    ' : .:
    ' :
    : .:
    : .:
    : .'
    '. :'
    :. .'
    '. .:'
    ':. .:'
    ':. .:'
    ''..........''
     
    Simon Kröger, Oct 9, 2005
    #8
  9. Re: [SOLUTION] Text Image (#50)

    On Oct 9, 2005, at 4:56 PM, Simon Kr=F6ger wrote:

    > Hi,
    >
    > here is my attempt of solving this weeks quiz:


    [snip]

    > sample output:
    >
    > .:'''''''.
    > .: :.
    > .: :.
    > : :
    > :' ':
    > .: :
    > : .':. ::
    > :'.' : .. ':
    > : :..' :' ': :
    > :. ' : .: :
    > ': '::'':.. ':' . :
    > :: ''.. :' .:'':.
    > :: . ': .: ..' . '.
    > ': ''''' .: .:::::''' :.
    > :: .:': :
    > .: : .:' :
    > .' '' '' :
    > :' :
    > : :
    > .' :
    > : ' :'
    > : .:
    > ' : .:
    > ' :
    > : .:
    > : .:
    > : .'
    > '. :'
    > :. .'
    > '. .:'
    > ':. .:'
    > ':. .:'
    > ''..........''


    Wow, I really like that! Too cool.

    Here's the code used in the quiz:

    #!/usr/local/bin/ruby -w

    unless ARGV.size =3D=3D 1 and File.exists? ARGV.first
    puts "Usage: #{File.basename($0)} IMAGE_FILE"
    exit
    end

    require "RMagick"

    text =3D %w{. : - ^ ! * + " =3D % o # \\ $ < &}

    image =3D Magick::Image.read(ARGV.shift).first

    image =3D image.quantize(text.size)
    image.scale!([39.0 / image.columns, 20.0 / image.rows].min)
    image =3D image.quantize(text.size)

    pixels =3D Array.new
    0.upto(image.rows) do |y|
    0.upto(image.columns) do |x|
    pixel =3D image.pixel_color(x, y).intensity
    pixels << pixel unless pixels.include? pixel
    end
    end
    pixels.sort! { |a, b| b <=3D> a }

    0.upto(image.rows) do |y|
    0.upto(image.columns) do |x|
    2.times { print text[pixels.index(image.pixel_color(x, =20
    y).intensity)] }
    end
    puts
    end

    __END__

    James Edward Gray II
     
    James Edward Gray II, Oct 9, 2005
    #9
  10. [SOLUTION] Text Image (#50)

    My solution relies on having RMagick do all the work. Here's the output
    for the test image:

    +-------------------------------------------------------------------------+
    | .::+====+:: |
    | .:==o======ooo*oo+. |
    | +oo=====++++===oo***+ |
    | :eek:o==++++===++==ooooo*^*. |
    | :eek:o====++++====oooooooo*^* |
    | .oo=====++++========ooo**^^o |
    | .ooo=====++++++======ooo**^^%: |
    | :*oo*o==============oooo****^^^. |
    | :eek:oo$WW^===========oooo****^^^^^= |
    | ooo*WWW%=========oooo^^*^**^^^^^^ |
    | oooo=o::eek:=====oooo*%WWW$^^*^^^^*^: |
    | =ooo=:+====ooooo**o^WWW$***^****^: |
    | .*o*o*ooooo==ooo*^*+====o*^*****^. |
    | :eek:%$$$$$WW$$$%%^^^^**********^^= |
    | .oWWWWWWWWWWWWWW$%%^**o****^^= :::::: |
    | %$$$$$$$W$$W$WWWW$^****^^o. ...::::::::==: |
    | =WWWW$$$W$$$$WW$$%^^****+. .........:::::::::::::::::=o+ |
    | :$WWWWWWWWWWWW%^****^%%%%%^^**oo====++:::::::::::::::+=o+ |
    | :+oo*$$WWWWWWW$%^*^^^^^%$$$%%%^**o===+:::::::::::::::::++==o: |
    | .:====o*^%$$$$$%^^%%^^^^%%%%%%%^^**o===+::::::::::::::::::===oo |
    | .:+++++==o*^%%%%%%$%%%%^^^^%%%^^^**oo===++:::::::::::::::::+==ooo |
    | .:+::::+++=oo*^%%%$%%%%%^^^^^*****ooo===+++::::::::::::::::++===oo= |
    | :++::::::+++=oo*^%%%%%%^^****ooooo=====++:::::::::::::++:::++====o*. |
    | :+::::::::::+===o**^^^^**ooo=====+=+++++::::::::::::+::==++++===ooo+ |
    | :+::::::::::::+++==oooooo====+::::+:::::+::::+::++::+::+==++=====oo= |
    | .+::::::::::::::::++=+=====+::::::+:::::+::::+:::+:::+++========ooo= |
    | :+::::::::::::::::::+:++++::::::++::::::::::+:::++:++==========ooo+ |
    |.++++:::::::::::::::::::::::::::+:::::+::::+:::++++===========oooo: |
    |.++++::::::::::::::::::::::::::::::++:+::+=+++==============oooo=. |
    | +++++++::::::::::::::::::::::++::++::+==+=+===========o===ooo=: |
    | :==++++::::+:::::::::+:+:::::::::+++===++=============ooooo=: |
    | .===++++++++++::+++::+++:+++++::+===++====o==========o=o==:. |
    | :=======+++++++++++++++++:++===============oo====oo=o==:. |
    | :====================++++++==+=========o=====ooo====: |
    | .==================================ooooooo=oo===+: |
    | :+=============================oooo=o==oo==::. |
    | ::==========================o====oo===::. |
    | ::++==============+===========+::. |
    | ..:::++++==++=+++++++++::.. |
    | ....:.::::::... |
    +-------------------------------------------------------------------------+


    require 'RMagick'

    CHARS = ['W', 'M', '$', '@', '#', '%', '^', 'x', '*', 'o', '=', '+',
    ':', '~', '.', ' ']
    FONT_ROWS = 8
    FONT_COLS = 4

    img = Magick::Image.read(ARGV[0] || "Flower_Hat.jpg").first

    # Resize too-large images. The resulting image is going to be
    # about twice the size of the input, so if the original image is too
    # large we need to make it smaller so the ASCII version won't be too
    # big. The `change_geometry' method computes new dimensions for an
    # image based on the geometry argument. The '320x320>' argument says
    # "If the image is too big to fit in a 320x320 square, compute the
    # dimensions of an image that will fit, but retain the original aspect
    # ratio. If the image is already smaller than 320x320, keep the same
    # dimensions."
    img.change_geometry('320x320>') do |cols, rows|
    img.resize!(cols, rows) if cols != img.columns || rows != img.rows
    end

    # Compute the image size in ASCII "pixels" and resize the image to have
    # those dimensions. The resulting image does not have the same aspect
    # ratio as the original, but since our "pixels" are twice as tall as
    # they are wide we'll get our proportions back (roughly) when we render.
    pr = img.rows / FONT_ROWS
    pc = img.columns / FONT_COLS
    img.resize!(pc, pr)

    img = img.quantize(16, Magick::GRAYColorspace)
    img = img.normalize

    # Draw the image surrounded by a border. The `view' method is slow but
    # it makes it easy to address individual pixels. In grayscale images,
    # all three RGB channels have the same value so the red channel is as
    # good as any for choosing which character to represent the intensity of
    # this particular pixel.
    border = '+' + ('-' * pc) + '+'
    puts border
    img.view(0, 0, pc, pr) do |view|
    pr.times do |i|
    putc '|'
    pc.times { |j| putc CHARS[view[j].red/16] }
    puts '|'
    end
    end
    puts border
     
    Timothy Hunter, Oct 9, 2005
    #10
  11. Re: [SOLUTION] Text Image (#50)

    I'm surprised how easy this Quiz was because of ImageMagick and
    RMagick (based on the other submissions, I didn't try it.) Kudos to
    the developers of those projects (though I imagine only the RMagick
    developer will be reading this.)

    Of course you quiz developers deserve kudos for your clever solutions
    using RMagick.

    I wonder how long the code would be for a solution that did NOT use
    RMagick or any other image library? Maybe future submissions will
    answer this question for me...

    Ryan
     
    Ryan Leavengood, Oct 10, 2005
    #11
  12. Re: [SOLUTION] Text Image (#50)

    On Oct 9, 2005, at 6:57 PM, Ryan Leavengood wrote:

    > I'm surprised how easy this Quiz was because of ImageMagick and
    > RMagick (based on the other submissions, I didn't try it.)


    Indeed. I only found RMagick two weeks ago, but it impressed me
    enough to make the quiz. It's a bit of a bear to get installed
    (because of ImageMagick, not the Ruby bindings), but worth the effort.

    I second the thanks to the developer for giving us such great tools
    to work with!

    James Edward Gray II
     
    James Edward Gray II, Oct 10, 2005
    #12
  13. Ruby Quiz

    Dave Burt Guest

    Hi,

    I have a solution written five years ago by Brian Fundakowski Feldman. Is
    that allowed?

    This code, which is not mine, uses the GD library.

    This is not my code:

    http://www.dave.burt.id.au/ruby/img2ascii.rb

    Cheers,
    Dave
     
    Dave Burt, Oct 10, 2005
    #13
  14. Re: [SOLUTION] Text Image (#50)

    James Edward Gray II wrote:

    > Wow, I really like that! Too cool.


    Thanks, yes it turned out better than expected.
     
    Simon Kröger, Oct 10, 2005
    #14
  15. Ruby Quiz

    Rob Rypka Guest

    Re: [SOLUTION] Text Image (#50)

    I tried this one out. I'm not sure if I was successful or not...

    My first instinct was to rank characters for intensity levels
    programmaticly. I then came to the realization that not all
    characters have the same distribution of intensity, so I thought I
    would try splitting them up, and matching them with sets of pixel
    intensities (instead of just one).

    ruby create_tables.rb num [extended]
    does the first part - pass it a number (number of pixels sqare that
    will be replaced by one character). uses extended ASCII if the second
    argument is applied.

    ruby i2a.rb src_img outfile num [normalized]
    does the second part. takes num x num clumps of pixels from src_image
    and finds the closest character from the appropriate table (by
    Euclidean distance), puts it out to outfile. If normalized is
    supplied, the image is normalized for maximum contrast in the source
    image.

    You can find the code here:
    http://www.rabble-rooster.org/rubyquiz/50/

    Results are in the results folder.

    The underscore also rendered to pure white, so I had to remove it
    manully from the YAML tables. Those tables are available also.

    I know this code needs some refactoring/reengineering, and I didn't
    take the time to look into how *Magick did things like scaling. Feel
    free to chide me on any points that are inefficient/bad/wrong/stupid.

    --
    Rob
     
    Rob Rypka, Oct 11, 2005
    #15
  16. [QUIZ] [Solution] Text Image (#50)

    Hello Everyone,

    I went into this quiz using the following approach. I split the image
    into pieces and find for each piece of the image the letter most
    similar to this piece. I did it all with image magick. There is room
    for improvement in the distance function, but it works ok. I'm sure it
    is the slowest solution so far, but it works.

    You can find the sourcecode and examples at

    http://ruby.brian-schroeder.de/quiz/asciiview/

    best regards,

    Brian

    _,,uuuuu,,_
    _u:EEEEEEEEEE{{[p,_
    _:EEEEEEEEEEEEEEE{{[Ou
    :EEEEEEEEEEEEEEEE{{{{[O3_
    UEEEEEEEEEEEEEEEE{{E{{{[O3_
    UEEEEEEEEEEEEEEEEEEEEE{{[S3B
    ;{EEEEEEEEEEEEEEEEEEEE{{[SO3B$
    ;{{{EEEEEEEEEEEEEEEEEE{{[[O3333u
    {[[SQQ{EEEEEEEEEEEEEEE{{[[OO3333B
    E{{[###${EEEEEEEEEEEE{{[SSSS333333q
    E{{{###PEEEEEEEEEEE{SSQQ3333O333333
    {{{{ " LEEEEEEEE{{[S$####$333333333
    {{{{{:cEEEEEE{{{[[SZZ####Z3O3333OS3
    F{{{{{{EEjjEEE{[SO35EEEFEEOO3OOOO33
    F{]###########QQ3993SSSOSOO[[OS33~
    "f################$Q3O[[[[OSS33~ L-F"FL
    I#IIII#############Q[SSOO33P" L--" FE.
    P######$##IIII####T3SS333P' LL---F -EEU
    ##############T3OOO3OOQ$$$9SSUUUUEEEEEEF- -EEE=
    E
    .;{[I##########TS3333S3$IIII$$B3O[{EEEEEFF -EEE=
    E{
    LEEEE{O#$I#####@BBB33333$$$II]$$B3O[{EEEEEF- -EEE=
    E{L
    LEEEEEEE[O3$$$$$$$$$$$$9BB$$$$$$@B3O[{EEEEEE-- --EEEE=
    E{{
    LEEEEEEEEEE[3B$$]I]]$$$$$BBBBBBB333O[[{EEEEEEF-- ---EEEEEE=
    E{{
    LEFFFFFFEEEEE{[3B$$]]$$$$B333OOO[[[{{{EEEEEEEEFF .EE--EEEEEEE=
    E{{"
    -FFF-- --FEEEEE{[3B@@@@@B33O[[{{EEEEEEEEEEEFFF L E .LEEEEEEEEEEE=
    E{{
    -FFFF- -FFEEEEE{[O22OOO[[{EEEEEEEEEFFFEEF --- LE -F .EEEEEEEEEEEE=
    {{
    LEF--- --FFEEEEEEEEEEEEEEEFFF-FEF EE LE LE" -E EEEEEEEEEEEE{{=
    "
    EEE--- --FFFEEEEEEEEEEEFF LEF LE LE -EE LEEEEEEEEEEEEEE{{"
    EEEEEF- ---FFEEEFEEFF -EE" -EF LEFL-EEEEEEEEEEEEEEEEEE{E"
    EEEE-F--- --F-FFFFFF -EF LLE LLEFEEEEEEEEEEEEEEEEEEEE{{E
    EEEEEE--------- --- --- LE LLEFFLEEEEEEEEEEEEEEEEEEEEEEE{{EF
    EEEEEEEEE--F------ - -L--LLLLLEEELLEEE-LEEEEEEEEEEEEEEEEEEEEEEEE{EE"
    FEEEEEEEEEEEE-----L-LLEEEEFF" .""FF"LEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
    .EEEEEEEEEEEEEEEEEEEEEEEEEELLLEELLLEEEEEEEEEEEEEEEEEEEEEEEEEEEEF
    .FEEEEEEEEEEEEEEEEEEEEEEEEEEEFEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEF
    FEEEEEEEEEEEEEEEEEEEEEEEELLEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEF
    FEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
    "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE{{E{EEEEEEEEEF"
    "FEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE{EEEEEEF"
    FFEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEFF"
    "FFEEEEEEEEEEEEEEEEEEEEEEEEEEEFFF"
    "FFFFFFEEEEEEEEEEEEEEFF"
    FF"""""


    _yv*/^^^^^^^/#Yy_
    y#^ '^#y
    y# ^#,
    _#^ Ty
    _# #y
    # ,- #_
    #^ #
    _#' ^g
    y# _Y/Xy #
    # # Tg ^$
    # #,^ y^ y**v_ #
    $ ###^ # _. # #
    # ^ _$_'_,# #
    #y _yyyyyyv*gyy_ ^###IIP #
    #y#$ ^ ^P*yy_ '' yf ,yvy_
    ^#$ ^P*y_ y# _y#^^ ,^#y
    '# ^P/*+ ,_ _T* _#^ __yv*P^ ' ^#=
    _
    Ty~/**^^M ^P**#^v/^y# _g#yyyyyyyyvY*#P^^ =
    #y
    y# '^rr**~'y#^^ _vP^' =
    #_
    y#P^ #P_ y#^ T =
    Y #
    _#^ ^#C/xvv-_yYP' =
    ^$
    y#^ ^^Pr/~^' =
    #
    _#^ =
    #
    g^ =
    yT
    #^ # =
    #
    # F ^ =
    $^
    #' _P @ # g # =
    y^
    y^ ,^ / g ^ y=
    ^
    # v y^
    # _/ y _ #^
    # Y^ _. , ,#'
    # r^ _^ g^
    # r/ Yr *^ _x ' y#
    ^y _ *' _- y#^
    # __ r _#^
    # '^ ' ' y#^
    ^# - y#^
    #y _ _YP'
    ^#, r _y#^
    ^#y r _v#^
    ^#y_ -x `~ -r _y*P^
    ^/*y_ ~/***r__yY/^^
    ^^P**YvyyyyyyyyyvvY*/P^^
    --
    http://ruby.brian-schroeder.de/

    Stringed instrument chords: http://chordlist.brian-schroeder.de/
     
    Brian Schröder, Oct 11, 2005
    #16
  17. Ruby Quiz

    Rob Rypka Guest

    Re: [QUIZ] [Solution] Text Image (#50)

    On 10/10/05, Brian Schr=F6der <> wrote:
    > I went into this quiz using the following approach. I split the image
    > into pieces and find for each piece of the image the letter most
    > similar to this piece. I did it all with image magick. There is room
    > for improvement in the distance function, but it works ok. I'm sure it
    > is the slowest solution so far, but it works.
    >
    > You can find the sourcecode and examples at
    >
    > http://ruby.brian-schroeder.de/quiz/asciiview/


    I do believe I got pWn3d!!1!... Nice work, Brian.

    I think my solution is probably slower, though :). I'm too used to
    doing this kind of thing in C/++.

    --
    Rob
     
    Rob Rypka, Oct 11, 2005
    #17
  18. Brian Schröder, Oct 11, 2005
    #18
  19. unfinished [SOLUTION] Text Image (#50)

    Hi,

    i'm completely new to ncurses, so could someone with more exprerience
    (or another OS) try this and tell me whats happening?
    On windows all the colors are very pale (are there consts for lighter
    colors?)
    -----------------------------------------------------------------------
    require 'RMagick'
    require "ncurses"

    Ncurses.initscr
    puts "Usage: #{$0} <img> [size]" or exit if !ARGV[0]
    puts "Sorry, no colors!" or exit unless Ncurses.has_colors?

    img, size = Magick::ImageList.new(ARGV[0]), (ARGV[1]||40).to_f
    factor = [size*2/img.rows, size/img.columns].min
    img.resize!(img.columns*factor, (img.rows*factor*0.5).round)

    COLORS =
    [[Ncurses::COLOR_BLACK, [0, 0, 0]], [Ncurses::COLOR_RED, [1, 0, 0]],
    [Ncurses::COLOR_GREEN, [0, 1, 0]], [Ncurses::COLOR_BLUE, [0, 0, 1]],
    [Ncurses::COLOR_YELLOW, [1, 1, 0]], [Ncurses::COLOR_MAGENTA, [1, 0, 1]],
    [Ncurses::COLOR_CYAN, [0, 1, 1]], [Ncurses::COLOR_WHITE, [1, 1, 1]]]

    GRADIENT = [[0, ' '], [50, ':'], [100, '|'], [150, 'I'], [200, '#']]
    COLORMAP = {}

    COLORS.size.times do |bg|
    COLORS.size.times do |fg|
    next if fg == bg
    i = (bg*COLORS.size) + fg
    Ncurses.init_pair(i, COLORS[fg][0], COLORS[bg][0])
    GRADIENT.each do |gr, c|
    r = COLORS[fg][1][0] * gr + COLORS[bg][1][0] * (255-gr)
    g = COLORS[fg][1][1] * gr + COLORS[bg][1][1] * (255-gr)
    b = COLORS[fg][1][2] * gr + COLORS[bg][1][2] * (255-gr)
    COLORMAP[[r, g, b]] = [i, c]
    end
    end
    end

    #(16*16*4).times do |i|
    # Ncurses.stdscr.attrset(Ncurses.COLOR_PAIR(i))
    # Ncurses.stdscr.mvaddstr(i/16, (i%16)*4, 'TEST')
    #end
    #Ncurses.refresh

    pixels = img.get_pixels(0, 0, img.columns, img.rows)
    img.rows.times do |y|
    img.columns.times do |x|
    p = pixels[y*img.columns + x]
    r, g, b, best, dist = p.red, p.green, p.blue, -1, 255
    COLORMAP.each do |k, v|
    d = Math.sqrt((r-k[0])**2 + (g-k[1])**2 + (b-k[2])**2)
    (best, dist = v, d) if d < dist
    end
    Ncurses.stdscr.attrset(Ncurses.COLOR_PAIR(best[0]))
    Ncurses.stdscr.mvaddstr(y, x, best[1])
    end
    end

    Ncurses.refresh
    -----------------------------------------------------------------------

    maybe someone can help..

    cheers

    Simon
     
    Simon Kröger, Oct 11, 2005
    #19
  20. Re: [QUIZ] [Solution] Text Image (#50)

    ------=_Part_4998_28661170.1129080179787
    Content-Type: text/plain; charset=ISO-8859-1
    Content-Transfer-Encoding: quoted-printable
    Content-Disposition: inline

    Hi,

    Best quiz yet. Er, well, quiz which held my attention longest anyway. :)

    My solution is um, less... elegant, than some of the others, but in a lot o=
    f
    ways, like a parent who mistakenly thinks their ugly child is cute I kinda
    like it. I don't really share my code a lot (maybe for obvious reasons) but
    I'm just so pleased with how easily ruby lets me hack things to high heaven
    and this one in particular makes me smile. Take special note that it only
    works on 24 bit .bmp files and put your hard hat on if you think you're
    going to feed anything but that into it. ;) Okay, enough blather, without
    further ado, the first code I've shared with you guys:

    #It only supports 24bit bmp files, and it even chokes on most of them ;)
    #It creates one character per pixel (which has obvious implications)
    #But it's 40 lines of pure ruby no lib use binary file up-hackery...
    #And quite frankly, thats what I do.

    MyPixel =3D Struct.new( 'MyPixel', :r, :g, :b )

    the_gradient =3D %w|D Y 8 S 6 5 J j t c + i ! ; : .|
    ###############PUT YOUR FILENAME
    HERE#########################################
    the_file =3D File.new('ducky.bmp', 'rb')
    the_file.read(2) #BM
    the_file.read(4).unpack('V')[0] #filesize
    the_file.read(4) #unused
    the_file.read(4).unpack('V')[0] #offset from beginning to bitmap data
    the_file.read(4).unpack('V')[0] #size of bitmap header
    image_x =3D the_file.read(4).unpack('V')[0] #width x in pixels
    image_y =3D the_file.read(4).unpack('V')[0] #height y in pixels
    the_file.read(2).unpack('v')[0] #planes?
    the_file.read(2).unpack('v')[0] #bits per pixel
    the_file.read(24) #unused

    the_bitmap =3D []
    puts "CRRRRUNCHHHH --- please wait, reading file..."
    image_y.times do |row|
    the_bitmap[row] =3D []
    image_x.times do |col|
    the_bitmap[row][col] =3D MyPixel.new( 0, 0, 0 )
    the_bitmap[row][col].b =3D the_file.read(1).unpack('c')[0]
    the_bitmap[row][col].g =3D the_file.read(1).unpack('c')[0]
    the_bitmap[row][col].r =3D the_file.read(1).unpack('c')[0]
    end
    end

    puts "output coming:"
    the_output =3D File.new('output.asciiart', 'w')
    (image_y-1).downto(0) do |row|
    image_x.times do |col|
    the_avg =3D
    (the_bitmap[row][col].b+the_bitmap[row][col].g+the_bitmap[row][col].r)/3
    the_output.write(the_gradient[the_avg>>4])
    end
    the_output.write("\n")
    end

    ------=_Part_4998_28661170.1129080179787--
     
    Harold Hausman, Oct 12, 2005
    #20
    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. Ruby Quiz

    [QUIZ] Animal Quiz (#15)

    Ruby Quiz, Jan 14, 2005, in forum: Ruby
    Replies:
    11
    Views:
    402
    James Edward Gray II
    Jan 18, 2005
  2. David Tran
    Replies:
    9
    Views:
    216
    David Tran
    Jan 21, 2005
  3. Ruby Quiz

    [QUIZ] 1-800-THE-QUIZ (#20)

    Ruby Quiz, Feb 18, 2005, in forum: Ruby
    Replies:
    15
    Views:
    341
    gabriele renzi
    Feb 24, 2005
  4. Marcelo Alvim

    [QUIZ] Newbie doubts about the quiz

    Marcelo Alvim, Aug 15, 2006, in forum: Ruby
    Replies:
    15
    Views:
    265
    Marcelo Alvim
    Aug 16, 2006
  5. Daniel Moore
    Replies:
    10
    Views:
    325
    James Gray
    Jan 31, 2009
Loading...

Share This Page