分享一个强大的 Vue 图片编辑插件(快来试试!)

Posted moiom

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分享一个强大的 Vue 图片编辑插件(快来试试!)相关的知识,希望对你有一定的参考价值。

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

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

【相关推荐:《vue.js教程》】

最近用户提出了一个新的需求,老师可以批改学生的图片作业,需要对图片进行旋转、缩放、裁剪、涂鸦、标注、添加文本等。乍一听,又要掉不少头发。有没有功能强大的插件实现以上功能,让我有更多的时间去阻止女票双十一剁手呢?答案当然是有的。

效果展示

涂鸦

裁剪

标注

旋转

滤镜

是不是很强大!还有众多功能我就不一一展示了。那么还等什么,跟我一起用起来吧~

安装

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 最大高度
  
);

效果如下:

自定义样式

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

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",
;

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, // 本地化语言为中文
      theme: customTheme, // 自定义样式
    ,
    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和遮罩mask
          initMenu: "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和遮罩mask
          initMenu: \'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

更多编程相关知识,请访问:编程入门!!

以上是关于分享一个强大的 Vue 图片编辑插件(快来试试!)的主要内容,如果未能解决你的问题,请参考以下文章

简单功能强大的jQuery在线图片裁剪插件croppic

简单功能强大的jQuery在线图片裁剪插件croppic

一款强大的前端vue实用图片放大预览插件(推荐收藏)

vue-piczoom 基于vue2.x的电商图片放大镜插件

强大的jQuery图片查看器插件Viewer.js

[210109]开源免费的轻量级电脑图片编辑处理软件 GIMP 不想用 PS 可以试试这个软件