npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

matting-editor

v0.2.4

Published

matting-editor

Downloads

44

Readme

稿定抠图编辑器

使用方法

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