我正在编写一个帮助方法,在需要时将图像转换为base64字符串。以下是代码
# config.rb
helpers do
def base64_url(img_link, file_type: "jpg")
require "base64"
if file_type =="jpg"
"data:image/jpg;base64,#{Base64.encode64(open(img_link).to_a.join)}"
elsif file_type =="png"
"data:image/jpg;base64,#{Base64.encode64(open(img_link).to_a.join)}"
else
link
end
end
end
在page.html.erb
中 <%= image_tag base64_url('/images/balcozy-logo.jpg') %>
现在问题是当ruby读取'/images/balcozy-logo.jpg'
时,它从系统根目录而不是从项目的根目录中读取文件。
错误信息如下
Errno::ENOENT at /
No such file or directory @ rb_sysopen - /images/balcozy-logo.jpg
如何解决此问题并从project_root/source/images
答案 0 :(得分:1)
在Middleman中app.root
返回应用程序的根目录。还有app.root_path
,它做同样的但返回一个Pathname对象,这稍微方便一点:
full_path = app.root_path.join("source", img_link.gsub(/^\//, ''))
如果gsub
以img_link
开头,/
是必需的,因为它会被解释为文件系统的根目录。
我冒昧地对你的方法做了一些修改:
require "base64"
helpers do
def base64_url(path, file_type: "jpg")
return path unless ["jpg", "png"].include?(file_type)
full_path = app.root_path.join("source", path.gsub(/^\//, ''))
data_encoded = File.open(full_path, 'r') do |file|
Base64.urlsafe_encode64(file.read)
end
"data:image/#{file_type};base64,#{data_encoded}"
end
end
我在这里做了一些事情:
将require "base64"
移至文件顶部;它不属于某种方法。
在方法的最开始点检查file_type
,如果它不在列出的类型中,则提前返回。
使用File.open
代替open(filename).to_a.join
(或更简洁的open(filename).read
)。 OpenURI(提供您正在使用的open
方法)对于从本地文件系统读取来说是过度的。
使用Base64.urlsafe_encode64
代替encode64
。可能没有必要,但它没有受到伤害。
删除不必要的if
;由于我们知道file_type
将jpg
或png
,我们可以直接在数据URI中使用它。
使用Middleman的内置资产系统可能有一种更优雅的方式来获取file_path
或确定文件的MIME类型,但是对文档进行非常简短的搜索并没有&#39什么都没有。