前端小功能:圖片對比度。
阿新 • • 發佈:2021-01-11
圖片對比度
css,filter已經實現很多圖片的功能了,拋棄IE,及一些不潮流的瀏覽器,直接使用css屬性就好了。
filter: contrast(${contrastNum})
無奈如果要相容IE的話,就是最新版IE11,這些css都沒有效果
百度都是用
只好用canvas處理一下了,記錄一下,比較很少用到的吧。以後就不要相容IE了
示例:
先快取圖片,ajax,保持圖片源不被汙染,IE禁止通過Image跨域請求圖片
function handleGetBlob(baseUrl) {return new Promise((resolve, reject) => { let xhr = new XMLHttpRequest() xhr.open('GET', baseUrl, true) xhr.responseType = 'blob' xhr.onload = function(option:any) { let res = option.target if (res.status === 200) { const bloburl = window.URL.createObjectURL(res.response) resolve(bloburl) }else{ reject(baseUrl) } } xhr.send() }) } function handleGetImage(baseUrl) { return new Promise((resolve) => { const image = new Image(); image.src = baseUrl; image.onload = function() { resolve(image) } }) }
然後再用canvas裝換圖片對比度就好了
async function contrastImage(image, contrast){ if(!HTMLCanvasElement.prototype.toBlob){ Object.defineProperty(HTMLCanvasElement.prototype, 'toBlob', { value:function(callback,type,quality){ // eslint-disable-next-line @typescript-eslint/no-this-alias let canvas = this; setTimeout(function () { let binStr = atob(canvas.toDataURL(type, quality).split(',')[1]); let len = binStr.length; let arr = new Uint8Array(len); for (let i = 0; i < len; i++) { arr[i] = binStr.charCodeAt(i); } callback(new Blob([arr], { type: type || 'image/png' })); }); } }); } return new Promise((resolve, reject) => { try { let canvas = document.createElement('canvas'); if (canvas.getContext) { let ctx = canvas.getContext('2d'); canvas.height = image.height; canvas.width = image.width; ctx.drawImage(image, 0, 0); let imageD = ctx.getImageData(0, 0, image.width, image.height); let pdata:any = imageD.data; const cont = (Number(contrast)/10) const avg = 127; for (let i = 0; i < pdata.length; i+=4) { let r = pdata[i] let g = pdata[i+1] let b = pdata[i+2] // pdata[i] = r + contrast; // pdata[i + 1] = g + contrast; // pdata[i + 2] = b + contrast; if((r+(r-avg)*cont)>255){ pdata[i]=255; }else if((r+(r-avg)*cont)<0){ pdata[i]=0; }else { pdata[i] = r+(pdata[i+1]-avg)*cont; } if((g+(g-avg)*cont)>255){ pdata[i+1]=255; }else if((g+(g-avg)*cont)<0){ pdata[i+1]=0; }else { pdata[i+1] = g+(g-avg)*cont; } if((b+(b-avg)*cont)>255){ pdata[i+2]=255; }else if((b+(b-avg)*cont)<0){ pdata[i+2]=0; }else { pdata[i+2] = b+(b-avg)*cont; } } ctx.putImageData(imageD, 0, 0); canvas.toBlob(function(blob) { const bloburl = window.URL.createObjectURL(blob) resolve(bloburl) }); canvas = null; } } catch (error) { reject(contrastUrl) } }) }
處理匯出的是URL,直接繫結img就可以了。
註釋部分,是圖片亮度的顯示方式。
百無一用
百無一用
百無一用
百無一用
百無一用
百無一用
百無一用
百無一用
百無一用
百無一用
百無一用
推薦一下,圖片處理Javascript的文章:https://blog.csdn.net/phg1024/article/details/16332711
繼續推薦一下:https://www.cnblogs.com/fsjohnhuang/p/4127888.html#a7
https://www.cnblogs.com/jwm1999/p/13056344.html
asyncfunctioncontrastImage(image,contrast){ if(!HTMLCanvasElement.prototype.toBlob){ Object.defineProperty(HTMLCanvasElement.prototype,'toBlob',{ value:function(callback,type,quality){ //eslint-disable-next-line@typescript-eslint/no-this-alias letcanvas=this; setTimeout(function(){ letbinStr=atob(canvas.toDataURL(type,quality).split(',')[1]); letlen=binStr.length; letarr=newUint8Array(len); for(leti=0;i<len;i++){ arr[i]=binStr.charCodeAt(i); } callback(newBlob([arr],{ type:type||'image/png' })); }); } }); } returnnewPromise((resolve,reject)=>{ try{ letcanvas=document.createElement('canvas'); if(canvas.getContext){ letctx=canvas.getContext('2d'); canvas.height=image.height; canvas.width=image.width; ctx.drawImage(image,0,0); letimageD=ctx.getImageData(0,0,image.width,image.height); letpdata:any=imageD.data; constcont=(Number(contrast)/10) constavg=127; for(leti=0;i<pdata.length;i+=4){ letr=pdata[i] letg=pdata[i+1] letb=pdata[i+2] //pdata[i]=r+contrast; //pdata[i+1]=g+contrast; //pdata[i+2]=b+contrast; if((r+(r-avg)*cont)>255){ pdata[i]=255; }elseif((r+(r-avg)*cont)<0){ pdata[i]=0; }else{ pdata[i]=r+(pdata[i+1]-avg)*cont; } if((g+(g-avg)*cont)>255){ pdata[i+1]=255; }elseif((g+(g-avg)*cont)<0){ pdata[i+1]=0; }else{ pdata[i+1]=g+(g-avg)*cont; }
if((b+(b-avg)*cont)>255){ pdata[i+2]=255; }elseif((b+(b-avg)*cont)<0){ pdata[i+2]=0; }else{ pdata[i+2]=b+(b-avg)*cont; } } ctx.putImageData(imageD,0,0); canvas.toBlob(function(blob){ constbloburl=window.URL.createObjectURL(blob) resolve(bloburl) }); canvas=null; } }catch(error){ reject(contrastUrl) } }) }