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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/462105.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

python-在图片上标实心圆点

代码&#xff1a; from PIL import Image, ImageDraw# 打开图像 image_path path_to_your_image.jpg image Image.open(image_path)# 创建一个可以在上面绘图的对象 draw ImageDraw.Draw(image)# 设置圆点的坐标和颜色 x 100 # 圆点的x坐标 y 100 # 圆点的y坐标 color …

【JVM】GCRoot

GC root原理 通过对枚举GCroot对象做引用可达性分析&#xff0c;即从GC root对象开始&#xff0c;向下搜索&#xff0c;形成的路径称之为 引用链。如果一个对象到GC roots对象没有任何引用&#xff0c;没有形成引用链&#xff0c;那么该对象等待GC回收。 可以作为GC Roots的对…

Vue命令式组件的编写与应用

目录 1.引言 2.传统的组件 3.命令式组件 4.命令式组件的应用场景 1.引言 大家好&#xff01;今天我们来聊聊Vue.js中的一个有趣话题——命令式组件。你有没有觉得&#xff0c;有时候我们在Vue模板里写组件&#xff0c;就像是在玩搭积木&#xff0c;每个积木都有固定的形状…

第二百零六回

文章目录 1. 概念介绍2. 思路与方法2.1 实现思路2.2 实现方法 3. 示例代码4. 内容总结 我们在上一章回中介绍了"给geolocator插件提交问题的结果"相关的内容&#xff0c;本章回中将介绍自定义标题栏.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 我…

set与zset数据类型

set类型基础 redis集合(set)类型和list列表类型类似&#xff0c;都可以用来存储多个字符串元素的 集合。但是和list不同的是set集合当中不允许重复的元素。而且set集合当中元素是没有顺序的&#xff0c;不存在元素下标。 redis的set类型是使用哈希表构造的&#xff0c;因此复…

Java面向对象案例之描述专业和学生(4)

类的方法图 学生类&#xff1a; 属性&#xff1a;学号&#xff0c;姓名&#xff0c;年龄&#xff0c;所学习的专业方法&#xff1a;学习的方法&#xff0c;描述学习状态。描述内容包括姓名、学号、年龄、所学习的专业信息 专业类&#xff1a; 属性&#xff1a;专业编号&#xf…

阅读 - 二维码扫码登录原理

在日常生活中&#xff0c;二维码出现在很多场景&#xff0c;比如超市支付、系统登录、应用下载等等。了解二维码的原理&#xff0c;可以为技术人员在技术选型时提供新的思路。对于非技术人员呢&#xff0c;除了解惑&#xff0c;还可以引导他更好地辨别生活中遇到的各种二维码&a…

线性回归 quickstart

构建一元一次方程 100个&#xff08;X, y &#xff09;&#xff0c;大概是’y3x4’ import numpy as npnp.random.seed(42) # to make this code example reproducible m 100 # number of instances X 2 * np.random.rand(m, 1) # column vector y 4 3 * X np.random…

深度揭秘HW中的灰色技术(盗号,个人实时定位,远程监听)

xss漏洞&#xff1a;是数量最多的漏洞 cross-site scripting 跨站脚本攻击 1.反射型xss&#xff1a;代码存在于网址中&#xff0c;将存在恶意代码的链接发给用户&#xff0c;点击后才能攻击成功实施。 2.存储型xss&#xff1a;指Web应用程序会将用户输入的数据信息保持在服务…

2024批量下载微博内容导出excel,数据包含微博链接,内容,点赞数,转发数,评论数,话题等

以歌手李健这个号为例&#xff0c;共抓取727条微博&#xff0c;导出的excel微博数据包含微博链接,微博正文,原始图片链接,被转发微博原始图片链接,是否为原创微博,微博视频链接,发布位置,发布时间,发布工具,点赞数,转发数,评论数,话题等。 第一条微博发布于2010年5月31 。 再根…

电机参数辨识算法(2)——基于高频注入的磁链辨识策略

电机参数辨识算法&#xff08;1&#xff09;——基于高频注入的电感辨识策略-CSDN博客https://blog.csdn.net/m0_46903653/article/details/136722750?spm1001.2014.3001.5501上一期已经讲过了电感辨识方法。 今天这是参数辨识的第二期&#xff0c;今天来简单看看磁链的辨识。…

(六)Android布局类型(表格布局TableLayout)

表格布局&#xff08;TableLayout&#xff09;&#xff0c;呈现行列方式&#xff0c;无法设置列&#xff0c;可以设置行&#xff0c;行数由TableRow对象个数决定。下图中有两个TableRow元素&#xff0c;所以&#xff0c;说明表格布局中有两行。 将内容填充到行中 第一行中&…

【ollama】(7):使用Nvidia Jetson Nano设备,成功运行ollama,运行qwen:0.5b-chat,速度还可以,可以做创新项目了

1&#xff0c;视频地址 https://www.bilibili.com/video/BV1Pj421o7W5/ 【ollama】&#xff08;7&#xff09;&#xff1a;使用Nvidia Jetson Nano设备&#xff0c;成功运行ollama&#xff0c;运行qwen:0.5b-chat&#xff0c;速度还可以&#xff0c;可以做创新项目了 2&#x…

【NC223888】红色和紫色

题目 红色和紫色 博弈论&#xff0c;想得出来思路就简单&#xff0c;想不出来就难。一般使用猜测法。 思路 如果小红随意取一个格子涂色&#xff0c;那么小紫怎么涂色才是她的最优选择呢&#xff1f; 假设小紫只能选择小红涂色的格子的相邻格子或者是最近斜对角的一个格子涂色…

浅易理解:卷积神经网络(CNN)

浅易理解卷积神经网络流程 本文的目录&#xff1a; 1 什么卷积神经网络 2 输入层 3 卷积层 4 池化层 5 全连接层 传统的多层神经网络只有 输入层、隐藏层、输出层 卷积神经网络&#xff08;CNN)&#xff1a; 在多层神经网络的基础上&#xff0c;加入了更加有效的特征学习部分…

JavaScript 基础知识

一、初识 JavaScript 1、JS 初体验 JS 有3种书写位置&#xff0c;分别为行内、内部和外部。 示例&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"wid…

CASA模型在陆地生态系统碳循环研究中的应用探讨

植被&#xff0c;作为陆地生态系统的重要基石&#xff0c;对维护生态环境功能具有不可替代的作用。其中&#xff0c;植被净初级生产力&#xff08;NPP&#xff09;是衡量植被生态系统健康与功能的关键指标。它反映了单位面积上绿色植被通过光合作用生产的有机质总量在扣除自养呼…

软件测试面试都问了什么?中级软件测试岗面试(4面)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 一面&#xff08;…

瑞熙贝通实验室安全培训考试系统

一、系统概述 瑞熙贝通实验室安全培训考试系统是一种基于互联网和人工智能技术的在线考试平台&#xff0c;旨在旨在提供实验室安全教育和考核的全面解决方案。该系统可以帮助实现实验室安全培训考试的在线化、智能化和规范化&#xff0c;提高实验室安全意识和能力&#xff0c;…

Arduino平台软硬件原理及使用——色环电阻及贴片电阻的阻值识别

文章目录 一、四色环电阻及其阻值识别 二、五色环、六色环电阻及其阻值识别 三、三位数字及四位数字编码的贴片电阻及其阻值识别 四、E96编码的贴片电阻及其阻值识别 一、四色环电阻及其阻值识别 如上图为四色环电阻的实物图&#xff0c;图中左侧的三道环间距一致&#xff0c;第…