請在這裏查看示例☞ gm示例
安裝
GraphicsMagick和ImageMagick的區別
- GraphicsMagick是從ImageMagick中分離出來的,推薦下載ImageMagick
加載GraphicsMagick(大小4.72 MB)
var gm = require('gm')
加載ImageMagick(大小23.8 MB)
var gm = require('gm').subClass({imageMagick: true})// 注意使用的區別
- 除了加載有區別,其他使用方式完全一樣
window版本
- 下載imagemagick的window版本(在頁面靠下方),如圖:
- 雙擊exe文件,進行安裝,安裝過程中要注意勾選以下選項
linux版本(ubuntu 16.04)
要點
圖片水印
var gm = require('gm').subClass({imageMagick: true})
gm('./public/images/a.png')// 原圖路徑
.font('./fonts/zhulangyingxingti.ttf')// 配置逐浪硬行體字庫路徑
.drawText(10, 10, '水印')
.write('./public/images/b.png', function (e) {// 輸出的圖片路徑
if(e) {
console.log(e.message)
}else {
console.log('done')
}
})
drawText()中文亂碼
- 字體文件使用中文名稱命名,運行時會報錯,所以不要使用中文命名
- 如果確保字庫引入正確,還出現中文亂碼,那一定是字庫文件本身有問題,換一種字庫就可以了
- 嘗試過字庫格式ttf、otf均支持
詳見:
字庫ttf和otf格式有什麼區別?
圖片驗證碼
- 準備一張背景雜亂的圖片和藝術字體的英文字庫
index.html
<img src="/gm/captchaAdd"><!-- 前端通過img標籤請求驗證碼 -->
app.js
var express = require('express') var session = require('express-session') ... var cap = {// 通過函數隨機出一個驗證碼對象,包括文字和在雜亂背景上的位置(這裏假如如下) text: 'ab12', pos: [20, 50], } // 生成驗證碼 app.all('/gm/captchaAdd', function(req, res, next) { var url = './public/images/'+(''+Math.cap()).replace('.', '')+'.png'// 設置驗證碼的輸出路徑,且給一個隨機文件名 gm('./lib/images/captchaBg.png')// 一張背景雜亂的圖片作爲驗證碼的背景 .font('./lib/src/SelfRighteousness-Regular.ttf')// 一種略藝術的英文字庫 .fontSize(50)// 設置字體大小 .drawText(cap.pos[0], cap.pos[1], cap.text)// 寫入隨機的驗證碼 .crop(100, 40, cap.pos[0], cap.pos[1])// 將相應的文字部分裁剪出來,作爲驗證碼 .noise(1)// 加入噪點 .write(url, function (e) {// 隨機一個文件名,並輸出驗證碼 if(e) { console.log(e.message) }else { req.session.captcha = cap// 將驗證碼對象寫入session,用來登錄時跟用戶輸入的作比較 res.download(url)// 這裏用download方法發送圖片,前端千萬不能用ajax方式請求 } }) }) // 用戶登錄 app.all('/user/login', function(req, res, next) { if(req.body.captcha.toLocaleLowerCase() != req.session.captcha.text.toLocaleLowerCase()) { res.send({message: '驗證碼不正確'}) }else { ... } })
- 效果如下
- 2. 3.
- 最後可以通過AI開放平臺提供的文字識別技術來測試機器識別的效果
- 升級版驗證碼(參考慕課網)
- 用戶使用某個用戶名嘗試登陸,如果錯誤,將給該用戶名在數據庫記錄一次錯誤
- 該用戶名錯誤次數達到3次,要求需等待半小時後才能再次嘗試登錄該用戶名,且必須輸入驗證碼
- 所以當用戶來到登錄頁面時,在輸入用戶名之後(或從cookie拿到記錄的用戶名),需要發送一個請求去驗證此用戶名是否需要輸入驗證碼,如需要,將驗證碼輸入框顯示出來
- 這個有個問題就是,其他用戶可以通過故意錯誤的登錄某些用戶名,來使這些用戶名永遠處於等半小時的狀態,導致永遠無法登陸(不過爲了用戶安全,犧牲一點用戶體驗也是值得的)
頭像裁剪
- 下面我給出4種方式的思路
- 方式1(本篇提供的demo即使用此方法)
- 前端使用上傳插件Webuploader來提供上傳圖片的功能
- 前端使用Jcrop來提供裁剪的位置
- 後端使用gm根據給出的裁剪位置對上傳的圖片進行裁剪
- 方式2(可以藉助jquery-plugins/h5Crop/插件,該插件我會繼續完成)
- 前端利用canvas實現裁剪和壓縮,將處理後的base64傳給後端
- 後端將base64轉化成圖片,返回給前端進行展示
- 方式3
- 前端把圖片傳給後端
- 後端壓縮處理過之後,返回給前端(附帶圖片唯一標識)
- 前端使用Jcrop獲取圖片的裁剪位置,將裁剪位置和圖片唯一標識傳給後端
- 後端對對應的圖片進行裁剪
- 方式4(這個需要藉助我的另一個裁剪插件,提供了2種方式進行裁剪,效果跟qq裁剪頭像一樣,以後會開源)
- 前端裁剪
- 前端通過js對圖片進行平移、縮放操作
- 再通過canvas的drawImage方法繪製操作後的圖片
- 再通過canvas的toDataURL進行壓縮同時獲取最終的base64
- 傳base64到後端,後端轉爲圖片,返回圖片路徑,前端進行展示
- 後端裁剪
- 前端通過js對圖片進行平移、縮放操作
- 將操作後獲取的裁剪參數(裁剪框的大小、縮放的比率、壓縮的比率)和圖片文件一同傳給後端
- 後端對上傳的文件進行裁剪,返回圖片路徑,前端進行展示
- 需使用到的ImageMagick小細節
- 讀取本地圖片資源
gm('upload\\temp\\crop\\20180601\\49076530-6584-11e8-9542-0d60dcc7daa8.jpg')
) - 讀取外鏈圖片資源
gm('http://localhost:3000/upload/temp/crop/20180601/49076530-6584-11e8-9542-0d60dcc7daa8.jpg')
) - 讀取base64圖片資源
'inline:' + 'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBD...'
)(注意不適用超過5000個字符的base64字符串,否則會轉換失敗) - 爲了解決base64過長時ImageMagick處理會失敗,我們使用node來轉換base64爲圖片
- 縮放圖片傳入百分比
gm('xxx.png').resize('50%')
) - 壓縮圖片傳入值
gm('xxx.png').quality(50)
) - 不管是前端canvas壓縮還是後端ImageMagick壓縮,最後的輸出的格式都要是jpeg或jpg,否則壓縮後的大小很可能會變大
- 讀取本地圖片資源
- 效果展示(動圖較大,請耐心等待)
- 前端裁剪
- 優缺點對比
- 方式1:後端只要寫1個接口(Webuploader對圖片可以進行壓縮)
- 方式2:兼容性IE>=10,減少後端工作量
- 方式3:適中,後端需要寫2個接口(上傳圖片接口和裁剪圖片接口)
- 方式4:編寫複雜,但是擴展性好,可自由選擇一種方式