Vue中使用图片编辑器 tui-image-editor 实现在线编辑保存

不想看的直接跳去第三步的2.2,点击2.2、改版的代码哈,代码基本上都注释了(就在改版的里面进行注释的,都是一行一行敲得,老可怜了)
在这里插入图片描述

一、目的

突然来个问题,就要让我在线编辑图片,并且还得上传,我直接干一天就得敲一天。
在这里插入图片描述

二、样式

1、初始上传页面(编辑前)

虽然弄得不好,但好在实现功能了
在这里插入图片描述

2、在线编辑页面

这是我改版之后的,也可以根据自己需要进行修改哈
在这里插入图片描述
下面上原版(我直接关闭美颜和滤镜,当然还得留件衣服,毕竟得见人)
在这里插入图片描述

3、初始上传页面(编辑后)

然后就是修改后的图片
在这里插入图片描述

三、上代码

1、安装依赖

具体怎么弄的忘了哈,可能也和本身的项目有关,就安装了这仨依赖,tui-image-editor安装不上加入不到package.json文件,加入了–save命令就下载成功了
在这里插入图片描述

npm install tui-color-picker
npm install --save tui-image-editor
npm install vue-quill-editor

2、使用代码

2.1、接近原版的代码

代码有点多哈,先发一下原版穿衣的

<template>
    <div class="box">
        <div class="drawing-container">
            <div id="tui-image-editor"></div>
        </div>
    </div>
</template>

<script>
    import storage from "@/utils/storage";
    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 {
        name: 'copper',
        data() {
            return {
                myHeaders:{},
                instance: null,
            }
        },
        mounted() {
            this.init();
            this.myHeaders= {
                'Token':storage.get("Token")
            }
        },
        methods: {
            init(file) {
                this.instance = new ImageEditor(
                    document.querySelector("#tui-image-editor"),
                    {
                        includeUI: {
                            loadImage: {
                                // path: require("@/assets/这里可以自定义照片,我给改成带入的了"),
                                path: file,
                                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>
    .box {
        width: 100%;
        height: 100%;
    }

    .drawing-container {
        height: 900px;
        position: relative;
    }
</style>

2.2、改版的代码

说是改版也就加了几个参数几个按钮
return下面加入了locale_zhcustomTheme
一个汉化的,反正我是不懂英文,
另一个是修改了样式,不然黢黑,我一般都用白色的,
想用黑的也好办,直接把common.backgroundColor这一行给他隐藏就OK了
只于加入的方法就保存返回了,解释也有
在代码中搜索以上的东西建议使用ctrl+F(一般都可以用,当然排除不一般)

然后下面是改版的

<template>
    <div class="box">
        <div class="drawing-container">
            <div id="tui-image-editor"></div>
            <el-button class="back" type="primary" size="small" @click="back">返回</el-button>
            <el-button class="save" type="primary" size="small" @click="save">保存</el-button>
        </div>
    </div>
</template>

<script>
    import storage from "@/utils/storage";
    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 {
        name: 'copper',
        data() {
            return {
                myHeaders:{},
                instance: null,
                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": "锁定宽高比例",
                },
                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",
                },
            }
        },
        props: ["parent2"],
        mounted() {
            this.init();
            this.myHeaders= {
                'Token':storage.get("Token")
            }
        },
        methods: {
            init(file) {
                this.instance = new ImageEditor(
                    document.querySelector("#tui-image-editor"),
                    {
                        includeUI: {
                            loadImage: {
                                // path: require("@/assets/这里可以自定义照片,我给改成带入的了"),
                                path: file,
                                name: "image",
                            },
                            menu: ["resize", "crop", "flip", "rotate", "draw", "shape", "icon", "text", "mask", "filter"], // 底部菜单按钮列表 想隐藏什么按顺序去除就行
                            initMenu: "draw", // 默认打开的菜单项
                            menuBarPosition: "bottom", // 菜单所在的位置
                            locale: this.locale_zh, // 本地化语言为中文
                            theme: this.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";  // 隐藏顶部重置按钮
            },
            //返回
            back(){
                this.parent2.showFlag1 = true;
                this.parent2.copperCrossAddOrUpdateFlag = false;
                this.parent2.addEditStyleChange()
            },
            // 保存图片,并上传
            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 文件
                //下面懒得弄组件直接用当前时间弄得文件名,如果后台写了这里可以随便,也可以使用uuid进行生成
                const file = new File([blob], new Date().getTime()+'.png', { type: blob.type });
                const form = new FormData();
                //后端使用@RequestParam("file") MultipartFile file接受,这里变换一下格式
                form.append("file", file);

                // 上传文件操作
                const url = this.$base.url + "file/upload"
                this.$http({
                    url: url,
                    method: "POST",
                    data: form,
                    header: this.myHeaders
                }).then(({data}) => {
                    if (data && data.code === 0) {
                        //我这里返回的是图片地址
                        var url = data.url;

                        //点击进入的代码我在下一部分贴出来
                        //保存完要返回,这里是一些返回操作,这里是从孙组件返回子组件,可以百度一下
                        //让上级组件显示
                        this.parent2.showFlag1 = true;
                        //让自己隐藏
                        this.parent2.copperCrossAddOrUpdateFlag = false;
                        //这个是恢复上级组件按钮的方法,框架有毛病,这个不重要
                        this.parent2.addEditStyleChange()
                        //这里是组件传值里面的带参返回
                        this.$emit('fileUrl', url);
                    } else {
                        this.$message.error(data.msg);
                    }
                })
            },
        }
    }
</script>

<style scoped>
    .box {
        width: 100%;
        height: 100%;
    }
    .drawing-container {
        height: 900px;
        position: relative;
        .save {
            position: absolute;
            right: 50px;
            top: 15px;
        }
        .back {
            position: absolute;
            right: 120px;
            top: 15px;
        }
    }
</style>

子组件怎么到的父组件

<copper-cross-add-or-update v-if="copperCrossAddOrUpdateFlag" @fileUrl="getFileUrl" :parent2="this" ref="copperCrossaddOrUpdate"></copper-cross-add-or-update>

点击在线编辑调用下面的方法

// 编辑
openOnlineEditor(file) {      
      //让当前页面隐藏
      this.showFlag1 = false;
      //让组件页面显示
      this.copperCrossAddOrUpdateFlag = true;
      //这个是调用组件的方法进行赋值文件,就是我说在自定义照片那一块
      this.$nextTick(() => {
          this.$refs.copperCrossaddOrUpdate.init(file);
      });
  },

然后组件保存带参返回

getFileUrl(data){
	//给那个在线编辑的图片框赋值
    this.ruleForm.zuoyepigai = data
    //修改一下状态,让在线编辑消失
    this.zuoyepigaiStatus = false
},

应该就这些了,可能弄得有点多,看懵的可以看看解释,看不清楚可以发一下信息
在这里插入图片描述

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值