图片编辑器tui-image-editor

news2024/11/18 3:50:09

提示:图片编辑器tui-image-editor

文章目录

  • 前言
  • 一、安装tui-image-editor
  • 二、新建components/ImageEditor.vue
  • 三、修改App.vue
  • 四、效果
  • 五、遇到问题 this.getResolve is not a function
  • 总结


前言

需求:图片编辑器tui-image-editor

一、安装tui-image-editor

npm install tui-image-editor --save

在这里插入图片描述

二、新建components/ImageEditor.vue

ImageEditor.vue

<template>
    <div class="image_editor_box" ref="dcRef">
      <div id="tui_image_editor"></div>
      <el-button class="image_save_btn" type="primary" size="small" @click="saveImage">保存</el-button>
    </div>
  </template>
  <script>
  import 'tui-image-editor/dist/tui-image-editor.css'
  import 'tui-color-picker/dist/tui-color-picker.css'
  import ImageEditor from 'tui-image-editor'
  const locale = {
    //菜单
    ZoomIn: '放大',
    ZoomOut: '缩小',
    Hand: '抓手工具',
    History: '历史',
    Undo: '撤销',
    Redo: '恢复',
    Reset: '重置',
    Delete: '删除',
    DeleteAll: '全部删除',
    //工具栏
    //尺寸调整
    Resize: '尺寸',
    Width: '宽度',
    Height: '高度',
    'Lock Aspect Ratio': '锁定宽高比例',
    Apply: '应用',
    Cancel: '取消',
    //镜像
    Flip: '镜像',
    'Flip X': 'X 轴',
    'Flip Y': 'Y 轴',
    //蒙版
    Mask: '蒙版',
    'Load Mask Image': '上传蒙版图片',
    //裁剪
    Crop: '裁剪',
    Square: '正方形',
    // 旋转
    Rotate: '旋转',
    Range: '区间',
    //画笔
    Draw: '画笔',
    Free: '曲线',
    Straight: '直线',
    Color: '颜色',
    //图形
    Shape: '图形',
    Rectangle: '矩形',
    Circle: '圆形',
    Triangle: '三角形',
    Fill: '填充',
    Stroke: '描边',
    //图标
    Icon: '图标',
    Arrow: '箭头',
    'Arrow-2': '箭头2',
    'Arrow-3': '箭头3',
    'Star-1': '五角星',
    'Star-2': '多角形',
    Polygon: '多边形',
    Location: '定位',
    Heart: '心形',
    Bubble: '气泡',
    'Custom icon': '自定义图标',
    //文字
    Text: '文字',
    Bold: '加粗',
    Italic: '斜体',
    Underline: '下划线',
    Left: '左对齐',
    Center: '居中',
    Right: '右对齐',
    'Text size': '字体大小',
    //滤镜
    Filter: '滤镜',
    Grayscale: '灰度',
    Sepia: '棕色',
    Blur: '模糊',
    Emboss: '浮雕',
    Invert: '底片',
    Sepia2: '棕色2',
    Sharpen: '锐化',
    'Remove White': '除去白色',
    Distance: '距离',
    Brightness: '亮度',
    Noise: '铜板雕刻',
    Pixelate: '马赛克',
    'Color Filter': '彩色滤镜',
    Threshold: '阈值',
    Tint: '色调',
    Multiply: '正片叠底',
    Blend: '混合色',
    Custom: '自定义',
    load: '上传',
    download:'下载',
  }  
  const IThemeConfig = {
  //图标
  'common.bi.image': 'https://t7.baidu.com/it/u=1595072465,3644073269&fm=193&f=GIF',
  'common.bisize.width': '30px',
  'common.bisize.height': '30px',
  //编辑器背景
  // 'common.backgroundImage': 'https://t7.baidu.com/it/u=1595072465,3644073269&fm=193&f=GIF',
  'common.backgroundColor': '#fff',
  'common.border': '1px solid #eee',

  // 菜单栏样式
  // 'header.backgroundImage': 'https://t7.baidu.com/it/u=1595072465,3644073269&fm=193&f=GIF',
  'header.backgroundColor': 'transparent',
  'header.border': '0 solid #000',

  // 上传按钮
  'loadButton.backgroundColor': '#ecf5ff',
  'loadButton.border': '1px solid #409EFF',
  'loadButton.color': '#409EFF',
  'loadButton.fontFamily': "'Noto Sans', sans-serif",
  'loadButton.fontSize': '12px',

  // 下载按钮
  'downloadButton.backgroundColor': '#409EFF',
  'downloadButton.border': '1px solid #409EFF',
  'downloadButton.color': '#fff',
  'downloadButton.fontFamily': "'Noto Sans', sans-serif",
  'downloadButton.fontSize': '12px',

  // 工具栏icon
  'menu.normalIcon.color': '#7A8799',
  'menu.activeIcon.color': '#409EFF',
  'menu.disabledIcon.color': '#A2AEBF',
  'menu.hoverIcon.color': '#323D4D',
  'menu.iconSize.width': '24px',
  'menu.iconSize.height': '24px',

  // 工具栏子菜单
  'submenu.normalIcon.color': '#7A8799',
  'submenu.activeIcon.color': '#323D4D',
  // 工具栏子菜单icon
  'submenu.iconSize.width': '24px',
  'submenu.iconSize.height': '24px',
  // 工具栏子菜单bg
  'submenu.backgroundColor': '#eee',
  // 工具栏子菜单分割线
  'submenu.partition.color': '#7A8799',
  //工具栏子菜单文字
  'submenu.normalLabel.color': '#7A8799',
  'submenu.normalLabel.fontWeight': '400',
  'submenu.activeLabel.color': '#323D4D',
  'submenu.activeLabel.fontWeight': '400',

  // 工具栏子菜单多选框
  'checkbox.border': '1px solid #7A8799',
  'checkbox.backgroundColor': '#fff',

  // 工具栏子菜单进度条--滑块
  'range.pointer.color': '#409EFF',
  // 工具栏子菜单进度条--底色
  'range.bar.color': '#A2AEBF',
  // 工具栏子菜单进度条--进度
  'range.subbar.color': '#409EFF',
  // 工具栏子菜单进度条--禁用
  'range.disabledPointer.color': '#A2AEBF',
  'range.disabledBar.color': '#A2AEBF',
  'range.disabledSubbar.color': '#7A8799',
  // 工具栏子菜单进度条--值
  'range.color': '#7A8799',
  'range.value.color': '#323D4D',
  'range.value.fontWeight': '400',
  'range.value.fontSize': '11px',
  'range.value.border': '1px solid #A2AEBF',
  'range.value.backgroundColor': '#fff',
  'range.title.fontWeight': '400',

  // 颜色选择器
  'colorpicker.button.border': '1px solid #A2AEBF',
  'colorpicker.title.color': '#7A8799',
};
  export default {
    props:{
        defaultImg:{
            type:Object,
            default:()=>{return {}},
        },
        defaultColorArr:{
            type:Array,
            default:()=>{return []},
        }
    },
    data() {
      return {
        imgEditor: null
      }
    },
    watch:{
        defaultImg(){
            this.imgEditor&&this.imgEditor.loadImageFromURL(this.defaultImg.path,this.defaultImg.name);
        }
    },
    mounted() {
        this.init(this.defaultImg);
    },
    methods: {
      //初始化ImageEditor
      init(defaultImg) {
        this.imgEditor = new ImageEditor(document.getElementById('tui_image_editor'), {
          includeUI: {
            //加载图片
            loadImage: { path:defaultImg.path, name: defaultImg.name },
            //尺寸  裁剪  旋转  画笔  图形  图标  文字  镜像  滤镜  蒙版
            menu: ['resize', 'crop', 'rotate', 'draw', 'shape', 'icon', 'text', 'flip', 'filter', 'mask'], //不初始化 filter mask
            // 默认工具
            initMenu: '',
            // 工具栏位置              
            menuBarPosition: 'bottom', 
            // 语言
            locale: locale,
            // 主题            
            theme: IThemeConfig        
          },
          // 最大宽度
          cssMaxWidth: (this.$refs.dcRef.clientWidth||1000)-80,
           // 最大高度
          cssMaxHeight: (this.$refs.dcRef.clientHeight||600)-64-48-80,
          uiSize: {
            width: '1000px',
            height: '700px'
          },
          selectionStyle: {
            cornerSize: 20,
            rotatingPointOffset: 70
          },
          picker:{}
        });
        //Load按钮文案改成上传
        const load = document.querySelector('.tui-image-editor-header-buttons>div');
        load.innerHTML = load.innerHTML.replace('Load','上传');
        //Download按钮文案改成下载
        const download = document.querySelector('.tui-image-editor-header-buttons .tui-image-editor-download-btn');
        download.innerHTML = "下载";
      },
      // 保存批注的图片
      saveImage() {
        let base64Str = this.imgEditor.toDataURL();
        let blob = this.base64ToBlob(base64Str);
        console.log(base64Str,blob);
        this.$emit('saveEditImgSrc',base64Str);
      },
      //base64转换成blob
      base64ToBlob(base64Str) {
        let arr = base64Str.split(",");
        let type = arr[0].match(/:(.*?);/)[1];
        let bstr = atob(arr[1]);
        let n = bstr.length;
        let u8arr = new Uint8Array(n);
        while (n--) {
            u8arr[n] = bstr.charCodeAt(n);
        }
        return new Blob([u8arr], { type });
      }
    }
  }
  </script>
  
  <style lang="scss" scoped>
  .image_editor_box {
    height: 100%;
    width: 100%;
    position: relative;
    .image_save_btn {
      position: absolute;
      width: 120px;
      height: 40px;
      right: 260px;
      top: 9px;
      background-color: #409EFF;
      border: 1px solid #409EFF;
      color: #fff;
      font-family: 'Noto Sans', sans-serif;
      font-size: 12px;
      border-radius: 40px;
    }
  }
  </style>
  <style>
    /** 隐藏图标和上传下载按钮 **/
    .image_editor_box .tui-image-editor-header-logo,.image_editor_box .tui-image-editor-header-buttons{
        /* display: none!important; */
    }
    /* 调整图片显示位置 */
    .image_editor_box .tui-image-editor-main{
        top:48px!important;
        height:auto!important;
    }
    .image_editor_box .tui-image-editor-container .tui-image-editor-range-wrap label{
      color: #7A8799;
    }
    .image_editor_box .tui-image-editor-container .tui-image-editor-checkbox label > span {
      color: #7A8799;
    }
    .image_editor_box .tui-image-editor-container .tui-image-editor-controls{
      background-color: #fcfcfc;
      border:1px solid #eee;
      border-top:0;
    }
    .image_editor_box .tui-image-editor-help-menu.top{
      border:1px solid #eee;
      background: #fcfcfc;
    }
    .image_editor_box .tie-filter-tint-color[title="色调"] .color-picker-control,
    .image_editor_box .tie-filter-blend-color[title="混合色"] .color-picker-control{
      height: 160px!important;
      left: -74px!important;
      top: -170px!important;
    }
  </style>
  

在这里插入图片描述

三、修改App.vue

App.vue

<template>
  <div id="app">
    <div class="img_mark_box">
      <div class="img_mark_l">
        <div class="img_mark_img" v-for="item,index in imgArr" :key="index" @click="changeImg(item)"><img :src="item.path" alt=""></div>
      </div>
      <div class="img_mark_m"><ImageEditor :defaultImg="activeImg" @saveEditImgSrc="saveEditImgSrc"></ImageEditor></div>
      <div class="img_mark_r"><img :src="editImgSrc" alt=""></div>
  </div>
  </div>
</template>

<script>
import ImageEditor from "./components/ImageEditor";
export default {
  name: 'App',
  components:{ImageEditor},
  data(){
    return {
      activeImg:'',
      editImgSrc:'',
      imgArr:[
        {
          path:require('@/assets/test.jpg'),
          name:'图片1'
        },
        {
          path:`data:image/jpeg;base64,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`,
          name:'图片2'
        },
        {
          path:'https://t7.baidu.com/it/u=1819248061,230866778&fm=193&f=GIF',
          name:'图片3'
        },
        {
          path:'https://t7.baidu.com/it/u=1595072465,3644073269&fm=193&f=GIF',
          name:'图片4'
        },
        {
          path:'https://t7.baidu.com/it/u=825057118,3516313570&fm=193&f=GIF',
          name:'图片5'
        },
        {
          path:'https://t7.baidu.com/it/u=602106375,407124525&fm=193&f=GIF',
          name:'图片6'
        },
        {
          path:'https://t7.baidu.com/it/u=55748064,2074988836&fm=193&f=GIF',
          name:'图片7'
        },
      ],
    }
  },
  created(){
    this.activeImg = this.imgArr[0];
  },
  methods:{
    changeImg(item){
      this.activeImg = item;
    },
    saveEditImgSrc(src){
      this.editImgSrc = src;
    },
  }
};
</script>

<style scoped >
.img_mark_box {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  padding: 0 200px 0 300px;
  box-sizing: border-box;
}
.img_mark_l,.img_mark_r{
  position: absolute;
  top: 0;
  bottom: 0;
}
.img_mark_l{
  left: 0;
  width: 300px;
  box-sizing: border-box;
  padding: 20px 10px;
}
.img_mark_img{
    height: 80px;
    box-sizing: border-box;
    vertical-align: middle;
    margin-bottom: 10px;
    overflow: hidden;
    border: 1px solid #eee;
    border-radius: 8px;
    cursor: pointer;
}
.img_mark_img>img{
    width: 100%;
    height: 100%;
}
.img_mark_r{
  right: 0;
  width: 200px;
  box-sizing: border-box;
  padding: 20px 10px;
}
.img_mark_r>img{
  width: 100%;
}
.img_mark_m{
  width: 100%;
  height: 100%;
}
</style>

在这里插入图片描述

四、效果

在这里插入图片描述

五、遇到问题 this.getResolve is not a function

问题:
在这里插入图片描述

sass-loader 版本过高,导致tui-image-editor的css无法解析

解决方案:

npm install sass-loader@7.3.1 --save-dev

报错内容:

Module build failed: TypeError: this.getResolve is not a function
    at Object.loader (D:\node_modules\sass-loader\dist\index.js:52:26)

 @ ./node_modules/vue-style-loader!./node_modules/css-loader?{"sourceMap":true}!./node_modules/vue-loader/lib/style-compiler?{"vue":true,"id":"data-v-4913b0a8","scoped":true,"hasInlineConfig":false}!D:/node_modules/sass-loader/dist/cjs.js?{"sourceMap":true}!./node_modules/vue-loader/lib/selector.js?type=styles&index=0!./src/components/ImageEditor.vue 4:14-385 13:3-17:5 14:22-393
 @ ./src/components/ImageEditor.vue
 @ ./node_modules/babel-loader/lib!./node_modules/vue-loader/lib/selector.js?type=script&index=0!./src/App.vue
 @ ./src/App.vue
 @ ./src/main.js
 @ multi (webpack)-dev-server/client?http://localhost:8080 webpack/hot/dev-server ./src/main.js

总结

踩坑路漫漫长@~@

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

DB算法原理与构建

参考&#xff1a; https://aistudio.baidu.com/projectdetail/4483048 Real-Time Scene Text Detection with Differentiable Binarization 如何读论文-by 李沐 DB (Real-Time Scene Text Detection with Differentiable Binarization) 原理 DB是一个基于分割的文本检测算…

IDEA自定义Maven仓库

Maven 是一款广泛应用于 Java 开发的工具&#xff0c;其作用类似于一个全自动的 JAR 包管理器&#xff0c;能够方便地导入开发所需的相关 JAR 包。在使用 Maven 进行 Java 程序开发时&#xff0c;开发者能够极大地提高开发效率。以下是关于如何安装 Maven 以及在 IDEA 中配置自…

电脑远程桌面选项变成灰色没办法勾选怎么办?

有些人在使用Windows系统自带的远程桌面工具时&#xff0c;会发现系统属性远程桌面选项卡中勾选启用“允许远程连接到此计算机”。 导致此问题出现的原因主要是由于组策略或者注册表设置错误造成的。 修复远程桌面选项变灰的两种方法&#xff01; 方法一&#xff1a;设置本地组…

【LeetCode】84. 柱状图中最大的矩形(困难)——代码随想录算法训练营Day60

题目链接&#xff1a;84. 柱状图中最大的矩形 题目描述 给定 n 个非负整数&#xff0c;用来表示柱状图中各个柱子的高度。每个柱子彼此相邻&#xff0c;且宽度为 1 。 求在该柱状图中&#xff0c;能够勾勒出来的矩形的最大面积。 示例 1: 输入&#xff1a;heights [2,1,5,…

Vue3调用钉钉api,内嵌H5微应用单点登录对接

钉钉内嵌H5微应用单点登录对接 https://open.dingtalk.com/document/isvapp/obtain-the-userid-of-a-user-by-using-the-log-free 前端需要的代码 1、安装 dingtalk-jsapi npm install dingtalk-jsapi2、在所需页面引入 import * as dd from dingtalk-jsapi; // 引入钉钉a…

python版本原因导致的grpcio-tools-1.48.2安装失败

因为工作需要使用python开发grpc客户端&#xff0c;在mac电脑上通以下命令安装python的grpc依赖库总是不成功 pip3 install --no-cache-dir --force-reinstall -Iv grpcio1.48.2 grpcio-tools1.48.2 clang -Wsign-compare -Wunreachable-code -fno-common -dynamic -DNDEBUG …

【string一些函数用法的补充】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言 string类对象的修改操作 我们来看 c_str 返回c格式的字符串的操作&#xff1a; 我们来看 rfind 和 substr 的操作&#xff1a; string类非成员函数 我们来看 r…

安卓之四大组件

组件描述Activity(活动)在应用中的一个Activity可以用来表示一个界面&#xff0c;意思可以理解为“活动”&#xff0c;即一个活动开始&#xff0c;代表 Activity组件启动&#xff0c;活动结束&#xff0c;代表一个Activity的生命周期结束。一个Android应用必须通过Activity来运…

react04- mvc 、 mvvm

MVC与MVVM stackoverflow论坛网站 react前端框架 使用框架前&#xff1a; 操作dom > js获取dom元素&#xff0c;事件侦听&#xff0c;修改数据&#xff0c;设置样式。。。 操作dom问题: 直接操作dom&#xff0c;会造成大量的回流、重绘&#xff0c;消耗大量性能操作起来也…

MySQL基础---SQL语句2(WHERE、AND、OR、ORDER BY、COUNT)

1. WHERE 子句 1. 语法 WHERE 子句用于限定选择的标准 在 slelece、update、delete 语句中&#xff0c;皆可使用 WHERE 子句来限定选择的标准 -- 查询语句 select 列名称 form 表名称 where 列 运算符 值-- 更新语句 update 列名称 form 列新值 where 列 运算符 值-- 删除语句…

Linux——信号量

目录 POSIX信号量 信号量原理 信号量概念 信号量函数 基于环形队列的生产者消费者模型 生产者和消费者申请和释放资源 单生产者单消费者 多生产者多消费者 多生产者多消费者的意义 信号量的意义 POSIX信号量 信号量原理 如果仅用一个互斥锁对临界资源进行保护&#…

Vulnhub靶机:Kioptrix_Level1.2

一、介绍 运行环境&#xff1a;Virtualbox 攻击机&#xff1a;kali&#xff08;192.168.56.101&#xff09; 靶机&#xff1a;Kioptrix_Level1.2&#xff08;192.168.56.106&#xff09; 目标&#xff1a;获取靶机root权限和flag 靶机下载地址&#xff1a;https://www.vul…

【3月14日-云服务器推荐】阿里云 腾讯云 京东云有什么区别? 选购指南 最新价格对比 搭建博客 游戏服务器均可多用

3月14日更新&#xff0c;本文纯原创&#xff0c;侵权必究 《最新对比表》已更新在文章头部—腾讯云文档&#xff0c;文章具有时效性&#xff0c;请以腾讯文档为准&#xff01; 【腾讯文档实时更新】云服务器1分钟教会你如何选择教程 https://docs.qq.com/document/DV0RCS0lGeH…

郭炜老师mooc第十一章数据分析和展示(numpy,pandas, matplotlib)

多维数组库numpy numpy创建数组的常用函数 # numpy数组import numpy as np #以后numpy简写为np print(np.array([1,2,3])) #>>[1 2 3] print(np.arange(1,9,2)) #>>[1 3 5 7] 不包括9 print(np.linspace(1,10,4)) #>>[ 1. 4. 7. 10.] # linespace(x,y,n)&…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的日常场景下的人脸检测系统(深度学习模型+PySide6界面+训练数据集+Python代码)

摘要&#xff1a;开发用于日常环境中的人脸识别系统对增强安全监测和提供定制化服务极为关键。本篇文章详细描述了运用深度学习技术开发人脸识别系统的全过程&#xff0c;并附上了完整的代码。该系统搭建在强大的YOLOv8算法之上&#xff0c;并通过与YOLOv7、YOLOv6、YOLOv5的性…

YOLOv9如何训练自己的数据集(NEU-DET为案列)

&#x1f4a1;&#x1f4a1;&#x1f4a1;本文内容&#xff1a;教会你用自己数据集训练YOLOv9模型 YOLOv9魔术师专栏 ☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️ ☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️ 包含注意力机制魔…

没有硬件基础可以学单片机吗?

没有硬件基础可以学单片机吗&#xff1f; 在开始前我分享下我的经历&#xff0c;我刚入行时遇到一个好公司和师父&#xff0c;给了我机会&#xff0c;一年时间从3k薪资涨到18k的&#xff0c; 我师父给了一些 电气工程师学习方法和资料&#xff0c;让我不断提升自己&#xff0c…

Docker-基本命令

目录 一、Docker与虚拟机技术 二、Docker功能 三、安装 安装&#xff1a; 1、环境准备&#xff1a; 2、安装docker 3、配置阿里云镜像加速 镜像加速源 4、Docker是怎么工作的 5、Docker为什么比虚拟机快 四、docker命令 1、镜像命令 Docker官方镜像库&#xff1a…

深入理解与应用Keepalive机制

目录 引言 一、VRRP协议 &#xff08;一&#xff09;VRRP概述 1.诞生背景 2.基本理论 &#xff08;二&#xff09;VRRP工作原理 &#xff08;三&#xff09;VRRP相关术语 二、keepalive基本理论 &#xff08;一&#xff09;基本性能 &#xff08;二&#xff09;实现原…

Hadoop伪分布式配置--没有DataNode或NameNode

一、原因分析 重复格式化NameNode 二、解决方法 1、输入格式化NameNode命令&#xff0c;找到data和name存放位置 ./bin/hdfs namenode -format 2、删除data或name&#xff08;没有哪个删哪个&#xff09; sudo rm -rf data 3、重新格式化NameNode 4、重新启动即可。