分享一款 Vue 图片编辑插件 (推荐)

💥本篇文章给大家分享一款强大到没朋友的Vue图片编辑插件,可以对图片进行旋转、缩放、裁剪、涂鸦、标注、添加文本等,快来试试并收藏吧!💕

这是一款对图片进行旋转、缩放、裁剪、涂鸦、标注、添加文本在线处理的图片处理插件,本人在在项目时实战用过,确实好用。

效果展示

涂鸦

裁剪

 标注

旋转

 滤镜

安装

npm i tui-image-editor
// or
yarn add tui-image-editor

使用

快速体验

复制以下代码,将插件引入到自己的项目中。

<template><div><div id="tui-image-editor"></div></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";
export default {data() {return {instance: null,};},mounted() {this.init();},methods: {init() {this.instance = new ImageEditor(document.querySelector("#tui-image-editor"),{includeUI: {loadImage: {path: "https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c1d7a1feb60346449c1a64893888989a~tplv-k3u1fbpfcp-watermark.image",name: "image",},initMenu: "draw", // 默认打开的菜单项menuBarPosition: "bottom", // 菜单所在的位置},cssMaxWidth: 1000, // canvas 最大宽度cssMaxHeight: 600, // canvas 最大高度});document.getElementsByClassName("tui-image-editor-main")[0].style.top = "45px"; // 图片距顶部工具栏的距离},},
};
</script><style scoped>
.drawing-container {height: 900px;
}
</style>

可以看到活生生的图片编辑工具就出现了,是不是很简单: 

国际化

由于是老外开发的,默认的文字描述都是英文,这里我们先汉化一下:

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": "锁定宽高比例",
};this.instance = new ImageEditor(document.querySelector("#tui-image-editor"),{includeUI: {loadImage: {path: "https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c1d7a1feb60346449c1a64893888989a~tplv-k3u1fbpfcp-watermark.image",name: "image",},initMenu: "draw", // 默认打开的菜单项menuBarPosition: "bottom", // 菜单所在的位置locale: locale_zh, // 本地化语言为中文},cssMaxWidth: 1000, // canvas 最大宽度cssMaxHeight: 600, // canvas 最大高度}
);

效果如下:

自定义样式

默认风格为暗黑系,如果想改成白底,或者想改变按钮的大小、颜色等样式,可以使用自定义样式。

按钮优化

通过自定义样式,我们看到右上角的 Load 和 Download 按钮已经被隐藏了,接下来我们再隐藏掉其他用不上的按钮(根据业务需要),并添加一个保存图片的按钮。

<template><div><div id="tui-image-editor"></div><el-button type="primary" size="small" @click="save">保存</el-button></div>
</template>// ...
methods: {init() {this.instance = new ImageEditor(document.querySelector("#tui-image-editor"),{includeUI: {loadImage: {path: "https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c1d7a1feb60346449c1a64893888989a~tplv-k3u1fbpfcp-watermark.image",name: "image",},menu: ["resize", "crop", "rotate", "draw", "shape", "icon", "text", "filter"], // 底部菜单按钮列表 隐藏镜像flip和遮罩maskinitMenu: "draw", // 默认打开的菜单项menuBarPosition: "bottom", // 菜单所在的位置locale: locale_zh, // 本地化语言为中文theme: customTheme, // 自定义样式},cssMaxWidth: 1000, // canvas 最大宽度cssMaxHeight: 600, // 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";  // 隐藏顶部重置按钮},// 保存图片,并上传save() {const base64String = this.instance.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("image", blob);// upload file},
}<style scoped>
.drawing-container {height: 900px;position: relative;.save {position: absolute;right: 50px;top: 15px;}
}
</style>

可以看到顶部的重置按钮,以及底部的镜像和遮罩按钮都已经不见了。右上角多了一个我们自己的保存按钮,点击按钮,可以获取到 base64 文件和 blob 文件。

完整代码

<template><div><div id="tui-image-editor"></div><el-button type="primary" size="small" @click="save">保存</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_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 = {"common.bi.image": "", // 左上角logo图片"common.bisize.width": "0px","common.bisize.height": "0px","common.backgroundImage": "none","common.backgroundColor": "#f3f4f6","common.border": "1px solid #333",// 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": "#ccc","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.init()},methods: {init() {this.instance = new ImageEditor(document.querySelector('#tui-image-editor'), {includeUI: {loadImage: {path: 'https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c1d7a1feb60346449c1a64893888989a~tplv-k3u1fbpfcp-watermark.image',name: 'image'},menu: ['resize', 'crop', 'rotate', 'draw', 'shape', 'icon', 'text', 'filter'], // 底部菜单按钮列表 隐藏镜像flip和遮罩maskinitMenu: 'draw', // 默认打开的菜单项menuBarPosition: 'bottom', // 菜单所在的位置locale: locale_zh, // 本地化语言为中文theme: customTheme // 自定义样式},cssMaxWidth: 1000, // canvas 最大宽度cssMaxHeight: 600 // 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' // 隐藏顶部重置按钮},// 保存图片,并上传save() {const base64String = this.instance.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('image', blob)// upload file}}
}
</script><style scoped>
.drawing-container {height: 900px;position: relative;.save {position: absolute;right: 50px;top: 15px;}
}
</style>

总结

以上就是 tui.image-editor 的基本使用方法,相比其他插件,tui.image-editor 的优势是功能强大,简单易上手。

插件固然好用,但本人也发现一个小 bug,当放大图片,用手掌拖动显示位置,再点击重置按钮时,图片很可能就消失不见了。解决办法有两个,一是改源码,在重置之前,先调用 resetZoom 方法,还原缩放比列;二是自己做一个重置按钮,点击之后调用 this.init 方法重新进行渲染。

赠人玫瑰,手有余香。如果觉得有用,就动动发财的小手,点个赞把~

更多 API 及 Demo 请参考:

github地址:https://github.com/nhn/tui.image-editor

API 及 Examples 地址:http://nhn.github.io/tui.image-editor/latest

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL 核心基础 | Pandaer杂货铺

MySQL一个后端开发必须会接触的中间件&#xff0c;也是关系型数据库的代表。如果你希望看下去这篇文章&#xff0c;需要你有使用MySQL或者相关关系型数据库的经验&#xff0c;不然这篇文章在你眼中就会索然无味了。 这篇文章不会讲解如何使用MySQL&#xff0c;例如如何安装&am…

【网络】应用层协议HTTPHTTPcookie与sessionHTTPS协议原理

主页&#xff1a;醋溜马桶圈-CSDN博客 专栏&#xff1a;计算机网络原理_醋溜马桶圈的博客-CSDN博客 gitee&#xff1a;mnxcc (mnxcc) - Gitee.com 目录 1.应用层协议HTTP 2.认识 URL 2.1 urlencode 和 urldecode 3.HTTP 协议请求与响应格式 3.1 HTTP 请求 3.2 HTTP 响应 …

搭建业务的性能优化指南

这是一篇搭建业务优化的心路历程&#xff0c;也是写给搭建业务的性能优化指南。 前言 直到今天&#xff0c;淘内的页面大多都迁移到了 SSR&#xff0c;从我们终端平台 - 搭建研发团队的视角看&#xff0c;业务大致可以分为两类 —— 搭建派 和 源码派。 这两者互不冲突&#xf…

Swift实现高效链表排序:一步步解读

文章目录 前言摘要问题描述题解解题思路Swift 实现代码代码分析示例测试与结果 时间复杂度空间复杂度总结关于我们 前言 本题由于没有合适答案为以往遗留问题&#xff0c;最近有时间将以往遗留问题一一完善。 148. 排序链表 不积跬步&#xff0c;无以至千里&#xff1b;不积小流…

开源 - Ideal库 - Excel帮助类,TableHelper实现(三)

书接上回&#xff0c;我们今天继续讲解实现对象集合与DataTable的相互转换。 01、把表格转换为对象集合 该方法是将表格的列名称作为类的属性名&#xff0c;将表格的行数据转为类的对象。从而实现表格转换为对象集合。同时我们约定如果类的属性设置了DescriptionAttribute特性…

基于DHCP,ACL的通信

该问题为华为的学习资料 1.首先把所有的PC机全部设置为DHCP 2.配置地址 3.ospf 4.dhcp 5.acl AR1 dhcp en interface GigabitEthernet0/0/0ip address 192.168.1.254 255.255.255.0 dhcp select global interface GigabitEthernet0/0/1ip address 10.1.12.1 255.255.255.…

基于深度学习的卷积神经网络十二生肖图像识别系统(PyQt5界面+数据集+训练代码)

本研究提出了一种基于深度学习的十二生肖图像识别系统&#xff0c;旨在利用卷积神经网络&#xff08;CNN&#xff09;进行图像分类&#xff0c;特别是十二生肖图像的自动识别。系统的核心采用了两种经典的深度学习模型&#xff1a;ResNet50和VGG16&#xff0c;进行图像的特征提…

探索温度计的数字化设计:一个可视化温度数据的Web图表案例

随着科技的发展&#xff0c;数据可视化在各个领域中的应用越来越广泛。在温度监控和展示方面&#xff0c;传统的温度计已逐渐被数字化温度计所取代。本文将介绍一个使用Echarts库创建的温度计Web图表&#xff0c;该图表通过动态数据可视化展示了温度值&#xff0c;并通过渐变色…

Attention显存统计与分析

Attention显存估计 简单的Attention函数 import torch import torch.nn as nn import einops class Attention(nn.Module):def __init__(self, dim, num_heads8, qkv_biasFalse, qk_scaleNone, attn_drop0., proj_drop0.):super().__init__()self.num_heads num_headshead_d…

[MacOS] [kubernetes] MacOS玩转虚拟化最佳实践

❓ 为什么不在MacOS本机安装呢&#xff1f;因为M系列芯片是Arm架构&#xff0c;与生产环境或者在本地调试时候&#xff0c;安装虚拟镜像和X86不同&#xff0c;造成不必要的切换环境的额外成本&#xff0c;所以在虚拟化的x86调试 步骤 & 详情 一: 安装OrbStack & 并配置…

Unity世界坐标转屏幕坐标报错解决办法。

问题描述&#xff0c;如果你在脚本中尝试使用Camera.转换世界坐标的时候发现点不出来&#xff0c;可以点到你的Camera这个方法看能否跳转&#xff0c;如果能够跳转&#xff0c;并且这个脚本是你自己写的&#xff0c;那么恭喜你&#xff0c;下面就是解决办法&#xff0c;直接将C…

系统监控——分布式链路追踪系统

摘要 本文深入探讨了分布式链路追踪系统的必要性与实施细节。随着软件架构的复杂化&#xff0c;传统的日志分析方法已不足以应对问题定位的需求。文章首先解释了链路追踪的基本概念&#xff0c;如Trace和Span&#xff0c;并讨论了其基本原理。接着&#xff0c;文章介绍了SkyWa…

IAR中编译下载未下载问题

第一张图片是正常下载&#xff0c;第二张未正常下载。经过查看download选项发现 启用了 suppress download &#xff08;禁用下载)

【UE5 C++】判断两点连线是否穿过球体

目录 前言 原理 代码 测试 结果 前言 通过数学原理判断空间中任意两点的连线是否穿过球体&#xff0c;再通过射线检测检验算法的正确性。 原理 &#xff08;1&#xff09;设球体球心的坐标为 &#xff0c;半径为r&#xff1b; &#xff08;2&#xff09;设线段中A点的坐…

网络安全之IP伪造

眼下非常多站点的涉及存在一些安全漏洞&#xff0c;黑客easy使用ip伪造、session劫持、xss攻击、session注入等手段危害站点安全。在纪录片《互联网之子》&#xff08;建议搞IT的都要看下&#xff09;中。亚伦斯沃茨&#xff08;真实人物&#xff0c;神一般的存在&#xff09;涉…

《运放秘籍》第二部:仪表放大器专项知识点总结

一、差分放大器与仪表放大器的讨论 1.1. 仪放的前世今生——差分放大器原理&#xff1f; 1.2. 差分放大的原理 1.3. 差分放大器检测电流 1.4. 差分放大器端一&#xff1a;输入阻抗 1.5. 差分放大器端二&#xff1a;共模抑制比 1.6. 为什么关注输入阻抗&#xff1f;共模抑…

AJAX一、axios使用,url组成(协议,域名,资源路径)查询参数和化简,错误处理,请求/响应报文,状态码,接口文档,

一、AJAX是什么 概念 &#xff1a; AJAX是一种与服务器&#xff08;后端&#xff09;通信的技术 二、请求库axios的基本用法 1导包 2使用 // 1. 发请求 axios({ url: 请求地址 }).then(res > { // 2.接收并使用数据 }) <body><p class"province"…

关于ConstarintLayout有关的点

目录 一、概述 二、过程。 1、介绍 主要特点 关键概念 使用示例 总结 2、我遇到的问题 问题&#xff1a; 可能的原因&#xff1a; 结论 一、概述 在学习过程中&#xff0c;发现对ConstarintLayout理解不够到位&#xff0c;下面是发现并解决问题过程。 二、过程。 1…

【UE5 C++课程系列笔记】06——定时器的基本使用

目标 使用定时器每秒调用函数打印一句日志信息&#xff0c;并在调用一定次数后停止定时器。 步骤 1. 新建一个Actor类&#xff0c;这里命名为 2. 先在“TimerActor.cpp”中获取定时器管理器 使用定时器管理器来设置定时器&#xff0c;该定时器在2s后启动&#xff0c;然后每…

用c语言完成俄罗斯方块小游戏

用c语言完成俄罗斯方块小游戏 这估计是你在编程学习过程中的第一个小游戏开发&#xff0c;怎么说呢&#xff0c;在这里只针对刚学程序设计的学生&#xff0c;就是说刚接触C语言没多久&#xff0c;有一点功底的学生看看&#xff0c;简陋的代码&#xff0c;简陋的实现&#xff0…