我基本上是在图片文件的标题中阅读并进行快速比较,以查看它实际上是什么类型的文件.BMP,GIF,PNG都很简单,因为它们的标题分别包含BM,GIF和PNG以识别自己.JPG给我带来了一些循环.
jpg的前3个字节往往是0xff\0xd8\0xff,在我的生命中,无论我如何设置它,我都无法通过简单的比较得到真正的值.
我读了前4个字节:
if data[0, 3] == "\xff\xd8\xff"
puts "This is a JPG"
end
Run Code Online (Sandbox Code Playgroud)
我知道我很接近,但我无法让它发挥作用.请让我知道我在这里错过了什么.
注意:我知道有宝石为我做这个,但我不想使用宝石.就那么简单.
这是一个字符编码问题.从JPEG读取前4个字节将返回ASCII编码的字符串:
head = File.read("some.jpg", 4)
# => "\xFF\xD8\xFF\xE1"
head.encodig
# => #<Encoding:ASCII-8BIT>
Run Code Online (Sandbox Code Playgroud)
另一方面,字符串是UTF-8编码的:
jpg_prefix = "\xff\xd8\xff"
# => "\xFF\xD8\xFF"
jpg_prefix.encoding
# => #<Encoding:UTF-8>
Run Code Online (Sandbox Code Playgroud)
比较UTF-8和ASCII字符串不能按预期工作:
head[0,3] == jpg_prefix
# => false
Run Code Online (Sandbox Code Playgroud)
您必须使用以下命令显式设置编码String#force_encoding:
jpg_prefix = "\xff\xd8\xff".force_encoding(Encoding::ASCII_8BIT)
# => "\xFF\xD8\xFF"
jpg_prefix.encoding
# => #<Encoding:ASCII-8BIT>
head[0,3] == jpg_prefix
# => true
Run Code Online (Sandbox Code Playgroud)
使用Integer#chr(由Mario Visic建议)创建的串联ASCII字符也有效:
jpg_prefix = 0xff.chr + 0xd8.chr + 0xff.chr
# => "\xFF\xD8\xFF"
jpg_prefix.encoding
# => #<Encoding:ASCII-8BIT>
Run Code Online (Sandbox Code Playgroud)
或者使用Array#pack:
jpg_prefix = ["FFD8FF"].pack("H*")
# => "\xFF\xD8\xFF"
jpg_prefix.encoding
# => #<Encoding:ASCII-8BIT>
Run Code Online (Sandbox Code Playgroud)