一款功能極其強大的圖檔編輯插件 tui.image-editor
快速體驗
- 首選在你的前端項目中安裝:
npm i tui-image-editor
// or
yarn add tui-image-editor
- 現在你就去建立一個
檔案,複制進去下面這段代碼:.vue
<template>
<div id="tui-image-editor"></div>
</template>
<script>
import "tui-image-editor/dist/tui-image-editor.css";
import "tui-color-picker/dist/tui-color-picker.css";
const ImageEditor = require("tui-image-editor");
export default {
data() {
return {
instance: null,
}
},
mounted() {
this.instance = new ImageEditor(
document.querySelector("#tui-image-editor"),
{
includeUI: {
loadImage: {
path: "https://uploadbeta.com/api/pictures/random/",
name: "image"
},
initMenu: "draw",
menuBarPosition: "bottom"
},
}
);
}
}
</script>
預設效果:

國際化:
工具中的描述預設都是英文的我們先把這部分漢化一下:
// 将原有的代碼改為這樣
<template>
<div id="tui-image-editor"></div>
</template>
<script>
import "tui-image-editor/dist/tui-image-editor.css";
import "tui-color-picker/dist/tui-color-picker.css";
const ImageEditor = require("tui-image-editor");
const locale_zh = {
// override default English locale to your custom
Crop: "裁剪",
DeleteAll: "全部删除",
Delete: "删除",
Undo: "撤銷",
Redo: "反撤銷",
Reset: "重置",
Flip: "鏡像",
Rotate: "旋轉",
Draw: "畫",
Shape: "形狀标注",
Icon: "圖示标注",
Text: "文字标注",
Mask: "遮罩",
Filter: "濾鏡",
Bold: "加粗",
Italic: "斜體",
Underline: "下劃線",
Left: "左對齊",
Center: "居中",
Right: "右對齊",
Color: "顔色",
"Text size": "字型大小",
Custom: "自定義",
Square: "正方形",
Apply: "應用",
Cancel: "取消",
"Flip X": "X 軸",
"Flip Y": "Y 軸",
Range: "區間",
Stroke: "描邊",
Fill: "填充",
Circle: "圓",
Triangle: "三角",
Rectangle: "矩形",
Free: "曲線",
Straight: "直線",
Arrow: "箭頭",
"Arrow-2": "箭頭2",
"Arrow-3": "箭頭3",
"Star-1": "星星1",
"Star-2": "星星2",
Polygon: "多邊形",
Location: "定位",
Heart: "心形",
Bubble: "氣泡",
"Custom icon": "自定義圖示",
"Load Mask Image": "加載蒙層圖檔",
Grayscale: "灰階",
Blur: "模糊",
Sharpen: "銳化",
Emboss: "浮雕",
"Remove White": "除去白色",
Distance: "距離",
Brightness: "亮度",
Noise: "噪音",
"Color Filter": "彩色濾鏡",
Sepia: "棕色",
Sepia2: "棕色2",
Invert: "負片",
Pixelate: "像素化",
Threshold: "門檻值",
Tint: "色調",
Multiply: "正片疊底",
Blend: "混合色"
// etc...
};
export default {
data() {
return {
instance: null,
}
},
mounted() {
this.instance = new ImageEditor(
document.querySelector("#tui-image-editor"),
{
includeUI: {
loadImage: {
path: "https://uploadbeta.com/api/pictures/random/",
name: "image"
},
initMenu: "draw",
menuBarPosition: "bottom",
locale: locale_zh // 本地化語言為中文
},
}
);
}
}
</script>
漢化後
這時候你會發現你可能不需要右上角的
Load
和
Download
和左上角這個預設的
logo
,我們可以通過自定義主題将這部分改掉:
修改上面的代碼為:
<template>
<div id="tui-image-editor"></div>
</template>
<script>
import "tui-image-editor/dist/tui-image-editor.css";
import "tui-color-picker/dist/tui-color-picker.css";
const ImageEditor = require("tui-image-editor");
const locale_zh = {
// override default English locale to your custom
Crop: "裁剪",
DeleteAll: "全部删除",
Delete: "删除",
Undo: "撤銷",
Redo: "反撤銷",
Reset: "重置",
Flip: "鏡像",
Rotate: "旋轉",
Draw: "畫",
Shape: "形狀标注",
Icon: "圖示标注",
Text: "文字标注",
Mask: "遮罩",
Filter: "濾鏡",
Bold: "加粗",
Italic: "斜體",
Underline: "下劃線",
Left: "左對齊",
Center: "居中",
Right: "右對齊",
Color: "顔色",
"Text size": "字型大小",
Custom: "自定義",
Square: "正方形",
Apply: "應用",
Cancel: "取消",
"Flip X": "X 軸",
"Flip Y": "Y 軸",
Range: "區間",
Stroke: "描邊",
Fill: "填充",
Circle: "圓",
Triangle: "三角",
Rectangle: "矩形",
Free: "曲線",
Straight: "直線",
Arrow: "箭頭",
"Arrow-2": "箭頭2",
"Arrow-3": "箭頭3",
"Star-1": "星星1",
"Star-2": "星星2",
Polygon: "多邊形",
Location: "定位",
Heart: "心形",
Bubble: "氣泡",
"Custom icon": "自定義圖示",
"Load Mask Image": "加載蒙層圖檔",
Grayscale: "灰階",
Blur: "模糊",
Sharpen: "銳化",
Emboss: "浮雕",
"Remove White": "除去白色",
Distance: "距離",
Brightness: "亮度",
Noise: "噪音",
"Color Filter": "彩色濾鏡",
Sepia: "棕色",
Sepia2: "棕色2",
Invert: "負片",
Pixelate: "像素化",
Threshold: "門檻值",
Tint: "色調",
Multiply: "正片疊底",
Blend: "混合色"
// etc...
};
const customTheme = {
// image 坐上角度圖檔
"common.bi.image": "", // 在這裡換上你喜歡的logo圖檔
"common.bisize.width": "0px",
"common.bisize.height": "0px",
"common.backgroundImage": "none",
"common.backgroundColor": "#f3f4f6",
"common.border": "1px solid #444",
// header
"header.backgroundImage": "none",
"header.backgroundColor": "#f3f4f6",
"header.border": "0px",
// load button
"loadButton.backgroundColor": "#fff",
"loadButton.border": "1px solid #ddd",
"loadButton.color": "#222",
"loadButton.fontFamily": "NotoSans, sans-serif",
"loadButton.fontSize": "12px",
"loadButton.display": "none", // 可以直接隐藏掉
// download button
"downloadButton.backgroundColor": "#fdba3b",
"downloadButton.border": "1px solid #fdba3b",
"downloadButton.color": "#fff",
"downloadButton.fontFamily": "NotoSans, sans-serif",
"downloadButton.fontSize": "12px",
"downloadButton.display": "none", // 可以直接隐藏掉
// icons default
"menu.normalIcon.color": "#8a8a8a",
"menu.activeIcon.color": "#555555",
"menu.disabledIcon.color": "#434343",
"menu.hoverIcon.color": "#e9e9e9",
"submenu.normalIcon.color": "#8a8a8a",
"submenu.activeIcon.color": "#e9e9e9",
"menu.iconSize.width": "24px",
"menu.iconSize.height": "24px",
"submenu.iconSize.width": "32px",
"submenu.iconSize.height": "32px",
// submenu primary color
"submenu.backgroundColor": "#1e1e1e",
"submenu.partition.color": "#858585",
// submenu labels
"submenu.normalLabel.color": "#858585",
"submenu.normalLabel.fontWeight": "lighter",
"submenu.activeLabel.color": "#fff",
"submenu.activeLabel.fontWeight": "lighter",
// checkbox style
"checkbox.border": "1px solid #ccc",
"checkbox.backgroundColor": "#fff",
// rango style
"range.pointer.color": "#fff",
"range.bar.color": "#666",
"range.subbar.color": "#d1d1d1",
"range.disabledPointer.color": "#414141",
"range.disabledBar.color": "#282828",
"range.disabledSubbar.color": "#414141",
"range.value.color": "#fff",
"range.value.fontWeight": "lighter",
"range.value.fontSize": "11px",
"range.value.border": "1px solid #353535",
"range.value.backgroundColor": "#151515",
"range.title.color": "#fff",
"range.title.fontWeight": "lighter",
// colorpicker style
"colorpicker.button.border": "1px solid #1e1e1e",
"colorpicker.title.color": "#fff"
};
export default {
data() {
return {
instance: null,
}
},
mounted() {
this.instance = new ImageEditor(
document.querySelector("#tui-image-editor"),
{
includeUI: {
loadImage: {
path: "https://uploadbeta.com/api/pictures/random/",
name: "image"
},
initMenu: "draw",
menuBarPosition: "bottom",
locale: locale_zh,
theme: customTheme, // 自定義主題
},
}
);
}
}
</script>
自定義樣式效果
我們将上面的預設圖檔,
Load
和
Download
按鈕去掉了,但是會發現上面存在了一條白色的,這就浪費了我們編輯圖檔的空間,我們繼續優化:
// 通過在主題中改變樣式隐藏掉我們不需要的header
const customTheme = {
// image 坐上角度圖檔
"common.bi.image": "", // 在這裡換上你喜歡的logo圖檔
"common.bisize.width": "0px",
"common.bisize.height": "0px",
"common.backgroundImage": "none",
"common.backgroundColor": "#f3f4f6",
"common.border": "1px solid #444",
// header
"header.backgroundImage": "none",
"header.backgroundColor": "#f3f4f6",
"header.border": "0px",
"header.display": "none", // 隐藏我們的header
// load button
"loadButton.backgroundColor": "#fff",
"loadButton.border": "1px solid #ddd",
"loadButton.color": "#222",
"loadButton.fontFamily": "NotoSans, sans-serif",
"loadButton.fontSize": "12px",
"loadButton.display": "none", // 可以直接隐藏掉
// download button
"downloadButton.backgroundColor": "#fdba3b",
"downloadButton.border": "1px solid #fdba3b",
"downloadButton.color": "#fff",
"downloadButton.fontFamily": "NotoSans, sans-serif",
"downloadButton.fontSize": "12px",
"downloadButton.display": "none", // 可以直接隐藏掉
// icons default
"menu.normalIcon.color": "#8a8a8a",
"menu.activeIcon.color": "#555555",
"menu.disabledIcon.color": "#434343",
"menu.hoverIcon.color": "#e9e9e9",
"submenu.normalIcon.color": "#8a8a8a",
"submenu.activeIcon.color": "#e9e9e9",
"menu.iconSize.width": "24px",
"menu.iconSize.height": "24px",
"submenu.iconSize.width": "32px",
"submenu.iconSize.height": "32px",
// submenu primary color
"submenu.backgroundColor": "#1e1e1e",
"submenu.partition.color": "#858585",
// submenu labels
"submenu.normalLabel.color": "#858585",
"submenu.normalLabel.fontWeight": "lighter",
"submenu.activeLabel.color": "#fff",
"submenu.activeLabel.fontWeight": "lighter",
// checkbox style
"checkbox.border": "1px solid #ccc",
"checkbox.backgroundColor": "#fff",
// rango style
"range.pointer.color": "#fff",
"range.bar.color": "#666",
"range.subbar.color": "#d1d1d1",
"range.disabledPointer.color": "#414141",
"range.disabledBar.color": "#282828",
"range.disabledSubbar.color": "#414141",
"range.value.color": "#fff",
"range.value.fontWeight": "lighter",
"range.value.fontSize": "11px",
"range.value.border": "1px solid #353535",
"range.value.backgroundColor": "#151515",
"range.title.color": "#fff",
"range.title.fontWeight": "lighter",
// colorpicker style
"colorpicker.button.border": "1px solid #1e1e1e",
"colorpicker.title.color": "#fff"
};
但是發現還是沒有隐藏掉,需要我們對樣式進行修改
// ...
document.getElementsByClassName("tui-image-editor-main")[0].style.top = 0;
下一步我們要拿到編輯後的圖檔了:
這個插件提供了一個
toDataURL
的方法,可以将我們編輯後的圖檔轉為
base64
,然後我們可以通過轉為
form
表單上傳到我們的伺服器,或者轉為圖檔,這裡提供一份上傳到背景的邏輯:
// ...
methods: {
uploadImg() {
const base64String = this.instance.toDataURL();
const data = window.atob(base64String.split(",")[1]);
const ia = new Uint8Array(data.length);
for (let i = 0; i < data.length; i++) {
ia[i] = data.charCodeAt(i);
}
const blob = new Blob([ia], { type: "image/png" });
const fd = new FormData();
fd.append("image", blob);
// upload fd
}
}
最後,放上一段完整的代碼:
<template>
<div class="container">
<div id="tui-image-editor"></div>
<button @click="uploadImg">完成并上傳</button>
</div>
</template>
<script>
import "tui-image-editor/dist/tui-image-editor.css";
import "tui-color-picker/dist/tui-color-picker.css";
const ImageEditor = require("tui-image-editor");
const locale_zh = {
// override default English locale to your custom
Crop: "裁剪",
DeleteAll: "全部删除",
Delete: "删除",
Undo: "撤銷",
Redo: "反撤銷",
Reset: "重置",
Flip: "鏡像",
Rotate: "旋轉",
Draw: "畫",
Shape: "形狀标注",
Icon: "圖示标注",
Text: "文字标注",
Mask: "遮罩",
Filter: "濾鏡",
Bold: "加粗",
Italic: "斜體",
Underline: "下劃線",
Left: "左對齊",
Center: "居中",
Right: "右對齊",
Color: "顔色",
"Text size": "字型大小",
Custom: "自定義",
Square: "正方形",
Apply: "應用",
Cancel: "取消",
"Flip X": "X 軸",
"Flip Y": "Y 軸",
Range: "區間",
Stroke: "描邊",
Fill: "填充",
Circle: "圓",
Triangle: "三角",
Rectangle: "矩形",
Free: "曲線",
Straight: "直線",
Arrow: "箭頭",
"Arrow-2": "箭頭2",
"Arrow-3": "箭頭3",
"Star-1": "星星1",
"Star-2": "星星2",
Polygon: "多邊形",
Location: "定位",
Heart: "心形",
Bubble: "氣泡",
"Custom icon": "自定義圖示",
"Load Mask Image": "加載蒙層圖檔",
Grayscale: "灰階",
Blur: "模糊",
Sharpen: "銳化",
Emboss: "浮雕",
"Remove White": "除去白色",
Distance: "距離",
Brightness: "亮度",
Noise: "噪音",
"Color Filter": "彩色濾鏡",
Sepia: "棕色",
Sepia2: "棕色2",
Invert: "負片",
Pixelate: "像素化",
Threshold: "門檻值",
Tint: "色調",
Multiply: "正片疊底",
Blend: "混合色",
// etc...
};
const customTheme = {
// image 坐上角度圖檔
"common.bi.image": "https://uploadbeta.com/api/pictures/random/", // 在這裡換上你喜歡的logo圖檔
"common.bisize.width": "0px",
"common.bisize.height": "0px",
"common.backgroundImage": "none",
"common.backgroundColor": "#f3f4f6",
"common.border": "1px solid #444",
// header
"header.backgroundImage": "none",
"header.backgroundColor": "#f3f4f6",
"header.border": "0px",
"header.display": "none",
// load button
"loadButton.backgroundColor": "#fff",
"loadButton.border": "1px solid #ddd",
"loadButton.color": "#222",
"loadButton.fontFamily": "NotoSans, sans-serif",
"loadButton.fontSize": "12px",
"loadButton.display": "none", // 可以直接隐藏掉
// download button
"downloadButton.backgroundColor": "#fdba3b",
"downloadButton.border": "1px solid #fdba3b",
"downloadButton.color": "#fff",
"downloadButton.fontFamily": "NotoSans, sans-serif",
"downloadButton.fontSize": "12px",
"downloadButton.display": "none", // 可以直接隐藏掉
// icons default
"menu.normalIcon.color": "#8a8a8a",
"menu.activeIcon.color": "#555555",
"menu.disabledIcon.color": "#434343",
"menu.hoverIcon.color": "#e9e9e9",
"submenu.normalIcon.color": "#8a8a8a",
"submenu.activeIcon.color": "#e9e9e9",
"menu.iconSize.width": "24px",
"menu.iconSize.height": "24px",
"submenu.iconSize.width": "32px",
"submenu.iconSize.height": "32px",
// submenu primary color
"submenu.backgroundColor": "#1e1e1e",
"submenu.partition.color": "#858585",
// submenu labels
"submenu.normalLabel.color": "#858585",
"submenu.normalLabel.fontWeight": "lighter",
"submenu.activeLabel.color": "#fff",
"submenu.activeLabel.fontWeight": "lighter",
// checkbox style
"checkbox.border": "1px solid #ccc",
"checkbox.backgroundColor": "#fff",
// rango style
"range.pointer.color": "#fff",
"range.bar.color": "#666",
"range.subbar.color": "#d1d1d1",
"range.disabledPointer.color": "#414141",
"range.disabledBar.color": "#282828",
"range.disabledSubbar.color": "#414141",
"range.value.color": "#fff",
"range.value.fontWeight": "lighter",
"range.value.fontSize": "11px",
"range.value.border": "1px solid #353535",
"range.value.backgroundColor": "#151515",
"range.title.color": "#fff",
"range.title.fontWeight": "lighter",
// colorpicker style
"colorpicker.button.border": "1px solid #1e1e1e",
"colorpicker.title.color": "#fff",
};
export default {
data() {
return {
instance: null,
};
},
mounted() {
this.instance = new ImageEditor(
document.querySelector("#tui-image-editor"),
{
includeUI: {
loadImage: {
path: "https://uploadbeta.com/api/pictures/random/",
name: "image",
},
initMenu: "draw",
menuBarPosition: "bottom",
locale: locale_zh,
theme: customTheme,
},
}
);
document.getElementsByClassName("tui-image-editor-main")[0].style.top = 0;
},
methods: {
uploadImg() {
const base64String = this.instance.toDataURL();
const data = window.atob(base64String.split(",")[1]);
const ia = new Uint8Array(data.length);
for (let i = 0; i < data.length; i++) {
ia[i] = data.charCodeAt(i);
}
const blob = new Blob([ia], { type: "image/png" });
const fd = new FormData();
fd.append("image", blob);
// upload fd
},
},
};
</script>
<style lang="css" scoped>
.container {
height: 95vh;
text-align: center;
}
</style>
最終效果,戰歌起!
最後
如果有什麼疑問或者使用中的其他問題可以在評論中讨論一下。