切割图像上的不规则形状 [英] Cutting irregular shape on image

查看:188
本文介绍了切割图像上的不规则形状的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用canvas clip()方法将图像剪切成特定的形状。

I am trying to cut an image into a particular shape using the canvas clip() method.

我已按照以下步骤执行此操作:

I have followed the following steps to do so:


  1. 绘制一个矩形。

  2. 在每一边画半圆圈。右半圆和右半圆向外突出,左半圆和上半圆是向内的。

下面提供了代码段:

var canvasNode = this.hasNode();
var ctx = canvasNode && canvasNode.getContext('2d');

var image = new Image();
image.onload = function() {
  ctx.drawImage(image, 0, 0, 512, 384);
};

image.src = "images/image.png";
var startX = 200;
var startY = 0;

var rectWidth = 150;
var rectHeight = 150;
var radius = 30;

//Main Rect
ctx.rect(startX, startY, rectWidth, rectHeight);

//Right arc
ctx.moveTo(startX+=rectWidth, startY+=(rectHeight/2));
ctx.arc(startX, startY, radius, 3 * Math.PI / 2, Math.PI / 2, false);

//Left arc
ctx.moveTo(startX-=(rectWidth / 2), startY+=(rectHeight / 2));
ctx.arc(startX, startY, radius, 0, Math.PI, true);

ctx.moveTo(startX-=(rectWidth / 2), startY-=(rectWidth / 2));
ctx.arc(startX, startY, radius, 3 * Math.PI / 2, Math.PI / 2, false);

ctx.clip();

我使用的图片大小为800 x 600(png)。请帮助我理解我在这里做错了什么。

The image that I am using is of size 800 x 600 (png). Please help me understand what I am doing wrong here.

推荐答案

首先,你为什么要使用 clip ?您目前只是绘制半圆,无需剪辑

Firstly, why are you using clip? You are currently just drawing semicircles, which works without clip.

其次,您正在创建路径和剪裁,但是你永远不会走这条路。结果,你不会在屏幕上看到任何东西。

Secondly, you are creating paths and clipping, but you never stroke the path. As a result, you won't see anything on the screen.

如果你只是笔划而不是剪辑,它对我来说部分起作用: http://jsfiddle.net/r6yAN/ 。你没有包括顶部的半圆。

If you just stroke instead of clip, it works partially for me: http://jsfiddle.net/r6yAN/. You did not include the top semicircle though.

编辑:看起来你没有使用最好的裁剪方式。您绘制一个矩形,但这也包括半圆形的一条线。如果你像这样画自己的每一条线/弧线你会更好: http://jsfiddle.net/ CH6qB / 6 /

It seems like you're not using the best way of clipping. You draw a rectangle, but this also includes a line in the semicircle. You'd be better off if you draw each line/arc yourself like this: http://jsfiddle.net/CH6qB/6/.

主要想法是从这个图像中的点到点移动:

The main idea is to move from point to point as in this image:

首先从(startX,startY),然后一行到(startX + lineWidth,startY),然后一个弧(startX + rectWidth / 2,startY) pi 0 (逆时针)等等。

So first start at (startX, startY), then a line to (startX + lineWidth, startY), then an arc at (startX + rectWidth / 2, startY) from pi to 0 (counterclockwise), etc.

如果你想在绘制图像后也画出路径,最好再次解开。否则,笔画的质量不会很好。

If you want to stroke the path as well after having drawn the image, it is a good idea to unclip again. Otherwise, the stroke will not be of great quality.

var canvasNode = document.getElementById('cv');
var ctx = canvasNode && canvasNode.getContext('2d');

var image = new Image();
image.onload = function() {
    // draw the image, region has been clipped
    ctx.drawImage(image, startX, startY);

    // restore so that a stroke is not affected by clip
    // (restore removes the clipping because we saved the path without clip below)
    ctx.restore();
    ctx.stroke();
};

image.src = "http://www.lorempixum.com/200/200/";

var startX = 200;
var startY = 0;

var rectWidth = 150;
var rectHeight = 150;
var radius = 30;

var lineWidth  = rectWidth  / 2 - radius;
var lineHeight = rectHeight / 2 - radius;

// typing pi is easier than Math.PI each time
var pi = Math.PI;

ctx.moveTo(startX, startY);

ctx.lineTo(startX + lineWidth, startY);
ctx.arc(startX + rectWidth / 2, startY,
        radius,
        pi, 0, true);
ctx.lineTo(startX + rectWidth, startY);

ctx.lineTo(startX + rectWidth, startY + lineHeight);
ctx.arc(startX + rectWidth, startY + rectHeight / 2,
        radius,
        -pi / 2, pi / 2, false);
ctx.lineTo(startX + rectWidth, startY + rectHeight);

ctx.lineTo(startX + rectWidth - lineWidth, startY + rectHeight);
ctx.arc(startX + rectWidth / 2, startY + rectHeight,
        radius,
        0, pi, false);
ctx.lineTo(startX, startY + rectHeight);

ctx.lineTo(startX, startY + rectHeight - lineHeight);
ctx.arc(startX, startY + rectHeight / 2,
        radius,
        pi/2, pi*3/2, true);
ctx.lineTo(startX, startY);

ctx.save(); // Save the current state without clip

ctx.clip();

这篇关于切割图像上的不规则形状的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆