【问题标题】:Image Copy Issue with Ruby File method each_byteRuby 文件方法 each_byte 的图像复制问题
【发布时间】:2026-01-12 22:25:01
【问题描述】:

这个问题困扰了我一段时间。

我有一个 34.6 KB 的 jpeg 文件。我们称它为 Image A。使用 Ruby,当我将 Image A 的每一行复制到一个新创建的名为 Image B 的文件中时,它被完全复制。它与图像 A 的大小完全相同,并且可以访问。

这是我使用的代码:

image_a = File.open('image_a.jpg', 'r')
image_b = File.open('image_b.jpg', 'w+')

image_a.each_line do |l|
  image_b.write(l)
end

image_a.close
image_b.close

此代码生成 image_a 到 image_b 的完美副本。

当我尝试将图像 A 逐字节复制到图像 B 时,它复制成功,但文件大小为 88.9 KB,而不是 34.6 KB。我无法访问图像 B。我的 mac 系统提醒我它可能已损坏或正在使用无法识别的文件格式。

相关代码:

//same as before
image_a.each_byte do |b|
  image_b.write(b)
end
//same as before

为什么在逐字节复制时,图像 B 比图像 A 大?为什么它也会以某种方式、形状或形式受损?为什么图像 A 和 B 一样大小,逐行复制,并且可以访问?

我的猜测是问题是编码问题。如果是这样,如果编码格式转换为正确的代码点,为什么在逐字节复制时编码格式很重要?代码点是否混杂在一起,因此解析器无法区分它们?

\s 和 \n 重要吗?好像是这样。我做了一些研究,发现图像 A 有 128 行代码,而图像 B 只有一行。

感谢阅读!

【问题讨论】:

    标签: ruby image encoding unicode base64


    【解决方案1】:

    IO#each_byte 迭代字节(又名整数)。但是,IO#write 将字符串作为参数。所以它通过to_s将整数转换为字符串。

    假设图像中的第一个字节是2551,您可以将字符串"255" 写入image_b。这就是您的image_b 变大的原因。您将数字字符串写入其中。

    写回字节时尝试以下操作:

    image_a.each_byte do |l|
      image_b.write l.chr
    end
    

    1 正如@stefan 指出的jpeg 图像以FF D8 开头。所以第一个字节是255

    【讨论】:

    • 或者只是image_b.write(l.chr)
    • 你是对的 :) 我最好在回答中使用chr()。谢谢!
    • 不应该 each_line 是 each_byte 因为 chr() 是在单个字节上操作?谢谢顺便说一句。它奏效了。
    • 正如@Stefan 所说,image_b.write(l.chr)(不是image_b.write(byte.chr))。
    • 谢谢,已编辑。看来我太累了不应该回答:) 错别字太多。