2016-01-21 41 views
0

我正在寫一個輔助方法需要時,將圖像轉換爲Base64字符串。下面是代碼如何文件的URL傳遞給輔助方法,在中間人

# 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') %>

現在的問題是,當紅寶石讀取'/images/balcozy-logo.jpg'它不是從項目的根目錄讀取系統根目錄下的文件。

錯誤信息如下

Errno::ENOENT at/
No such file or directory @ rb_sysopen - /images/balcozy-logo.jpg 

如何解決這個問題,並從project_root/source/images

+0

你知不知道你有'數據:在你的'if'的兩個分支圖像/ jpg'? –

回答

1

通過適當的圖片網址中間人app.root返回應用程序的根目錄。還有app.root_path,它不相同,但返回的路徑名對象,這是稍微更方便:

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 

我已經在這裏做了幾件事情:

  1. 感動require "base64"到的頂部文件;它不屬於一個方法。

  2. 檢查file_type在方法的開始,早返回,如果它不是所列類型之一。

  3. 而不是open(filename).to_a.join(或更簡潔的open(filename).read),請使用File.open。 OpenURI(提供您使用的open方法)對於從本地文件系統進行讀取而言是矯枉過正的。

  4. 使用Base64.urlsafe_encode64代替encode64。可能沒有必要,但它並沒有傷害。

  5. 卸下不必要if;因爲我們知道file_type將是jpgpng我們可以直接在數據URI中使用它。

有可能是一個更優雅的方式來獲得file_path或使用中間人的內置資產系統確定文件的MIME類型,而是一個非常簡單的搜索的文檔並沒有把任何東西。

+0

非常感謝您爲此付出的努力。我必須改變兩件事才能使它工作。 full_path行錯過了源目錄,因此它沒有找到該文件,所以我嘗試了這個'full_path = app.root_path +「#{:source}」+ path。gsub(/^\ //,'')'並且工作。 由於某些原因'urlsafe_encode64(file.read)'encode does not work,just just ahead ahead'encode64(file.read)'現在它的工作非常好。 還用PNG測試,一切都好。再次感謝:) –

+0

標記爲已接受的答案,請更新後來者的代碼。我可以做到這一點,但我希望你做的榮譽:) –

+1

':source'只是一個符號,它是Ruby中一種特殊的字符串,所以''#{:source}「'是等效的到':source.to_s',這只是''source''。我更新了我的答案,使用'app.root_path.join(「source」,path.gsub(...))'而不是'app.root_path + path.gsub(...)'。 –

相關問題