如何利用Vue实现图片的马赛克和涂鸦功能?

1. Vue介绍

Vue 是一套用于构建用户界面的渐进式框架。Vue 的核心库只关注视图层。

在本文将讲解如何利用 Vue 和一些其他的库来实现图片的马赛克和涂鸦功能。

2. 马赛克功能实现

2.1. 获取图片信息

首先,接下来要使用的几个库 。我们将使用以下库:

vue

vue-croppie

vue-easy-crop

js-image-mosaic

其中,vue-croppie 和 vue-easy-crop 用于截取图片,而 js-image-mosaic 用于处理马赛克效果。

在 Vue 的 data 上存储选择的图片信息:

data() {

return {

selectedImg: null,

mosaicImg: null,

mosaicSize: 25,

mosaicOpacity: 1,

};

},

在模板中,使用 file input 元素来选择图片:

<template>

<div class="mosaic-demo">

<input type="file" @change="onSelectImg"/>

<div v-if="selectedImg">

<vue-croppie

ref="croppie"

:img="selectedImg"

:viewport="{ width: 200, height: 200, type: 'circle' }"

:boundary="{ width: 300, height: 300 }"

/>

<button type="button" class="mosaic-button" @click="applyMosaic">

Apply Mosaic

</button>

</div>

</div>

</template>

使用 @change 事件在文件选择器中选择图像,然后使用 vue-croppie 组件来确保图像在可见区域内。我们将 onSubmit 方法定义如下:

methods: {

onSelectImg(event) {

this.selectedImg = event.target.files[0];

},

applyMosaic() {

const image = this.$refs.croppie.get().toDataURL();

const img = new Image();

img.onload = () => {

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

canvas.width = img.width;

canvas.height = img.height;

canvas.getContext('2d').drawImage(img, 0, 0);

this.mosaicImg = new JSMosaic(canvas, { size: this.mosaicSize, alpha: this.mosaicOpacity })

.generate();

};

img.src = image;

},

},

在 applyMosaic 方法中,我们拿到之前在 vue-croppie 组件上截取的图像。我们创建了一个新图像标签并将数据 url 设置为图像源。一旦图像加载完毕,我们将其绘制到画布上,并使用 JSMosaic 库创建蒙版图像。

2.2. 显示马赛克效果

在模板中,我们使用 vue-easy-crop 创造一个容器来显示马赛克<img>

 <template>

<div class="mosaic-demo">

<input type="file" @change="onSelectImg"/>

<div v-if="selectedImg">

<vue-croppie

ref="croppie"

:img="selectedImg"

:viewport="{ width: 200, height: 200, type: 'circle' }"

:boundary="{ width: 300, height: 300 }"

/>

<button type="button" class="mosaic-button" @click="applyMosaic">

Apply Mosaic

</button>

<div class="mosaic-result" v-if="mosaicImg">

<vue-easy-crop :image="mosaicImg">

<span aria-hidden="true">{{ $t('scratchArea.label') }}</span>

</vue-easy-crop>

</div>

</div>

</div>

</template>

现在,我们已经使用 vue-croppie 组件截取选择的图像,并使用 JSMosaic 库创建马赛克效果。使用 vue-easy-crop 库可以方便地和美观地显示那幅马赛克图像。

3. 涂鸦功能实现

3.1. 编写样式表

在样式表中,我们编写用于在画布上绘制图形的 CSS 代码。下面是我们的样式表:

.canvas-container::before {

content: "";

display: block;

background-color: rgba(255, 255, 255, 0.5);

position: absolute;

top: 0;

left: 0;

right: 0;

bottom: 0;

z-index: 1;

}

.canvas {

display: block;

position: relative;

z-index: 2;

}

3.2. 创建涂鸦组件

在我们的组件模板中,我们创建了一个图像输入,并将其包装在一个在页面上点击后呈现涂鸦图像的容器中。

 <template>

<div class="draw-container">

<input type="file" @change="onSelectImg" />

<div class="canvas-container" @mousedown="handleMouseDown" @mouseup="handleMouseUp" @mousemove="handleMouseMove">

<canvas ref="canvas" class="canvas" width="600" height="400" />

</div>

</div>

</template>

在 data 中,我们存储希望绘制的图形,在这里放置了一个空对象:

data() {

return {

drawingObject: {},

isMousePressed: false,

image: null

};

},

在处理鼠标活动事件的方法中,我们地几个地方才是相关的件。首先,在 handleMouseDown 方法中,我们设置 isMousePressed 布尔值为 true。

handleMouseDown(e) {

this.isMousePressed = true;

this.drawingObject.color = '#'+Math.floor(Math.random()*16777215).toString(16);

this.drawingObject.size = 2;

this.drawingObject.points = [

{

x: e.offsetX,

y: e.offsetY

}

];

},

然后,在 handleMouseMove中,我们开始绘制选择颜色和大小的方格图形:

handleMouseMove(e) {

if (this.isMousePressed) {

this.drawingObject.points.push({

x: e.offsetX,

y: e.offsetY

});

}

this.draw();

},

在 handleMouseUp 处理程序中,我们将当前建立的图形添加到 drawings 数组中,并将 drawingObject 重置为空对象:

handleMouseUp() {

if (this.isMousePressed) {

this.drawings.push(this.drawingObject);

this.drawingObject = {};

this.isMousePressed = false;

}

},

我们还需要在 mounted 钩子中编写一个方法来将图像加载到画布中:

mounted() {

this.loadImage();

},

methods: {

loadImage() {

if (!this.image) {

return;

}

const canvas = this.$refs.canvas;

const context = canvas.getContext('2d');

const img = new Image();

img.onload = () => {

context.drawImage(img, 0, 0, canvas.width, canvas.height);

};

img.src = this.image;

},

...

},

在 loadImage 方法中,我们检查图像是否存在,如果存在,则将其绘制到画布上,这样就可以在涂鸦之上显示它。

3.3. 绘制图案

最后,我们通过将所有在 drawings 数组中的图形渲染到画布上来完成绘制图案功能。

draw() {

const canvas = this.$refs.canvas;

const context = canvas.getContext('2d');

context.clearRect(0, 0, canvas.width, canvas.height);

this.loadImage();

this.drawings.forEach((drawing) => {

context.beginPath();

context.strokeStyle = drawing.color;

context.lineWidth = drawing.size;

context.moveTo(drawing.points[0].x, drawing.points[0].y);

drawing.points.forEach((point) => {

context.lineTo(point.x, point.y);

});

context.stroke();

context.closePath();

});

},

在绘制函数中,我们使用 canvas 清除画布,然后使用 context.beginPath 确保没有先前的绘图对象残留。接着,我们使用 context.strokeStyle 和 context.lineWidth 设置绘图颜色和线宽。此后,我们使用 moveTo 和 lineTo 将每个点连接到下一个点,并使用 context.stroke 将绘制图案渲染到屏幕上。

4. 结论

在本文中,我们探讨了如何通过使用一些 Vue 库(vue-croppie,vue-easy-crop 和 js-image-mosaic)以及使用 vanilla JavaScript 能快速达到实现图片的马赛克和涂鸦的方式。我希望你能按照这些步骤,完成这个应用,并且能改善它或者利用它来完成自己的项目。