Converting binary image file to bmp file using RMagick2.0


#1

We are trying to convert “image1.txt” file which is a binary file to
“image1.bmp” file usng Ruby + RMagick2.0 but not able to get the
required output that is “Menu.bmp”. Following the attached code that we
have reached so far. Look forward to get some help as how to get an
output like “Menu.bmp” from the file called “image1.txt”

I was not able to attached all the three files ( image1.txt, image1.bmp
and Menu.bmp) So just attached the source file “image1.txt” and if you
run the following case, it wll generate “image1.bmp”

require ‘rmagick’
file_name = “C:/image1.text” # the binary file
image_file_name = “C:/image1.bmp” # the expected file to be generated
image = Magick::Image.new(704, 480)
file = File.read(file_name)

#=begin
one = []
two = []
three = []

p = 0
l = 1
file.each_byte { |x|
case l
when 1
one << x
#getOne=((moveOne << 1 + 16) >> 11 + 16)
#one << getOne
l += 1
when 2
two << x
#getTwo=((moveTwo << 6 + 16) >> 11 + 16)
#two << getTwo
l += 1
when 3
three << x
#getThree=((moveThree << 11 + 16) >> 11 + 16)
#three << getThree
p += 1
#puts “#{one} #{two} #{three}”
l = 1
end
}

bufferscreen_height=480
bufferscreen_width=704
k=0
for i in 0…bufferscreen_height
#puts “Height: #{i} \n\n”
for j in 0…bufferscreen_width
#puts “Width: #{j} \n\n”
#q=Magick::Pixel.new(25,75,34, 0)

q=Magick::Pixel.new(one[k],two[k],three[k],0)
#q=Magick::Pixel.new(((one[k] << 17) >> 27), ((two[k] << 22) >> 27),

((three[k] << 27) >> 27), 0)
#puts “R:#{one[k]} G:#{two[k]} B:#{three[k]}”
#puts “\n\n”
#y, z = p.divmod(704)
image.pixel_color(j,i,q)

k += 1
end
end
image.write(image_file_name)
#=end


#2

fyi:

The source file “image1.txt” is 32 bit binary file and the file
“image1.bmp” that to be created needs to be 24 bit. This convertion
someone alreasy implemented in C# in our team from dev. side but we need
to do this using Ruby/RMagick.


#3

On Monday 19 January 2009 19:09:34 Kamaljeet S. wrote:

fyi:

The source file “image1.txt” is 32 bit binary file and the file
“image1.bmp” that to be created needs to be 24 bit. This convertion
someone alreasy implemented in C# in our team from dev. side but we need
to do this using Ruby/RMagick.

The source file you provided isn’t really 32bit, but 16bit (probably in
RGB565
mode)

Jan


#4

OK, if its 16 bit any way around to get it decoded and proper image out
in 24 bit.


#5

The file out still comes out incorrect. Please see attached file.


#6

Kamaljeet S. wrote:

OK, if its 16 bit any way around to get it decoded and proper image out
in 24 bit.

You can write the .bmp file using a BMP3: prefix to force 24-bit format:

img.write(“bmp3:myimage.bmp”)

For more information about ImageMagick and BMP format, go here:
http://www.imagemagick.org/Usage/formats/#bmp.


#7

Just to know and make sure that if its possible using Ruby + RMagick 2.0
to convert binary 32bit “.TEXT” file to 24 bit “.bmp” file ?

thanks


#8

Hi,

2009/1/20 Kamaljeet S. removed_email_address@domain.invalid:

require ‘rmagick’
p = 0
#getTwo=((moveTwo << 6 + 16) >> 11 + 16)
}

end
image.write(image_file_name)
#=end

Here is a working code for your 16 bit input file:
require ‘rmagick’
file_name = “C:/image1.text” # the binary file
image_file_name = “C:/image1.bmp” # the expected file to be generated
image = Magick::Image.new(704, 480)
file = File.open(file_name,“rb”).read

one = []
two = []
three = []

file.unpack(‘S*’).each { |x|
three << (x & 0x1F) * 8
two << ((x >> 5) & 0x1F) * 8
one << ((x >> 10) & 0x1F) * 8
}

bufferscreen_height=480
bufferscreen_width=704
k=0
for i in 0…bufferscreen_height
for j in 0…bufferscreen_width
q=Magick::Pixel.new(one[k],two[k],three[k],0)
image.pixel_color(j,i,q)
k += 1
end
end
image.write(image_file_name)

Regards,

Park H.


#9

The above posting code worked fine for 704/480 binary to image file but
for the attached file the same code is not working. Its 800/480 binary
file. Possible to advice please. Im try to use the following code.

require ‘rmagick’
file_name = “C:/image2.text” # the binary file
image_file_name = “C:/image2.bmp” # the expected file to be generated
image = Magick::Image.new(800, 480)
file = File.open(file_name,“rb”).read

one = []
two = []
three = []

file.unpack(‘S*’).each { |x|
three << (x & 0x1F) * 8
#puts “Three: #{three}”
two << ((x >> 5) & 0x1F) * 8
#puts “Two: #{two}”
one << ((x >> 10) & 0x1F) * 8
#puts “One: #{one}”
}

bufferscreen_height=480
bufferscreen_width=800
k=0
for i in 0…bufferscreen_height
for j in 0…bufferscreen_width
q=Magick::Pixel.new(one[k],two[k],three[k],0)
image.pixel_color(j,i,q)
k += 1
end
end
image.write(image_file_name)


#10

Hi,

I was able to get 1 binary files from dev. and tried the following code
but .bmp goes bad still. Possible please to look into and advice. Binary
files attached as zip file.

require ‘rmagick’
file_name = “C:/1.txt” # the binary file
image_file_name = “C:/1.bmp” # the expected file to be generated
image = Magick::Image.new(800, 480)
file = File.open(file_name,“rb”).read

one = []
two = []
three = []

file.unpack(‘S*’).each { |x|
three << (x & 0x1F) * 8
#puts “Three : #{three}”
two << ((x >> 5) & 0x1F) * 8
#puts “Two : #{two}”
one << ((x >> 10) & 0x1F) * 8
#puts “One : #{one}”

}

bufferscreen_height=480
bufferscreen_width=800
k=0
for i in 0…bufferscreen_height
for j in 0…bufferscreen_width
q=Magick::Pixel.new(one[k],two[k],three[k],0)
#puts “i is : #{i} and j is : #{j} R:#{one[k]} G:#{two[k]}
B:#{three[k]}”
image.pixel_color(j,i,q)
k += 1
end
end
image.write(image_file_name)

thanks


#11

2009/1/23 Kamaljeet S. removed_email_address@domain.invalid

#puts “One: #{one}”
end
end
image.write(image_file_name)

Attachments:
http://www.ruby-forum.com/attachment/3194/image2.text

I guess your input binary file is corrupted. It’s size must be
768000(800x480x2) bytes but it is only 76801 bytes.

Regards,

Park H.


#12

The code sent work prefectly fine. Thanks you so much for this help.

Possible to help to understand the following code. Understanding is
important i guess for future or any site that i can refer in regards to
the following code.

  • whats happeing in this “file.unpack(‘S*’).”
  • what this kind of code mean “0xF800”
  • what this means “>> 11) << 3)”

file.unpack(‘S*’).each { |x|
one << (((x & 0xF800) >> 11) << 3)
two << (((x & 0x7E0) >> 5) << 2)
three << ((x &0x1F)<< 3)
}

thanks


#13

Hi,

2009/1/29 Kamaljeet S. removed_email_address@domain.invalid:

file = File.open(file_name,“rb”).read
one << ((x >> 10) & 0x1F) * 8
#puts “i is : #{i} and j is : #{j} R:#{one[k]} G:#{two[k]}
B:#{three[k]}”
image.pixel_color(j,i,q)
k += 1
end
end
image.write(image_file_name)

The binary input file is 16bit rgb565 format and upside-down image.
Here is the modified code:

require ‘rmagick’
file_name = “C:/1.txt” # the binary file
image_file_name = “C:/image1.bmp” # the expected file to be generated
image = Magick::Image.new(800, 480)
file = File.open(file_name,“rb”).read

one = []
two = []
three = []

file.unpack(‘S*’).each { |x|
one << (((x & 0xF800) >> 11) << 3)
two << (((x & 0x7E0) >> 5) << 2)
three << ((x &0x1F)<< 3)
}

bufferscreen_height=480
bufferscreen_width=800
k=0
for i in 0…bufferscreen_height
for j in 0…bufferscreen_width
q=Magick::Pixel.new(one[k],two[k],three[k],0)
image.pixel_color(j,bufferscreen_height-i,q)
k += 1
end
end
image.write(image_file_name)

Regards,

Park H.


#14

2009/1/29 Kamaljeet S. removed_email_address@domain.invalid:

file.unpack(‘S*’).each { |x|
one << (((x & 0xF800) >> 11) << 3)
two << (((x & 0x7E0) >> 5) << 2)
three << ((x &0x1F)<< 3)
}

file.unpack(‘S*’) is for converting byte array to 16bit integer array.

In case of RBG565, the each 16bit consists of
RRRRRGGGGGGBBBBB (R: Red, G: Green, B: Blue)

First, extracting each color from rgb565
red = (rgb565 & 0xF800) >> 11
green = (rgb565 & 0x7E0) >> 5
blue = (rgb565 & 0x1F)

Then, converting 16bit color to 24bit color by multiplying 8,4,8
r = red << 3
g = green << 2
b = blue << 3

How do you come to know that “binary input file is 16bit rgb565 format”

The 16bit image is either rgb555 or rgb565.
If trying with rgb555 not works, it is rgb565.

Regards,

Park H.


#15

thanks for the reply.

Whats this terms means:

  1. “0xF800” or “0x7E0” so on… anything specific to anything.
    and
  2. what this means “<<” or “>>”

thanks


#16

2009/1/29 Kamaljeet S. removed_email_address@domain.invalid:

thanks for the reply.

Whats this terms means:

  1. “0xF800” or “0x7E0” so on… anything specific to anything.
    0xF800 is hexadecimal number ant equal to 63488 and 0b1111100000000000
    in binary.
    0x7E0 is 0b11111100000

RRRRRGGGGGGBBBBB & 0xF800 =
RRRRRGGGGGGBBBBB & 0b1111100000000000 =
RRRRR00000000000

RRRRRGGGGGGBBBBB & 0x7E0 =
RRRRRGGGGGGBBBBB & 0b1111100000000000 =
00000GGGGGG00000

and
2) what this means “<<” or “>>”

<< is binary left shift operator. The left operands value is moved
left by the number of bits specified by the right operand.

is binary right shift operator. The left operands value is moved right by the number of bits specified by the right operand.
RRRRR00000000000 >> 11 =
RRRRR

00000GGGGGG00000 >> 5 =
GGGGGG

RRRRR << 3 =
RRRRR000

GGGGGG << 2 =
GGGGGG00

Regards,

Park H.


#17

Hi,

The attached binary file is not displays image correctly and looks like
pixel shift is required. If i can get help on this please.

require ‘rmagick’
file_name = “C:/Hubimage1.txt” # the binary file
image_file_name = “C:/Hubimage1.bmp” # the expected file to be generated
image = Magick::Image.new(800, 480)
file = File.open(file_name,“rb”).read

one = []
two = []
three = []

file.unpack(‘S*’).each { |x|
one << (((x & 0xF800) >> 11) << 3)
two << (((x & 0x7E0) >> 5) << 2)
three << ((x &0x1F)<< 3)
}
bufferscreen_height=480
bufferscreen_width=800
k=0
for i in 0…bufferscreen_height
for j in 0…bufferscreen_width
q=Magick::Pixel.new(one[k],two[k],three[k],0)
image.pixel_color(j,i,q)
k += 1
end
end

image.write(image_file_name)


#18

One more thing i forgot to ask please.

How do you come to know that “binary input file is 16bit rgb565 format”

thanks