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依赖
  • [] 错误管理
  • [] 添加自定义组件

Readme

Keywords

Package Sidebar

Install

npm i matting-editor

Weekly Downloads

0

Version

0.2.4

License

ISC

Unpacked Size

8.88 MB

Total Files

86

Last publish

Collaborators

  • zongzi89
  • kylee0325
  • gaoding-bot
  • jimco
  • sharkseven
  • facai
  • laoshu133
  • kinglisky
  • aui
  • noahlam
  • mljsgto222
  • xuezi
  • mutou
  • moocher
  • zengtiansheng
  • codert
  • hezai