整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

如何在fabric.js中使用蒙版合成图片

 现在借助于Html5中Canvas可以实现在线对图片进行一些较复杂的编辑操作,如图片合成、裁剪、旋转、缩放、调整亮度、添加滤镜等等。但由于canvas原生api使用起来比较繁琐,特别是利用canvas对图片一些复杂的操作,如利用蒙版实现手机壳和图案在线合成并可调整图案大小及位置时,使用原生api的工作量非常大,且随着需求的调整、细化,代码会变得复杂且臃肿,难以维护,最终变成shit mountain堆在那里。

  当需要实现此类复杂的功能时,这就不得不借助于现成的canvas库了,比如fabric.js。fabric.js是一个功能强大且易用的Html5 Canvas js类库。使用fabric.js,我们可以轻松实现对图片进行在线合成、裁剪等复杂操作。

  本篇文章将介绍如何使用fabric.js实现带蒙版图片合成及调整、导出等。

  1. 安装并在js中引入fabric
//模块项目
npm install fabric --save
import { fabric } from "fabric"
//非模块化项目
<script src="fabric.js"></script>
  1. 在html中新建一个canvas标签
<canvas id="c" ></canvas>
  1. 初始化canvas
let id = 'c';
let canvas = new fabric.Canvas(id, {
    backgroundColor: '#fff',//背景色,默认透明背景
    width: 800,//canvas画布宽度
    height: 800//画布高度
})
  1. 添加背景图片
fabric.Image.fromURL(图片的URL, (img) => {
    img.scaleToHeight(800);//图片缩放到画布高度
    canvas.add(img);
    canvas.sendToBack(img);//放在最底层
    //也可以直接使用canvas.setBackgroundImage方法直接设置背景图片
}, {
    //也可以在回调里使用.set方法设置各个属性值
    crossOrigin: "anonymous",//跨域时需要加上
    selectable: false,
    left: 800 / 2, //显示在画布中间
    top: 800 / 2,
    originX: 'center',//横坐标原点位置
    originY: 'center',//纵坐标原点位置
});

注意: 要需要在回调函数里按实际宽或高度设置图片宽度或高度显示比例,img.scaleToHeight(800)


  1. 加载蒙版及图案
//先加载蒙版
fabric.Image.fromURL(蒙版url, (mask) => {
    mask.scaleToHeight(800);
    //加载图案
    fabric.Image.fromURL(图案url, (img) => {
        img.scaleToHeight(800);
        canvas.add(img);
    }, {
        crossOrigin: "anonymous",
        left: 400,
        top: 400,
        originX: 'center',
        originY: 'center',
        selectable: false,
        borderColor: "#0091FF", //选中时边框颜色
        borderScaleFactor: 2, //边框比例因子
        cornerSize: 8,//边框控制角大小
        padding: 0,
        cornerColor: "#0091FF",
        clipPath: mask,//指定蒙版图片
    });
}, {
    crossOrigin: "anonymous",
    absolutePositioned: true,//根据实际设置,为true时固定显示,不随图案移动而移动
    left: 400,//指定蒙版显示大小
    top: 400,
    originX: 'center',
    originY: 'center',
});

  1. 启用编辑
    设置图案图片的selectable属性为true,并设置图片对象为活动状态
img.set("selectable", true);
canvas.setActiveObject(img);
canvas.requestRenderAll();

  1. 保存编辑后的图案
    保存可以直接导出为图片,也可以导出为json
//导出为json
let json = canvas.toJSON();
//将json保存到后台服务器,可以根据json对图片再次编辑,json中包含了调整后图片的高度、宽度、角度等信息

//导出为base64图片
let imgBase64 = canvas.toDataURL({
    format:'png',
    multiplier: 2,//根据实际需要设置导出图片与当前canvas的比例,比例越大,导出图片的分辨率越高
});
  1. 对编辑过的图案再次编辑
    初始化canvas后,通过loadFromJSON加载图片,这样加载出来的图片是我们上次编辑后的图片,可以对其继续调整。
canvas.loadFromJSON(json, canvas.renderAll.bind(canvas));

问题
  尽管fabric.js功能已经很强大,api也比较完善,结合官网文档可以快速实现我们的需求,但有一些细节问题需要我们去踩坑、去总结,比如:

  1. 加载json后图片位置大小等与上次我们编辑完保存的有些许差异,这是因为导出的json中的left、top、angle、scaleX、scaleY等只保留到小数点后两位,这样当我们的图片分辨率比较高时,差距尤其明显,解决此问题只需导出时指定我们需要保留的属性即可
let json = canvas.toJSON(['crossOrigin', 'selectable','angle', 'left', 'right', 'scaleX', 'scaleY']);
  1. 加载蒙版时别忘了指定蒙版图片属性的absolutePositioned为true(根据实际需要设置)
  2. 在vue等框架中通过条件渲染或列表渲染时需对canvas择机初始化,否则会找不到canvas元素导致初始化失败

*标题:** Web端屏幕截屏,生成自定义海报!

---

**引子**

随着互联网应用的多样化,越来越多的场景下需要用到网页截图和自定义海报生成的功能,比如分享文章摘要、活动宣传、产品展示等。本文将深入探讨如何通过Web前端技术实现这一功能,让用户直接在浏览器中完成屏幕截取并设计自己的个性化海报。我们将围绕HTML5、Canvas以及一些JavaScript库来构建一个实用且互动性强的解决方案,助您在项目中轻松集成这一热门功能。

---

**一、理解基础概念**

**1.1 Canvas API简介**

在Web前端领域,`<canvas>` 元素是HTML5中的一个重要组成部分,它提供了在网页上绘制图形的能力,包括动态图像。利用Canvas API,我们可以捕获网页视图的图像数据,并将其转换为可编辑或可保存的图像格式。

**1.2 屏幕截屏原理**

实现网页截屏的核心在于使用Canvas结合`window.getComputedStyle()`获取元素样式信息,然后遍历DOM树并渲染到Canvas上。最终通过`toDataURL()`方法将Canvas内容转为图片数据。

---

**二、实现网页截屏功能**

**2.1 获取页面可视区域**

```javascript

function capturePage() {

const html2canvasOptions = {

useCORS: true, // 处理跨域图片资源

allowTaint: false,

};

return html2canvas(document.body, html2canvasOptions)

.then((canvas) => {

// 返回Base64编码的图片数据

return canvas.toDataURL('image/png');

})

.catch((error) => console.error("Error capturing page:", error));

}

```

此处使用了`html2canvas`库来简化屏幕截取的过程,它可以将整个DOM树的内容渲染到Canvas上。请注意,在实际项目中,可能需要指定截取特定区域而非整个body。

**2.2 将截屏结果转化为海报模板**

```javascript

// 假设我们已经获得了截屏图片dataURL

let screenshotDataUrl = await capturePage();

// 创建一个新的canvas用于制作海报

const posterCanvas = document.createElement('canvas');

posterCanvas.width = POSTER_WIDTH;

posterCanvas.height = POSTER_HEIGHT;

// 获取canvas上下文

const ctx = posterCanvas.getContext('2d');

// 将截屏图片加载到新的canvas

let img = new Image();

img.src = screenshotDataUrl;

img.onload = () => {

// 添加背景、边框、文字等自定义元素

// ...


// 将截屏图片绘制到海报canvas

ctx.drawImage(img, MARGIN_LEFT, MARGIN_TOP);

// 最后将海报canvas转为图片

let finalPosterDataUrl = posterCanvas.toDataURL('image/png');

// 可以将finalPosterDataUrl用于显示、下载或上传

};

```

在这个阶段,我们首先捕获到网页屏幕内容,然后在新的Canvas上添加自定义设计元素(如背景、logo、标题等),最后合并成一张完整的海报图片。

---

**三、优化与拓展**

**3.1 性能优化**

- **懒加载**:只截取用户可见区域或滚动事件触发时才截取。

- **压缩优化**:对生成的图片进行压缩以减少传输和存储成本。

**3.2 功能扩展**

- **添加交互设计**:允许用户选择截图范围、拖拽图片位置、调整图片大小等。

- **社交分享**:集成微信、微博等社交平台的分享接口,便于用户一键分享自定义海报。

---

**四、实战案例及代码详解**

此处可以进一步提供详细的代码分析和示例代码片段,逐行解释上述核心函数的实现逻辑,并给出一个包含完整功能的简单Demo页面源码,以便读者跟随实践。

---

**结语**

通过熟练掌握Web前端技术和巧妙运用Canvas与相关库,我们可以高效地实现在浏览器端进行屏幕截取和自定义海报生成。这一功能不仅提升了用户体验,也为各种在线应用增添了趣味性和实用性。未来随着Web技术的持续发展,这类功能还将衍生出更多创新应用场景,让我们共同期待并探索更多的可能性。

---

**注:** 由于篇幅限制,以上仅展示了部分关键代码和思路,实际编写技术教程时,应详细介绍每个步骤的具体实现细节,附带完整代码实例,并配以图文说明和效果演示,确保读者能够顺利理解和复现该功能。同时,建议在实战环节引导读者一步步搭建真实环境下的项目,并针对常见问题给予解答。

anvas 合成图片

Html Code
   <img src="./tupian.png"  id="image" style="display: none;">
    <canvas id="main" width="248" height="250" style="width: 100%;">
      当前浏览器不支持Html5的canvas
    </canvas>

    <a href="javascript:void(0);" class="js_download_compicture">下载</a>

JS Code
 //canvas 使用2d绘图上下文提供的方法
    var oCanvasMain = document.getElementById("main");
    var mainCtx = oCanvasMain.getContext("2d");

    /* num1 合成图片 start */
    //先把图片绘制在画布上
    mainCtx.drawImage($('#image')[0], 0, 0, 248, 350);
    // 在画布上绘制文字
    mainCtx.font = "200px  微软雅黑";
    mainCtx.textAlign = "center";
    mainCtx.fillStyle = "#000";
    mainCtx.fillText("绘制的文案", 124, 157);
    /* 合成图片end */ 

    // ####关键代码第二步
    var oImage = new Image();
    //toDataURL方法,可以导出canvas元素上的图像
    oImage.src = oCanvasMain.toDataURL('image/png', 1);
    $('#main').after(oImage).hide();
新增需求「在pc下载功能」 ⬆️ 
//需要两个方法
function dataURLtoBlob(dataurl) {
        var arr = dataurl.split(','),
            mime = arr[0].match(/:(.*?);/)[1],
            bstr = atob(arr[1]),
            n = bstr.length,
            u8arr = new Uint8Array(n)
        while (n--) {
            u8arr[n] = bstr.charCodeAt(n)
        }
        return new Blob([u8arr], { type: mime })
    }
function downloadBase64(dataUrl, filename) {
        var imageFile, href
        const downloadLink = document.createElement('a');
        try {
            var blob = dataURLtoBlob(dataUrl)
            var href = window.URL.createObjectURL(blob)
            downloadLink.download = filename
            downloadLink.href = href
            downloadLink.click()
        } catch (err) {
        } finally {
            if (href) {
                // window.URL.revokeObjectURL(href)
            }
        }
    }
/* 如果想实现点击下载 */
    $('.downalink').on('click',function(){
        downloadBase64(oCanvasMain.toDataURL('image/png', 1), '图片名称.png');
    })

html2canvas 插件合成图片

html2canvas可以通过纯JS对浏览器端进行截屏,但截图的精确度还有待提高,部分css不可识别,所以在canvas中不能完美呈现原画面样式