Nonstop Progressive Marxism

    matting-editor

    0.2.4 • Public • Published

    稿定抠图编辑器

    使用方法

    npm install matting-editor
    <template>
        <matting-editor
            ref="mattingEditor"
            :options="mattingEditorOptions"
            @update="onMattingUpdate"
            @error="onMattingError"
        >
            <div slot="logo">logo 注入</div>
            <div class="user-tips">支持外部组件注入(需自定义 CSS)</div>
        </matting-editor>
    </template>
     
    <script>
    import Vue from 'vue';
    import MattingEditor from 'matting-editor';
     
    Vue.use(MattingEditor);
    </script> 

    开发模式

    npm run dev
    # visit page on localhost:8080 

    关于懒加载

    使用懒加载可以在我们需要抠图 SDK 的时候,再进行代码加载。

    // install-matting-editor.js
    import Vue from 'vue';
     
    let promise;
     
    export default () => {
        if(!promise) {
            promise = new Promise(resolve => {
                // 引入 matting-editor 组件
                require(['matting-editor'], resolve);
            })
            .then(mattingModule => {
                // 调用 matting-editor 的 install 方法
                // 参数是 Vue
                mattingModule.default.install(Vue);
     
                return Promise.delay(0);
            });
        }
     
        return promise;
    };
     
    // index.js
    import installMattingEditor from './install-matting-editor';
     
    installMattingEditor()
    .then(() => {
        // ...
    });

    User canceled

    用户连续进行抠图操作,若上一次抠图未处理完,将会抛出 User canceled 错误

    err.name; // CancellationError
    err.canceled; // true

    配置参数

    options:

    默认参数如下,包含钩子的默认实现:

    mattingEditorOptions = {
        // 图片最大高度
        maxImageHeight: 1000,
     
        // 图片最大宽度
        maxImageWidth: 1000,
     
        maxFileSize: 9 * 1024 * 1024,
     
        // 画布背景色值
        canvasBackgroundColor: "#e6e6e6",
     
        // 笔刷颜色对象
        brushColorsMap: {
            // 保留刷子颜色
            keep: "#196cfa",
     
            // 剔除刷子颜色值
            drop: "#f73d64"
        },
     
        // 背景色列表
        swatches: [
            {
                // 颜色值 null 表示透明
                value: null,
     
                // text tips
                text: '透明'
            },
            {
                value: '#000000',
                text: '黑色'
            },
            {
                value: '#666666',
                text: '灰色'
            },
            {
                value: '#ffffff',
                text: '白色'
            },
            {
                value: '#d8090b',
                text: '红色'
            },
            {
                value: '#01a1ff',
                text: '蓝色'
            }
        ],
     
        // 默认刷子类型
        defaultTool: 'keep',
     
        // 工具栏开关
        showToolbar: true,
     
        // 抠图 loading 图片延迟时间
        loadingDelay: 500,
     
        // 第一次使用的用户(通过 localStorage = matting_guided_new_user 缓存) 显示新手引导
        guiderable: true,
     
        // 第一次使用的用户(通过 localStorage = matting_popper_store 缓存) 显示指引性引导
        // 用户在画布上画完一笔后 3s 后在相对的笔刷上出现 popper 提示选择另外一个画笔
        // 用户选择另外笔刷在画布上画完 3s 后在背景选择位置出现 popper 提示可以选择其他颜色
        popperGuiderable: true,
     
        // 新手帮助
        enableHelp: false,
     
        // 保存钩子,编辑器会在用户操作、抠图结果更新时调用此钩子
        // 入参为编辑器内部维护 `matting` 数据
        // 返回 `Promise`,结果需要返回一个 `matting` 对象
        saveMatting(matting) {
            return Promise.try(() => {
                if (matting.id) {
                    if (matting.$update) {
                        return matting.$update();
                    }
     
                    return axios.put(`/api/mattings/${matting.id}`, matting);
                }
     
                if (matting.$save) {
                    return matting.$save();
                }
     
                return axios.post('/api/mattings', matting);
            })
            .then(res => {
                return res.data || res;
            });
        },
     
        // 抠图钩子,编辑器会在用户操作后调用此钩子
        // 入参分别为 `mattingData`, `matting`
        // 返回 `Promise`,结果内至少需要包含 `edge_paths`, `mask_url` 字段
        mattingImage(matting) {
            const apiUrl = `/api/mattings/${matting.id}/images`;
     
            return axios.post(apiUrl, {
                content: matting.content
            })
            .then(res => {
                return res.data;
            });
        },
     
        // 图片上传钩子
        // 入参为图片 blob 数据,可以直接通过 oss 等方式上传
        // 返回 `Promise`,结果至少需要返回 `url` 字段
        uploadImage(imageBlob, matting) {
            return {
                url: URL.createObjectURL(imageBlob)
            };
        }
    }

    主要数据结构

    mattingData

    mattingData 对象是 matting 对象中的核心部分,用于存储抠图的主要信息。

    defaultMattingData = {
        sourceImage: '',        // 抠图图片,必须为 URL 地址
        imageHeight: 0,         // 图片的高度
        imageWidth: 0,          // 图片的宽度
        backgroundColor: null,  // 抠图的背景颜色,null为透明,需要为Hex颜色值
        featheringRadius: 0,    // 画笔边缘平滑像素
        brushSize: 30,          // 画笔大小像素
        lines: []               // 存储笔画路径信息,笔画数据结构在后面说明
    }

    line

    line 对象记录每个笔画的信息,存储在 mattingData.line 中,每个 line 对应一个笔画。

    line = {
        action: 'keep',         // keep 为保留笔画,drop 为丢弃笔画
        alpha: 0.8,             // alpha 通道
        color: 1666298,        // hex 颜色值的十进制值
        points: [0, 1, 3, 5]    // 存储笔画路径,绘制方式请参考源码
    }

    matting

    matting 对象,对外的主要数据结构。

    matting = {
        content: JSON.string(mattingData)   // matting 只需将被JSON序列化后的 mattingData 存储在content即可,可以根据需要添加其他字段
    }

    主要接口

    importMatting()

    用于导入一个已经存在的 matting 对象,同时初始化编辑器

    mattingEditor.importMatting({
        id: 1,
        content: '{"sourceImage":"https://xxx.jpg","brushSize":30,"lines":[...]}',
    });

    importMattingByImage()

    通过图片 url 创建抠图,先调用 saveMatting 钩子函数,创建 matting 对象,并初始化编辑器。若图片宽高超过限制,会先压缩,再调用 uploadImage 钩子函数上传图片

    const imageUrl = 'https://xxx.jpg';
    const extendData = {
        scene: 'koutu'    
    }; // 添加 matting 属性
     
    mattingEditor.importMattingByImage(imageUrl, extendData)
    .then(matting => {
        // matting 对象
     
        console.log(matting.scene); // koutu
    });

    importMattingByFile()

    通过图片 file 文件创建抠图,先调用 saveMatting 钩子函数,创建 matting 对象, 并初始化编辑器。若图片宽高超过限制,会先压缩,再调用 uploadImage 钩子函数上传图片

    const extendData = {
        scene: 'koutu'
    }; // 添加 matting 属性
     
    mattingEditor.importMattingByFile(file, extendData)
    .then(matting => {
        // matting 对象
     
        console.log(matting.scene); // koutu
    });

    createMatting()

    用于创建 matting 对象。需要注意的是,创建后的 matting 对象的 content 字段为字符串,如果需要修改 mattingData,需要先 JSON.parse 解析后再操作

    // 创建默认 matting
    let matting = mattingEditor.createMatting();
     
    // 根据已有的 mattingData 创建,该函数会用默认值填充 mattingData 的空字段
    let matting = mattingEditor.createMatting(mattingData);
     
    // 还可以为 matting 添加自定义字段
    let extendData = {
        extend: 'extend'
    };
    let matting = mattingEditor.createMatting(mattingData, extendData);
    /**
     * {
     *     content: ...,
     *     extend: 'extend'
     * } 
     */

    getMattingData()

    获取当前抠图数据对象

    let mattingData = mattingEditor.getMattingData();
     
    // mattingData 结构如下
    mattingData = {
        // 抠图插件版本号
        version: '1.0.0',
     
        // 原图片地址
        sourceImage: 'http://123.png',
     
        // 当前图片宽度
        imageWidth: 100,
     
        // 当前图片高度
        imageHeight: 100,
     
        // 结果图的背景颜色, "#000"
        backgroundColor: null,
     
        // 笔刷直径
        brushSize: 30,
     
        // 边缘平滑度
        featheringRadius: 0,
     
        // 当前笔刷数组对象
        lines: [
            {
                // 线条类型
                action: 'keep',
     
                // 线条透明图(0-1)
             alpha: 0.8,
     
                // 颜色值
                color: 0xff0000
     
                // 线条坐标 n: 代表x坐标 n+1代表y坐标
                points: [],
     
                // 笔刷直径 / zoom
                size: 30
            }
        ]
    }

    getMatting()

    获取当前抠图 matting 对象

    let matting = mattingEditor.getMatting();
     
    // matting 结构如下
    matting = {
        id: 1,
        content: '{"sourceImage":"https://xx.jpg","lines":[]}',
        result_image: 'https://xxx.jpg'
    };

    downloadImage([imageOptions])

    下载结果图。返回 Promise

    mattingEditor.downloadImage({
        // 导出图片类型 ('png', 'jpg', 'jpeg')
        type: 'jpg',
     
        // 图片质量只有 `jpg` `jpeg` 设置有效,数值 0-1
        quality: 0.8
    });

    exportImage([imageOptions])

    获取结果图。返回 Promise,结果返回 DataURL

    mattingEditor.exportImage({
        // 导出图片类型 ('png', 'jpg', 'jpeg')
        type: 'jpg',
     
        // 图片质量只有 `jpg` `jpeg` 设置有效,数值 0-1
        quality: 0.8
    })
    .then(dataURL => {
        // dataURL = "data:image/png;base64,iVBORw0KGgxxxxxx"
    });

    getImageType(url)

    获取图片后缀,支持 DataURL、MIME types、URL。对于 URL 格式的字符串,只支持jpg、jpeg、png三种格式。如果不是图片类型,则返回 undefined

    let dataURL = 'data:image/png;xxxxxxxxx';
    console.log(mattingEditor.getImageType(dataURL)); // png
     
    let mimeTypes = 'image/jpeg';
    console.log(mattingEditor.getImageType(mimeTypes)); // jpeg
     
    let url = 'http://example.com/path/to/image.jpg';
    console.log(mattingEditor.getImageType(url));    // jpg
     
    let url = 'http://example.com/path/to/image.gif'
    console.log(mattingEditor.getImageType(url));    // undefined

    assertImageType(url)

    判断是否是受支持的图片格式,不支持的格式会抛出异常,支持的格式会静默。支持的参数类型与 getImageType() 相同

    mattingEditor.assertImageType(url)

    updateViewSize()

    更新画布位置,尺寸

     
    mattingEditor.updateViewSize();
     

    setBrushSize(brushSize)

    设置刷子尺寸

     
    mattingEditor.setBrushSize(30);
     

    setFeatheringRadius(featheringRadius)

    设置边缘平滑

     
    mattingEditor.setFeatheringRadius(2);
     

    setBackgroundColor(backgroundColor)

    设置输出图背景

     
    mattingEditor.setBackgroundColor("#000");
     

    setOptions(options)

    设置 mattingOptions

     
    mattingEditor.setOptions({
        canvasBackgroundColor: "#e6e6e6"
    });
     

    undo()

    撤销

     
    mattingEditor.undo();
     

    redo()

    重做

     
    mattingEditor.redo();
     

    zoomIn()

    放大

     
    mattingEditor.zoomIn();
     

    zoomOut()

    缩小

     
    mattingEditor.zoomOut();
     

    fitZoom()

    适应画布

     
    mattingEditor.fitZoom();
     

    setZoom(zoom)

    设置图片比例 注:最大 4 倍,最小 20px

     
    mattingEditor.setZoom(2);
     

    showGuider()

    显示抠图引导弹窗 不受配置参数 guiderable 影响

     
    mattingEditor.showGuider();
     

    initPopperGuider()

    初始化指引性引导 不受配置参数 popperGuiderable 影响 注:请在 dom 加载完成后初始化 (通过 localStorage = matting_popper_store 缓存) 重复调用无效

     
    // 用户在画布上画完一笔后 3s 后在相对的笔刷上出现 popper 提示选择另外一个画笔
    // 用户选择另外笔刷在画布上画完 3s 后在背景选择位置出现 popper 提示可以选择其他颜色
     
    mattingEditor.initPopperGuider();
     

    稿定抠图生命周期事件

    ready()

    插件准备就绪,图片已载入 canvas

    <matting-editor
        @ready="ready"
    />
     
    export default {
        methods: {
            ready() {}
        }
    }

    change(mattingData)

    笔刷画完,开始请求抠图API前

    <matting-editor
        @change="change"
    />
     
    export default {
        methods: {
            change(mattingData) {
                // mattingData 可参考上面结构
            }
        }
    }

    mattinged(mattingResult, mattingData)

    图片抠图完成, 未调用 uploadImage()

    <matting-editor
        @mattinged="mattinged"
    />
     
    export default {
        methods: {
            mattinged(mattingResult, mattingData) {
                // mattingData 可参考上面结构
                // 抠图处理接口的返回结果
                mattingResult = {
                    edge_paths: ["M0 450 ... 3z"],
                    mask_url: "http://xxx.json"
                }
            }
        }
    }

    update(mattingData)

    结果图更新后

    <matting-editor
        @update="update"
    />
     
    export default {
        methods: {
            update(mattingData) {
                // mattingData 可参考上面结构
            }
        }
    }

    error(err)

    抠图失败,带err参数

    <matting-editor
        @error="error"
    />
     
    export default {
        methods: {
            error(err) {
                // err 错误信息
            }
        }
    }

    TODO

    • [] 去除Jquery依赖
    • [] 错误管理
    • [] 添加自定义组件

    Keywords

    Install

    npm i matting-editor

    DownloadsWeekly Downloads

    0

    Version

    0.2.4

    License

    ISC

    Unpacked Size

    8.88 MB

    Total Files

    86

    Last publish

    Collaborators

    • jimco
    • sharkseven
    • facai
    • doodlewind
    • laoshu133
    • maple-leaf
    • kinglisky
    • aui
    • colinleo
    • noahlam
    • lijianzhang
    • mljsgto222
    • xuezi
    • mutou
    • liajoy
    • baituo
    • moocher
    • zengtiansheng
    • codert
    • hezai