強大的CSS:濾鏡和混合模式處理的圖片如何上傳下載?

智雲程式設計發表於2019-05-22

一、使用CSS濾鏡和混合模式線上PS

使用CSS濾鏡和混合模式可以實現各種各樣的影像處理效果,內建眾多影像處理效果,部分效果示意如下縮圖:

強大的CSS:濾鏡和混合模式處理的圖片如何上傳下載?

進入demo頁面你也可以點選這裡的按鈕,更換你本地的素材,檢視對應的影像效果:

強大的CSS:濾鏡和混合模式處理的圖片如何上傳下載?

呈現的效果雖好,但是也帶來另外一個問題,雖然視覺上是已經處理後的圖片,但是如果我們右鍵-圖片另存為,會發現還是原圖。

如果使用者覺得某個圖片處理後的效果很棒,想要儲存到自己的本機,就會受阻。

或者說,我們基於CSS濾鏡和混合模式製作了一款影像處理的工具,最後需要把這些已經處理好的圖片上傳到後臺,作為一個獨立的 <img> 元素使用,也會受阻。

怎麼辦?難道我們要放棄這麼好的特性,還使用canvas來處理影像嗎?[圖片上傳失敗...(image-9fb53e-1558444076034)]

不需要的,實際上是有方法可以得到CSS處理後的影像的。

二、SVG foreignObject元素與視覺儲存

SVG中有個 <foreignObject>元素 ,可以實現在SVG內部嵌入XHTML元素,例如:

// canvas轉為blob並上傳
canvas.toBlob(function (blob) {
    // 圖片ajax上傳
    var xhr = new XMLHttpRequest();
    // 檔案上傳成功
    xhr.onload = function() {
         // xhr.responseText就是返回的資料
    };
    // 開始上傳
    xhr.open("POST", 'upload.php', true);
    xhr.send(blob);    
}, 'image/jpeg');

而SVG本質上就是個影像,也就是說,我們只需要把影像處理相關的HTML程式碼和CSS程式碼放在 <foreignObject> 元素中,然後作為 <img> 影像呈現,然後再繪製到canvas畫布上,這樣就可以得到純正的處理後的點陣圖影像了。

demo頁面最後一張圖片和CSS處理後的圖片長相雖同,但是本質卻不同,一個還是原始圖(試試右鍵-另存為),一個本質上是合成圖(試試右鍵-另存為),如下截圖示意:

強大的CSS:濾鏡和混合模式處理的圖片如何上傳下載?

於是,接下來,無論是是要下載到本機還是上傳到伺服器都不是問題。

關於上傳,可以傳輸影像canvas.toDataURL()的base64資料,也可以傳輸 canvas.toBlob() 的Blob資料:

// canvas轉為blob並上傳
canvas.toBlob(function (blob) {
    // 圖片ajax上傳
    var xhr = new XMLHttpRequest();
    // 檔案上傳成功
    xhr.onload = function() {
         // xhr.responseText就是返回的資料
    };
    // 開始上傳
    xhr.open("POST", 'upload.php', true);
    xhr.send(blob);    
}, 'image/jpeg');

三、我該如何在專案中使用?

上面的 demo頁面 中,我寫了個名為 cssRenderImage2PureImage() 的方法,可以把類似下面程式碼結構的CSS影像處理結果變成一張圖片:

<div id="input" class="clarendon-filter">
    <img src="./example.jpg">
</div>
.clarendon-filter {
    filter: contrast(1.2) saturate(1.35);
    display: inline-block;
    position: relative;
}
.clarendon-filter::before {
    content: '';
    display: block;
    height: 100%;
    width: 100%;
    top: 0; left: 0;
    position: absolute;
    background: rgba(127,187,227,.2);
    mix-blend-mode: overlay;
    pointer-events: none;
}

cssRenderImage2PureImage() 方法語法:

cssRenderImage2PureImage(dom, callback);

其中:

dom
必須引數。DOM物件。
callback
可選引數。Function。回撥方法,支援一個引數,為合成後的圖片的base64資訊。
示例:

cssRenderImage2PureImage(input, function (url) {
    // url就是合成後的圖片base64地址
    // 你可以對url做你任何你想做的事情……
});

四、其它說明以及結束語

  1. cssRenderImage2PureImage 方法高度定製,如果你的CSS濾鏡處理的DOM結構有所不同,你需要根據你的專案場景調整下 cssRenderImage2PureImage 方法裡面的程式碼;
  2. <foreignObject> 元素是著名的html2canvas工具的核心,通常一些小的區域性的截圖功能,我們直接自己擼十幾行程式碼處理下就好了,更高效更靈活。關於SVG的 <foreignObject> 元素,我之前專門寫過一個文章介紹過:“ SVG <foreignObject>簡介與截圖等應用 ”,想要深入瞭解實現原理的人可以看看。
  3. 此技術實現請在Chrome瀏覽器下玩耍。

本文所提供的解決方案和應用場景涉及到了CSS濾鏡和混合模式,SVG  <foreignObject> 元素,以及Canvas的影像繪製和處理技巧。幸好這3個領域是自己著重學習的領域,如果有哪一方面缺失,解決方案一定無法信手捏來。

我們究竟要學什麼東西,不是看這個東西到底熱不熱門,而是要看跟你想感興趣的領域是否相關,SVG和Canvas實際上屬於小眾領域,但都與圖形表現密切相關,因此,義無反顧學習,而且學習的時候不要只學熱門的API,一些不常用的特性,API也要面面俱到,例如SVG  <foreignObject> 元素就是個很不常用的SVG元素,但在這裡大放異彩,是技術實現的最關鍵部分。

自己是一個五年的前端工程師,希望本文對你有幫助!

這裡推薦一下我的前端學習交流扣qun:731771211 ,裡面都是學習前端的,如果你想製作酷炫的網頁,想學習程式設計。自己整理了一份2019最全面前端學習資料,從最基礎的HTML+CSS+JS【炫酷特效,遊戲,外掛封裝,設計模式】到移動端HTML5的專案實戰的學習資料都有整理,送給每一位前端小夥伴,每天分享技術


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69901074/viewspace-2645232/,如需轉載,請註明出處,否則將追究法律責任。

相關文章