根据Wikipedia页面,.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]
为了将其转换为little-endian格式,我最好的解决方案是将每个十进制值转换为十六进制字符串,反转数组,连接元素,并将生成的十六进制字符串转换回整数。
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")
)?答案 0 :(得分:6)
Ruby中的字节争吵通常涉及String#unpack
和Array#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
答案 1 :(得分: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"]