1

根据维基百科页面,.bmp图像的宽度存储在文件的标题中,以字节 0x12 到 0x15 为单位。例如,在 256x256 的图像中,字节 0x12 到 0x15 看起来像这样;Ruby 将每个字节转换为整数:

file = File.open("red_bmp.bmp", "r")
bytes = file.bytes.to_a
bytes[0x12..0x15]
#=> [0, 1, 0, 0]

为了将其转换为小端格式,我最好的解决方案是将每个十进制值转换为十六进制字符串,反转数组,连接元素,然后将生成的十六进制字符串转换回整数。

width = bytes[0x12..0x15].map {|x| x.to_s(16).rjust(2, "0")}.reverse.join.to_i(16)
#=> 256
  • 有没有更简单的方法来解决这个问题?
  • 有没有一种简单的方法来读取文件并返回一个十六进制值数组而不是整数(不求助于x.to_s(16).rjust(2, "0"))?
4

2 回答 2

6

Ruby 中的字节争论通常涉及String#unpackArray#pack; 在您的情况下,您希望将一些字节解压缩到本机 Ruby 值中,以便您想要String#unpack并且想要使用以下V格式:

V         | Integer | 32-bit unsigned, VAX (little-endian) byte order

我会做这样的事情:

# The "b for binary" is important since you just want to deal with bytes
# and any encoding will get in the way.
fp = open(whatever, 'rb')

# Seek to the desired offset.
fp.seek(0x12)

# Read in four bytes.
s = fp.read(4)

# Unpack the bytes and the array:
two_fifty_six = s.unpack('V').first
于 2013-07-06T02:02:57.830 回答
2

有没有更简单的方法来解决这个问题?

f =  File.open('mybmp.bmp',"wb")
str = [256, 256].pack "l>2"
p str     #"\x00\x00\x01\x00\x00\x00\x01\x00"
f.write str
f.close

f = File.open('mybmp.bmp', "rb")
str = f.read 8
arr = str.unpack "l>2"
p arr     #[256, 256]

str = arr.pack("l<2")
p str    #"\x00\x01\x00\x00\x00\x01\x00\x00"

有没有一种简单的方法来读取文件并返回一个十六进制值数组而不是整数

用这一行替换上面的最后两行:

p arr.map {|num| sprintf "%04x", num }  #["0100", "0100"]

也许:

arr = str.unpack "h*"
results = []

arr[0].scan(/.{8}/) do |chars8|
  curr = ""

  chars8.scan(/.{2}/) do |chars2|
    curr << "\\x#{chars2}"
  end

  results << curr
end

p results     #["\\x00\\x00\\x10\\x00", "\\x00\\x00\\x10\\x00"]
于 2013-07-06T01:28:59.133 回答