Encoding/decoding a image as Base64 (fails under Ruby1.9 but worksunder Ruby1.8)

  • Thread starter Iñaki Baz Castillo
  • Start date
I

Iñaki Baz Castillo

Hi, the folowing code encodes and decodes a image file as Base64:

=2D Encode "icon.png" in Base64 as "base64.txt":
=2D-------------------------------------
File.open("base64.txt","w") do |file|
file.write [open("icon.png").read].pack("m")
end
=2D-------------------------------------

=2D Decode "base64.txt" as a PNG "new_icon.png" file:
=2D-------------------------------------
File.open('new_icon.png', 'wb') do |file|
file << (IO.readlines('base64.txt').to_s.unpack('m')).first
end
=2D-------------------------------------


It works perfectly under Ruby1.8 (after encoding and decoding "icon.png" is=
=20
exatcly the same as "new_icon.png", the same binay file).

However running under Ruby1.9 the result is different since "new_icon.png" =
is=20
a corrupted image file. When I try to open it with a image viewer I get thi=
s=20
error (under Linux):

libpng warning: gAMA: CRC error
libpng error: PNG unsigned integer out of range.


Which is the difference when using Ruby1.9? how to solve it?
Thanks a lot.


=2D-=20
I=C3=B1aki Baz Castillo <[email protected]>
 
I

Iñaki Baz Castillo

El Jueves, 3 de Diciembre de 2009, I=C3=B1aki Baz Castillo escribi=C3=B3:
Hi, the folowing code encodes and decodes a image file as Base64:
=20
- Encode "icon.png" in Base64 as "base64.txt":
--------------------------------------
File.open("base64.txt","w") do |file|
file.write [open("icon.png").read].pack("m")
end
--------------------------------------
=20
- Decode "base64.txt" as a PNG "new_icon.png" file:
--------------------------------------
File.open('new_icon.png', 'wb') do |file|
file << (IO.readlines('base64.txt').to_s.unpack('m')).first
end
--------------------------------------
=20
=20
It works perfectly under Ruby1.8 (after encoding and decoding "icon.png" = is
exatcly the same as "new_icon.png", the same binay file).
=20
However running under Ruby1.9 the result is different since "new_icon.png"
is a corrupted image file. When I try to open it with a image viewer I g= et
this error (under Linux):
=20
libpng warning: gAMA: CRC error
libpng error: PNG unsigned integer out of range.
=20
=20
Which is the difference when using Ruby1.9? how to solve it?
Thanks a lot.

The difference is in the second step, the decoding process, since "base64.t=
xt"=20
file is the same using Ruby1.8 or 1.9.




=2D-=20
I=C3=B1aki Baz Castillo <[email protected]>
 
I

Iñaki Baz Castillo

El Jueves, 3 de Diciembre de 2009, I=C3=B1aki Baz Castillo escribi=C3=B3:
The difference is in the second step, the decoding process, since
"base64.txt" file is the same using Ruby1.8 or 1.9.

Ok, the issue is fixed by uing "IO.read" rather than "IO.readlines":

=2D Decode "base64.txt" as a PNG "new_icon.png" file:
=2D-------------------------------------
File.open('new_icon.png', 'wb') do |file|
file << (IO.read('base64.txt').to_s.unpack('m')).first
end
=2D-------------------------------------=20


=2D-=20
I=C3=B1aki Baz Castillo <[email protected]>
 
L

Lars Christensen

=A0File.open("base64.txt","w") do |file|
=A0 =A0file.write [open("icon.png").read].pack("m")
=A0end

=A0File.open('new_icon.png', 'wb') do |file|
=A0 =A0file << (IO.readlines('base64.txt').to_s.unpack('m')).first
=A0end

Which is the difference when using Ruby1.9? how to solve it?
Thanks a lot.

In Ruby 1.9, Array#to_s is an alias for Array#inspect.

In Ruby 1.8, Array#to_s worked like Array#join with no arguments.

Try this:
IO.read "base64.txt"
 
R

Robert Klemme

2009/12/3 I=F1aki Baz Castillo said:
Hi, the folowing code encodes and decodes a image file as Base64:

- Encode "icon.png" in Base64 as "base64.txt":
--------------------------------------
=A0File.open("base64.txt","w") do |file|
=A0 =A0file.write [open("icon.png").read].pack("m")
=A0end
--------------------------------------

- Decode "base64.txt" as a PNG "new_icon.png" file:
--------------------------------------
=A0File.open('new_icon.png', 'wb') do |file|
=A0 =A0file << (IO.readlines('base64.txt').to_s.unpack('m')).first
=A0end
--------------------------------------


It works perfectly under Ruby1.8 (after encoding and decoding "icon.png" = is
exatcly the same as "new_icon.png", the same binay file).

However running under Ruby1.9 the result is different since "new_icon.png= " is
a corrupted image file. When I try to open it with a image viewer I get t= his
error (under Linux):

=A0libpng warning: gAMA: CRC error
=A0libpng error: PNG unsigned integer out of range.


Which is the difference when using Ruby1.9? how to solve it?
Thanks a lot.

One thing strikes odd: you are not reading the file in binary mode.
It may be that 1.9 punishes you for that. You probably rather want

File.open("base64.txt","w") do |file|
file.write [File.open("icon.png", "rb") {|io| io.read}].pack("m")
end

You can simplify decoding as

File.open('new_icon.png', 'wb') do |file|
file.write(File.read('base64.txt').unpack('m').first)
end

Kind regards

robert

--=20
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
 
I

Iñaki Baz Castillo

El Jueves, 3 de Diciembre de 2009, Robert Klemme escribi=F3:
2009/12/3 I=F1aki Baz Castillo said:
Hi, the folowing code encodes and decodes a image file as Base64:

- Encode "icon.png" in Base64 as "base64.txt":
--------------------------------------
File.open("base64.txt","w") do |file|
file.write [open("icon.png").read].pack("m")
end
--------------------------------------

- Decode "base64.txt" as a PNG "new_icon.png" file:
--------------------------------------
File.open('new_icon.png', 'wb') do |file|
file << (IO.readlines('base64.txt').to_s.unpack('m')).first
end
--------------------------------------


It works perfectly under Ruby1.8 (after encoding and decoding "icon.png"
is exatcly the same as "new_icon.png", the same binay file).

However running under Ruby1.9 the result is different since
"new_icon.png" is a corrupted image file. When I try to open it with a
image viewer I get this error (under Linux):

libpng warning: gAMA: CRC error
libpng error: PNG unsigned integer out of range.


Which is the difference when using Ruby1.9? how to solve it?
Thanks a lot.
=20
One thing strikes odd: you are not reading the file in binary mode.
It may be that 1.9 punishes you for that. You probably rather want
=20
File.open("base64.txt","w") do |file|
file.write [File.open("icon.png", "rb") {|io| io.read}].pack("m")
end
=20
You can simplify decoding as
=20
File.open('new_icon.png', 'wb') do |file|
file.write(File.read('base64.txt').unpack('m').first)
end


That makes lot of sense!
Thanks.

=2D-=20
I=F1aki Baz Castillo <[email protected]>
 
I

Iñaki Baz Castillo

El Jueves, 3 de Diciembre de 2009, Lars Christensen escribi=F3:
File.open("base64.txt","w") do |file|
file.write [open("icon.png").read].pack("m")
end

File.open('new_icon.png', 'wb') do |file|
file << (IO.readlines('base64.txt').to_s.unpack('m')).first
end

Which is the difference when using Ruby1.9? how to solve it?
Thanks a lot.
=20
In Ruby 1.9, Array#to_s is an alias for Array#inspect.
=20
In Ruby 1.8, Array#to_s worked like Array#join with no arguments.
=20
Try this:
IO.read "base64.txt"

Yes. It seems that usng "to_s" could be a bit problematic under Ruby1.9 due=
to=20
the new behaviour...
Thanks.


=2D-=20
I=F1aki Baz Castillo <[email protected]>
 
R

Rick DeNatale

El Jueves, 3 de Diciembre de 2009, Lars Christensen escribi=F3:
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top