当前位置: 首页 > article >正文

使用tui-image-editor 图片编辑 标注图片

需求背景

鼠标悬浮在图片上 出现编辑按钮 点击编辑 对该图片进行编辑(输入文案、涂鸦、标记、裁剪等)

可以体验一下它线上编辑器

Image-editor | TOAST UI :: Make Your Web Delicious!

使用

  • 首先在你的前端项目中安装:
npm i tui-image-editor
// or
yarn add tui-image-editor

我是封装成一个单独的组件 使用的时候直接引入就行

  • 新建一个.vue文件
  • <template>
      <div class="container">
        <div id="tui-image-editor"></div>
        <div slot="footer" class="dialog-footer">
          <el-button size="mini" @click="close">取消</el-button>
          <el-button size="mini" type="primary" @click="uploadImg">完成并保存</el-button>
        </div>
      </div>
      <!-- <el-dialog append-to-body :visible.sync="editor" :before-close="closeFun" title="详情" top="0" width="95%">
        <div class="container">
          <div id="tui-image-editor"></div>
        </div>
        <span slot="footer" class="dialog-footer">
          <el-button size="mini">下载</el-button>
          <el-button size="mini">保存至服务器</el-button>
        </span>
      </el-dialog> -->
    </template>
    <script>
    import {getSubToken} from '@/api/index'
    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 localeZh = {
      // 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',
      '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 {
      props: ['editor', 'editImgUrl', 'editFile'],
      watch: {
        'editImgUrl': {
          deep: true,
          handler: function (newVal, oldVal) {
            console.log(newVal, oldVal, '000000000000000')
          }
        }
      },
      data () {
        return {
          instance: null
        };
      },
      mounted () {
        this.init()
      },
      methods: {
        init () {
          this.instance = new ImageEditor(
            document.querySelector('#tui-image-editor'),
            {
              includeUI: {
                loadImage: {
                  path: this.editImgUrl,
                  name: 'image'
                },
                initMenu: 'draw',
                menu: [
                  'crop', // 裁切
                  'draw', // 添加绘画
                  'text', // 添加文本
                  'rotate', // 旋转
                  'flip' // 翻转
                  // 'shape', // 添加形状
                  // 'icon', // 添加图标
                  // 'mask', // 添加覆盖
                  // 'filter' // 添加滤镜
                ],
                menuBarPosition: 'bottom',
                locale: localeZh,
                theme: customTheme,
                cssMaxWidth: 800,
                cssMaxHeight: 500
              }
            }
          );
          document.getElementsByClassName('tui-image-editor-main')[0].style.top = 0;
          // document.querySelector('[tooltip-content="ZoomIn"]').style.display = 'none' // 放大
          // document.querySelector('[tooltip-content="ZoomOut"]').style.display = 'none' // 缩小
          document.querySelector('[tooltip-content="Hand"]').style.display = 'none' // 拖动界面
          document.querySelector('[tooltip-content="History"]').style.display = 'none'
          document.querySelector('.tie-btn-deleteAll').style.display = 'none' // 清空
        },
        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' });
          var abc = new File([blob], this.editFile.fileName, {type: 'image/png', lastModified: Date.now()});
          const file = new FormData();
          console.log(abc)
          file.append('file', abc);
          // axios请求代码...
        },
        close () {
          this.$emit('close')
        }
      }
    };
    </script>
    
    <style lang="scss" scoped>
    .container {
      height: 100%;
      text-align: left;
    }
    .dialog-footer{
      position: absolute;
      bottom: 8px;
      right: 10px;
    }
    </style>
    

    默认的样式如下

说明:直接按照官方的 有很多东西是我们不需要的比如上面的logo 和右上角的按钮  可以通过自定义样式去掉 参考代码里的customTheme 还有官方的提示都是英文的 所以需要汉化 参考代码里的localeZh

调整完之后

引用组件

import tuiImageEditor from '../../tuiImageEditor';
components: { tuiImageEditor },
<el-dialog class="body" append-to-body :visible.sync="editor" :before-close="close" title="编辑" top="0" width="95%">
      <tui-image-editor ref="tuiImageEditor" :editor="editor" :editImgUrl='editImgUrl' :editFile="editFile"
        @close="close" @uploadImg="uploadImg"></tui-image-editor>
    </el-dialog>

有很多涉及传值的地方 可以根据自己项目的场景删掉或者替换

到这里就差不多可以了 说下我遇到的问题

1.刚开始的时候 我的悬浮气泡里文字样式错位 我自己重新安装了一下 就又好了 

2.我的需求是在弹窗内编辑 所以理所当然的是把这个编辑器放在弹窗里再装成组件之后 但是引入后 就报错 不知道啥原因 所以我就在引入组件的时候 用弹窗包起来 大家如果有知道原因的 欢迎评论区留言


http://www.kler.cn/a/272632.html

相关文章:

  • 把软件加入开机自启动
  • 鸿蒙Socket通信示例(TCP通信)
  • 柔若初春,留心新生儿嘴唇发白
  • 【每日算法】理论:常见AIGC模型; 刷题:力扣单调栈
  • 红帽rhce认证报名费用多少?rhcsa 红帽认证含金量高吗?
  • 亮点抢先看!4月16-17日,百度Create大会开设“AI公开课”,大咖带你打造赚钱工具
  • 鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:TextPicker)
  • OSPF协议全面学习笔记
  • 【ArcGIS 脚本工具】强制移动要素类,绕过空间参考不一致
  • JVM 相关知识点记录
  • Vue动态绑定Class与Style
  • Docker Mysql无root账户创建最高权限用户
  • opencv中的图像均值模糊—blur
  • 华为PixArt-α:高质量、低成本的文生图模型,训练时长只有SD 1.5的10.8%
  • 隐私和安全是首要考虑?Zoho ToDo的任务管理工具适合您
  • Nginx的日志怎么看,在哪看,access.log日志内容详解
  • Webpack 学习笔记
  • 在Linux/Ubuntu/Debian中使用lsof和fuser查看/解除文件占用
  • 数字电子技术实验(七)
  • 卷径计算(卷径检测开关+博途PLC SCL源代码)