Forum: Ruby Converting binary image file to bmp file using RMagick2.0

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Kamaljeet S. (Guest)
on 2009-01-19 20:06
Attachment: image1.zip (0 Bytes)
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
Kamaljeet S. (Guest)
on 2009-01-19 20:10
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.
Jan D. (Guest)
on 2009-01-20 00:10
(Received via mailing list)
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
Kamaljeet S. (Guest)
on 2009-01-20 00:38
OK, if its 16 bit any way around to get it decoded and proper image out
in 24 bit.
Tim H. (Guest)
on 2009-01-20 00:52
(Received via mailing list)
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.
Kamaljeet S. (Guest)
on 2009-01-20 01:26
Attachment: image1.zip (0 Bytes)
The file out still comes out incorrect. Please see attached file.
Kamaljeet S. (Guest)
on 2009-01-20 20:47
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
Heesob P. (Guest)
on 2009-01-21 05:16
(Received via mailing list)
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.
Kamaljeet S. (Guest)
on 2009-01-22 18:36
Attachment: image2.text (0 Bytes)
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)
Heesob P. (Guest)
on 2009-01-23 03:11
(Received via mailing list)
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.
Kamaljeet S. (Guest)
on 2009-01-28 18:30
Attachment: 1.zip (0 Bytes)
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
Heesob P. (Guest)
on 2009-01-29 03:32
(Received via mailing list)
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.
Kamaljeet S. (Guest)
on 2009-01-29 03:42
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
Kamaljeet S. (Guest)
on 2009-01-29 03:45
One more thing i forgot to ask please.

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

thanks
Heesob P. (Guest)
on 2009-01-29 04:09
(Received via mailing list)
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.
Kamaljeet S. (Guest)
on 2009-01-29 05:27
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
Heesob P. (Guest)
on 2009-01-29 06:36
(Received via mailing list)
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.
Kamaljeet S. (Guest)
on 2009-02-04 23:05
Attachment: Hubimage1.zip (0 Bytes)
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)
This topic is locked and can not be replied to.