如何将.png文件的数据嵌入Ruby文件中?
我的问题是关于Ruby源文件以及在其中存储二进制数据的能力 我知道在Ruby文件中如何将.png文件的数据嵌入Ruby文件中?,ruby,image,Ruby,Image,我的问题是关于Ruby源文件以及在其中存储二进制数据的能力 我知道在Ruby文件中\uuuuuuuuuuuuuuu\uuuuuuu之后,我可以将我想要的任何数据放在那里,文件仍然可以正常工作 然后我可以通过数据常量加载它 给定一个文件“foobar.png”,我如何将这些数据放入一个文件中,在\uuuu END\uuuu注释后存储该文件,然后再次加载它,这样我就有了一个“功能性”图像 我的想法是创建一个Ruby文件,它向用户提供HTML(启动时默认使用Webrick),并具有一些小图像 稍后,我
\uuuuuuuuuuuuuuu\uuuuuuu
之后,我可以将我想要的任何数据放在那里,文件仍然可以正常工作
然后我可以通过数据
常量加载它
给定一个文件“foobar.png”,我如何将这些数据放入一个文件中,在\uuuu END\uuuu
注释后存储该文件,然后再次加载它,这样我就有了一个“功能性”图像
我的想法是创建一个Ruby文件,它向用户提供HTML(启动时默认使用Webrick),并具有一些小图像
稍后,我希望最终在该文件中存储多个.png文件,但现在我只想了解如何读取应为.png文件的数据流。我想UNIX读取二进制数据的方法是。有一种方法可以顺利地用于此类数据 一般用法代码示例:
require 'base64'
encode = Base64.encode64(File.read('/path/to/my_awesome_picture.jpg') # this will convert picture to ASCII text
decode = Base64.decode64(File.write('/path/to/new_awesome_picture.jpg', encode)) # This will convert
注意:实际上没有测试代码,但应该可以工作。因为Ruby文件是以文本编码的,所以不能将数据包含为二进制blob,所以必须以某种方式对其进行编码。最简单的方法是合并格式。执行类似于在将PNG名称映射到Base64数据之后放置JSON对象的操作。因此:
require "json"
require "base64"
f = File.open("thiscamefromthescript.png", "wb")
f.write(Base64.decode64(JSON.parse(DATA.read)['some_png']))
__END__
{
"some_png" : "BASE64ENCODEDIMGAGEHERE"
}
您可以非常简单地做到这一点,至少对于一个文件,尽管我不确定是否推荐它。源文件的
数据
部分的内容(\uuuuu END\uuuu
之后的位)不需要是文本,它们可以是任何二进制数据,您可以使用将其放置到位
DATA
常量只是一个对象,因此您可以对其调用read
,以获取字符串中的数据
下面是一个使用Sinatra为图像提供服务的示例。(在某些方面使用Sinatra会使这变得更复杂,因为在经典模式下,Sinatra会查看数据段本身以获取内联模板,这就是本示例使用模块化样式的原因)
然后,您可以运行ruby combined.rb
,Sinatra服务器将为您的映像提供服务,以满足对其根目录的任何请求
我认为Java for Linux的早期版本是以自解压二进制文件的形式发布的,它使用了与此类似的技术—它使用了一个连接到压缩归档文件的shell脚本,该脚本检测到同一文件中压缩内容的开头,并解压缩并写出这些文件
以这种方式合并多个文件会很棘手。您可能需要一些分隔符来分隔它们,因为您处理的是二进制数据,所以需要确保分隔符不会出现在实际数据中。我认为最简单的解决方案是对它们进行base64编码,并在数据部分使用一些数据格式,您的代码可以对其进行解析和解码
但我怀疑这是否是正确的方式。如果您想让分发脚本变得更容易,那么更好的选择可能是将所有内容打包到包含代码和图像的gem中。虽然这是可行的,但这是一个非常糟糕的主意。.png文件的等效表示形式在文本文件中要大得多,这就是Ruby脚本。此外,您必须修改源代码才能修改图像。相反,将源代码和数据拆分,不要将它们合并到单独的Ruby脚本和单独的PNG文件中,并根据需要从磁盘加载它们。这将非常快速,并且不需要编辑代码来添加/删除图像。替代方法是重定向浏览器,将适当的文件作为“图像”(HTTPd)服务器提供的静态图像加载,或将其作为blob或数据库中的文件名和磁盘上的图像存储在数据库中,等等,除了将编码数据存储在文件中,我什么都愿意做。
require 'sinatra/base'
class App < Sinatra::Base
set :image, DATA.read
get '/' do
headers['Content-type'] = 'image/png'
settings.image
end
end
App.run!
# make sure there's a newline after __END__
# but only one so you don't add any more data at the
# start of your image file
__END__
cat source.rb image.png > combined.rb