image in css/html from url to uri

上次寫了一個單獨一個檔案轉換為 data uri ,但在網站圖片尚未完全確定前這樣做事相當花費時間而且難以驗證檔案,所以再寫了一個 script 夾帶再出 build 流程中,方便的把圖片轉換為 data uri,當然 data uri 沒辦法適用所有的圖片,所以 script 中的 minSize 就是設定要轉換的圖片尺寸上限,單位為 pixel (大約計算出檔案大小),由於 html parse 重寫一次比較麻煩,所以使用了 cheerio 方便做 dom selector

由於許久沒寫 coffeeScript 決定用這 script 快速複習一下

fs = require('fs')
cheerio = require('cheerio')
staticFolder = 'static'
imgFolder = 'img'
cssFolder = 'css'
cssRoot = __dirname + '/' + cssFolder
htmlFolder = 'views'
htmlRoot = __dirname + '/../application/' + htmlFolder
minSize = 300
minFileSize = minSize * minSize * 3
skipFiles = ['.sass-cache', '.DS_Store', 'http://', 'sass', 'template.css', 'template_bho.css', 'ie.css', 'print.css', 'mail']
Core = module.exports =
getFileList: (folderPath = null, cb) ->
console.log 'getFileList begin ', arguments
return null unless folderPath
return fs.readdirSync(folderPath) unless cb
fs.readdir folderPath, (err, files) ->
(if (err) then cb(null) else cb(files))
getFile: (path = null, cb) ->
console.log 'getFile begin ', arguments
return null unless path
unless cb
f = fs.readFileSync(path)
if f
return f.toString()
else
return null
fs.readFile path, (err, data) ->
(if (err) then cb(null) else cb(data.toString()))
saveFile: (path = null, data = null, cb) ->
console.log 'saveFile begin ', arguments
return null unless path
return null unless data
if typeof(data) is 'string'
data = new Buffer(data, 'utf8')
unless cb
return fs.writeFileSync(path, data)
fs.writeFile path, data, (err) ->
if(err)
console.log 'err = ' ,err
else
console.log 'save success = ', path
getCSSUrl: (cssData = null, isDuplicate = null, cb) ->
console.log 'getCSSUrl begin ', arguments
return null unless cssData
css = cssData
ma = css.match(/url\(\.\.[^ \;\,]*\)/g)
result = []
return ma unless isDuplicate
for i of ma
m = ma[i]
result.push m if result.indexOf(m) < 0
return result
imageToUri: (data = null, format = 'png') ->
console.log 'imageToUri begin ', arguments
return null unless data
base64data = new Buffer(data).toString('base64')
return imgString = 'url(data:image/' + format + ';base64,' + base64data + ')'
replacePath: (originalPath = '') ->
console.log 'replacePath begin ', arguments
# url(../img/landing/bg_num_web1.png)
originalPath = originalPath.substr(4, originalPath.length - 5)
return __dirname + originalPath.replace(/\.\./i, '')
replaceSrcPath: (originalPath = '') ->
console.log 'replaceSrcPath begin ', arguments
# /static/img/landing/bg_num_web1.png
# originalPath = originalPath.substr(4, originalPath.length - 5)
_regex = new RegExp('/' + staticFolder, 'i')
return __dirname + originalPath.replace( _regex, '')
replaceCSS: (cssPath = null, cb) ->
console.log 'replaceCSS begin ', arguments
return null unless cssPath
data = @getFile(cssPath)
if data
urls = @getCSSUrl(data)
if urls and urls.length
for i of urls
oldUrl = urls[i]
newUrl = @replacePath(urls[i])
img = @getFile(newUrl)
if(img.length < minFileSize)
uri = @imageToUri(img)
data = data.replace(oldUrl, uri)
@saveFile(cssPath, data)
else
console.log 'can not find ==> ', cssPath
replaceHtml: (htmlPath = null, cb) ->
console.log 'replaceHtml begin ', arguments
return null unless htmlPath
data = @getFile(htmlPath)
if data
$ = cheerio.load(data)
$('img').each (index, item)=>
$item = $(item)
if $item.attr('data-i18n-img')
return
src = $item.attr('src')
if src and src.indexOf('<?') < 0
src = @replaceSrcPath(src)
img = @getFile(src)
uri = @imageToUri(img)
if img.length < minFileSize
$item.attr('src', uri)
@saveFile(htmlPath, $.html())
else
console.log 'can not find ==> ', cssPath
# image in CSS
cssfiles = Core.getFileList(cssRoot)
for i of cssfiles
cName = cssfiles[i]
cPath = cssRoot + '/' + cName
if skipFiles.indexOf(cName) >= 0
continue
Core.replaceCSS(cPath)
# image in HTML or other views/template
htmlfiles = Core.getFileList(htmlRoot)
for i of htmlfiles
hName = htmlfiles[i]
hPath = htmlRoot + '/' + hName
if skipFiles.indexOf(hName) >= 0
continue
Core.replaceHtml(hPath)


相關連結
cheerio
nodejs image to Data uri
coffeeScript

沒有留言:

張貼留言