vue3中使用组件tui-image-editor进行图片处理

时间:2025-02-16 19:02:44
<template> <el-dialog :title="title" :modelValue="dialogVisible" :show-close="true" :close-on-click-modal="false" :close-on-press-escape="false" :before-close="closeDialog" destroy-on-close width="60%" > <div class="drawing-container"> <!-- 绘图组件容器DOM --> <div id="tui-image-editor"></div> <el-button class="save" type="primary" @click="save">保存</el-button> </div> </el-dialog> </template> <script setup> import 'tui-image-editor/dist/' import 'tui-color-picker/dist/' import ImageEditor from 'tui-image-editor' import { importNewImg } from "@/api/back/"; import { uploadAvatar } from "@/api/system/user"; // 中文菜单 const locale_zh = { ZoomIn: '放大', ZoomOut: '缩小', Hand: '手掌', History: '历史', Resize: '调整宽高', 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: '混合色', Width: '宽度', Height: '高度', 'Lock Aspect Ratio': '锁定宽高比例' } // 画布组件自定义样式 const customTheme = { "": "", // 左上角logo图片 "": "0px", "": "0px", "": "none", "": "#f3f4f6", "": "1px solid #333", // header "": "none", "": "#f3f4f6", "": "0px", // load button "": "#fff", "": "1px solid #ddd", "": "#222", "": "NotoSans, sans-serif", "": "12px", "": "none", // 可以直接隐藏掉 // download button "": "#fdba3b", "": "1px solid #fdba3b", "": "#fff", "": "NotoSans, sans-serif", "": "12px", "": "none", // 可以直接隐藏掉 // icons default "": "#8a8a8a", "": "#555555", "": "#ccc", "": "#e9e9e9", "": "#8a8a8a", "": "#e9e9e9", "": "24px", "": "24px", "": "32px", "": "32px", // submenu primary color "": "#1e1e1e", "": "#858585", // submenu labels "": "#858585", "": "lighter", "": "#fff", "": "lighter", // checkbox style "": "1px solid #ccc", "": "#fff", // rango style "": "#fff", "": "#666", "": "#d1d1d1", "": "#414141", "": "#282828", "": "#414141", "": "#fff", "": "lighter", "": "11px", "": "1px solid #353535", "": "#151515", "": "#fff", "": "lighter", // colorpicker style "": "1px solid #1e1e1e", "": "#fff", }; // props const props = defineProps({ dialogVisible: { type: Boolean, default: () => { return false; }, }, title: { type: String, default: "", }, imgUrl: { type: String, default: "", }, }); const emit = defineEmits() const instance = ref(null) onMounted(() => { nextTick(() => { init() // 页面创建完成后调用 }) }) // 关闭弹框 const closeDialog = ()=> { emit('closeCropperDialog') // = '' } const init = ()=> { instance.value = new ImageEditor(document.querySelector('#tui-image-editor'), { includeUI: { loadImage: { path: props.imgUrl, name: 'image' }, menu: ['resize', 'crop', 'rotate', 'draw', 'shape', 'icon', 'text', 'filter'], // 底部菜单按钮列表 隐藏镜像flip和遮罩mask initMenu: 'draw', // 默认打开的菜单项 menuBarPosition: 'bottom', // 菜单所在的位置 locale: locale_zh, // 本地化语言为中文 theme: customTheme // 自定义样式 }, cssMaxWidth: 400, // canvas 最大宽度 cssMaxHeight: 500 // canvas 最大高度 }) document.getElementsByClassName('tui-image-editor-main')[0].style.top = '45px' // 调整图片显示位置 document.getElementsByClassName( 'tie-btn-reset tui-image-editor-item help' )[0].style.display = 'none' // 隐藏顶部重置按钮 } // 保存图片,并上传 const save = ()=> { const base64String = instance.value.toDataURL() // base64 文件 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' }) // blob 文件 const form = new FormData() form.append("avatarfile", blob); uploadAvatar(form).then(res=>{ emit('getNewImg',res.imgUrl); closeDialog() }) } </script> <style lang="scss" scoped> .drawing-container { width: 100%; height: 80vh; position: relative; .save { position: absolute; right: 50px; top: 15px; } } </style>

相关文章