Use React to build a web app: simple image editor (part 2)

Tobby Kuo
6 min readJan 31, 2019

--

第二篇主要會講其中的一些功能我是怎麼實作的,如果要看實作之前我是怎麼考慮的可以看第一篇

原始碼的部分我放在這:https://github.com/tobby168/image-editor-by-react

React元件架構

<app_background>
<nav_bar/>
<process_bar/>
<preview_container>
<hidden_image/>
<hidden_logo/>
<canvas>
<fake_text/>
</canvas>
<file_input/>
</preview_container>
<text_container/>
<img_container/>
</app_background>

一開始隱藏而沒有顯示在畫面中的有<process_bar/>、<hidden_image/>、<hidden_logo/>、<img_container/>,兩個hidden的元件中,image是預覽時先繪製的縮小比例圖片,而logo則是為了要在最後繪製前先把logo的靜態檔案讀入。

/

/

/

/

Canvas繪製

  1. 等比例縮放後繪製預覽圖片
document.getElementById('image_show').width=preview.width;document.getElementById('image_show').height=preview.height;previewSize = preview.width;const radio = preview.width / 960;const ctx = document.getElementById('image_show').getContext('2d');ctx.drawImage(preview, 0, 0, preview.width, preview.height);

將圖片縮小後放入長寬960px的canvas中,其中的ratio就是圖片的縮放比例,之後要繪製真正的圖片時會再用到。

2.繪製logo及標題到正確位置:

event.emit('process_start');document.getElementById('fake_text_shadow').style.display = 'none';document.getElementById('fake_text').style.display = 'none';var previewLogo = document.getElementById('hidden_logo');ctx.drawImage(previewLogo, 0, 0, previewLogo.width, previewLogo.height, 800 * radio, 20 * radio, 140 * radio, 140 * radio);

在960 * 960的圖片中,我希望logo的位置在800, 20,並且長寬為140,因此在繪製時要乘上上面的縮放比例。

而標題字的位置則是用jQuery去抓<fake_text/>的top以及left值後,換算過後繪製。

3.將繪製完成圖檔轉成base64:

var dataURL = canvas.toDataURL();document.getElementById('canvas_to_img').src = dataURL;

畫完的canvas可以用toDataURL()方法來轉成dataURL,可以用src=dataURL的方式引入圖檔,讓使用者下載。

繪製進度條

event.emit('process_start');

在每個繪製步驟開始前,會發出這樣的事件,觸發繪製以及讓進度條跑到下一個檢查點,進度條前進的速度是亂數增加的,只有檢查點才是真的😂。

const interval = setInterval(()=>{
const process = this.state.process + Math.floor(Math.random()*3);
if(process < 25){
this.setState({process});
}else{
this.setState({process: 25});
clearInterval(interval);
}
},40);

架站以及Cache

這次選擇將工具放在firebase上,因為我覺得用firebase部署靜態網站很方便,只要安裝好firebase-tools並且init後,輸入firebase deploy就可以部署新的檔案上去,而且它也有提供現成的ssl服務。

而之前提到把字型放進Cache則是需要再firebase.json中做設定,像這樣:

{
"hosting": {
"public": "dist",
"headers": [ {
"source" : "**/*.@(png|otf|css)",
"headers" : [ {
"key" : "Cache-Control",
"value" : "max-age=800000"
} ]
}]
}
}

未來功能

關於這個圖片編輯器,未來想要實現的功能大概有兩個方向:

  1. 更多圖片編輯功能:在查詢canvas繪製圖片的同時,也有看到一些資料是可以調整圖片的參數的(曝光、對比、灰階⋯⋯),雖然我們團隊有統一使用foodie這個手機app修圖,但選用foodie的原因無非是為了色調的統一以及其內建適合食物的濾鏡,但foodie輸出後都有噪點變多、解析度變差的問題,所以如果能夠在這個圖片編輯器內加入參數調整已經風格一致的濾鏡,想必可以部分地提升圖片品質。
  2. 自動化編輯:在尋找資料的過程中,也同時看到了Google Cloud Vision的API,這個API的功能非常強大,不僅能夠辨識物體、也能統計顏色出現的比率,若給它充足的訓練之後,甚至能夠做出裁切圖片等操作。之後不知道能不能用這個服務來實現自動找出最佳的標題字位置之類的。

--

--

Tobby Kuo

Microsoft Software Engineer, focus on infrastructure developments for big data in distributed environments.