JS實現(xiàn)將圖片轉(zhuǎn)為base64格式
前言
前段時間在寫我的VUE全棧項目的時候,遇到要把前端的照片上傳到后端,再由后端存到數(shù)據(jù)庫的問題,通過網(wǎng)上查找資料,看了一些其他寫者的解決方法,最終采用轉(zhuǎn)BASE64的方法。本人覺得把上傳的圖片轉(zhuǎn)為BASE64格式相比其他是比較簡單的。
什么是BASE64
Base64是一種用64個字符來表示任意二進(jìn)制數(shù)據(jù)的方法。它是一種編碼方式,而非加密方式,即可以將一張圖片數(shù)據(jù)編碼成一串字符串,使用該字符串代替圖像地址。
BASE64的優(yōu)缺點
優(yōu)點: 減少一張圖片的http請求
缺點: 導(dǎo)致轉(zhuǎn)換后的css文件體積增大,而CSS 文件的體積直接影響渲染,導(dǎo)致用戶會長時間注視空白屏幕,而且轉(zhuǎn)換后的數(shù)據(jù)是一大串字符串。
注意:圖片轉(zhuǎn)BASE64格式的適合小圖片或者極簡單圖片,大圖片不劃算。它的格式為:data:image/type;base64,xxxx...
雖然說這種方式不適用于體積大的圖片,但不得不說有時候還挺方便的。由于在我的vue項目中上傳的圖片都比較小,單一,為了方便我采用了這種方式來實現(xiàn)將前端上傳的圖片存到數(shù)據(jù)庫中。
話不多說,進(jìn)入正題!下面以Vue+Koa框架、數(shù)據(jù)庫為MYSQL為例。
案例
前端: 首先在把圖片傳給后端之前,前端對圖片進(jìn)行格式轉(zhuǎn)換,轉(zhuǎn)換成功后就可以照常調(diào)用后端給的接口,傳進(jìn)去就行。
我這里就是點了提交按鈕后,觸發(fā)編寫的點擊事件函數(shù),在函數(shù)里先對圖片轉(zhuǎn)base64,轉(zhuǎn)成功后再調(diào)用后端給的接口,把此數(shù)據(jù)以及其他數(shù)據(jù)傳進(jìn)去就行。
在前端編寫轉(zhuǎn)base64的函數(shù)(很重要)
export function uploadImgToBase64 (file) { return new Promise((resolve, reject) => { const reader = new FileReader()//html5提供的一種異步文件讀取機制 reader.readAsDataURL(file)//將文件讀取為Base64編碼的數(shù)據(jù)URL reader.onload = function () { // 圖片轉(zhuǎn)base64完成后返回reader對象 resolve(reader) } reader.onerror = reject }) }
前端要為轉(zhuǎn)為base64的圖片的相應(yīng)操作
const state = reactive({ picture: [] //這個是用來裝表單里選中的照片 }) const imgBroadcastListBase64 = [] //用來存放轉(zhuǎn)base64后的照片,用數(shù)組是因為上傳的圖片可能不止一張 console.log('圖片轉(zhuǎn)base64開始...') // 遍歷每張圖片picture 異步 const filePromises = state.picture.map(async file => { //console.log(file); const response = await uploadImgToBase64(file.file) //調(diào)用函數(shù) 將圖片轉(zhuǎn)為base64 //console.log(response,111); return response.result.replace(/.*;base64,/, '') // 去掉data:image/jpeg;base64, }) // 按次序輸出 base64圖片 for (const textPromise of filePromises) { imgBroadcastListBase64.push(await textPromise) } console.log('圖片轉(zhuǎn)base64結(jié)束..., ', imgBroadcastListBase64) //判斷imgBroadcastListBase64是否<=1,是的話就是上傳一張圖片,否則上傳的是多張圖片 if(imgBroadcastListBase64.length<=1){ state.imgsStr = imgBroadcastListBase64.join()//轉(zhuǎn)字符串 }else{ state.imgsStr = imgBroadcastListBase64.join(',')//轉(zhuǎn)字符串并且每個值用','拼接,這樣是為了方便后面從數(shù)據(jù)庫拿到數(shù)據(jù),將圖片又轉(zhuǎn)為之前的base64格式 } //調(diào)用后端提供的接口,傳數(shù)據(jù)到數(shù)據(jù)庫里(這個只是自己編寫的后端接口,主要是為了展示傳數(shù)據(jù)) const res = await secondGoodsAdd({ create_time: ti, content_goods: state.content, color: state.title2, price: state.title3, tel: state.title4, img: state.imgsStr,//轉(zhuǎn)base64后的圖片 concat_num: 0, like_num: 0, name_goods: state.title1 }) if (res.code === '80000') { showSuccessToast('發(fā)布成功!') } router.push('/cicle')
存到數(shù)據(jù)庫中的圖片路徑是轉(zhuǎn)為base64后的且刪除前面data:image/jpeg;base64
的字符串。
這樣數(shù)據(jù)就存到數(shù)據(jù)庫中啦!存進(jìn)去的是字符串。
那么問題來了,數(shù)據(jù)是存進(jìn)去了,但是我又想拿到這個數(shù)據(jù)到前端顯示出來,好,那我就先直接拿到前端用,結(jié)果發(fā)現(xiàn)報錯了!說是請求頭太長?想辦法解決下!后面我的解決辦法是拿到這個轉(zhuǎn)為了base64且去掉前面data...字段的的圖片數(shù)據(jù)再轉(zhuǎn)為正常的base64的格式。好,來轉(zhuǎn)換吧!
//我這里是在后端編寫的接口,用于展示被添加到數(shù)據(jù)庫中的所有數(shù)據(jù) router.get('/cirleLifeLook',async(ctx,next)=>{ try { const result=await userService.cirleLifeLook() for(let i=0;i<result.length;i++){ var imgData=result[i].img //獲取每條數(shù)據(jù)中的照片字段 if(imgData){ if(imgData.indexOf(',')>-1){//存在','的話代表是多張圖片的混合的字符串 let ans=imgData.split(',') //切割 獲得多張之前切掉data...后的base64字符串 let s=[] for(let j=0;j<ans.length;j++){ s.push("data:image/png;base64,"+ans[j])//還原每張圖片初始的base64數(shù)據(jù) } result[i].img=s }else{ result[i].img="data:image/png;base64,"+imgData //就一張圖片直接在前面拼接"data:image/png;base64," } } }//到此為止,在給前端傳數(shù)據(jù)前就修改了其中每條數(shù)據(jù)里的照片地址,這樣就可以正常顯示啦 if(result.length){ ctx.body={ code:'80000', data:result, msg:'獲取成功' } }else{ ctx.body={ code:'80005', data:'null', msg:'還沒有信息' } } } catch (error) { ctx.body={ code:'80002', data:error, msg:'服務(wù)器異常' } } })
OK,到此就結(jié)束啦~現(xiàn)在是不是覺得把圖片轉(zhuǎn)base64還是挺簡單的?還挺有用的?快去實踐下吧。記住此方法只適合小圖片類型的,大點的文件可能會崩掉哈!
到此這篇關(guān)于JS實現(xiàn)將圖片轉(zhuǎn)為base64格式的文章就介紹到這了,更多相關(guān)JS圖片轉(zhuǎn)base64內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript+html實現(xiàn)前端頁面滑動驗證(2)
這篇文章主要為大家詳細(xì)介紹了JavaScript+html實現(xiàn)前端頁面滑動驗證的第二種方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-06-06JavaScript事件學(xué)習(xí)小結(jié)(三)js事件對象
這篇文章主要介紹了JavaScript事件學(xué)習(xí)小結(jié)(三)js事件對象的相關(guān)資料,非常不錯具有參考借鑒價值,需要的朋友可以參考下2016-06-06為body標(biāo)簽和document.body都添加點擊事件后僅Firefox彈出了兩次
為body標(biāo)簽和document.body都添加點擊事件后僅Firefox彈出了兩次,需要的朋友可以參考下。2011-04-04javascript操作向表格中動態(tài)加載數(shù)據(jù)
這篇文章主要為大家詳細(xì)介紹了javascript操作向表格中動態(tài)加載數(shù)據(jù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2020-08-08Iframe 自適應(yīng)高度并實時監(jiān)控高度變化的js代碼
不得不用到iframe,且被強烈要求不能讓它出現(xiàn)滾動條!嵌入的頁面肯定是高度不一的,頁面中也不能出現(xiàn)大片空白,所以也不能寫死高度!真是麻鬼煩??!2009-10-10JavaScript判斷瀏覽器對CSS3屬性是否支持的多種方法
其實在使用css3的一些屬性時,為了兼顧低端瀏覽器對CSS3的不友好性,往往需要知道某些瀏覽器是否支持要使用的CSS3屬性,以此來做向下適配。比如常見的CSS3動畫就很有必要檢測瀏覽器是否支持。下面本文就分享了幾種方法,有需要的朋友們可以參考借鑒。2016-11-11