简体   繁体   English

绘制图像轮廓的最佳实践

[英]best practice in drawing outline of image

I've tried 3 ways to make it, but the effect doesn't looks well. 我尝试了3种方法来制作它,但效果并不理想。

  1. copy and fill image then make offset. 复制并填充图像,然后进行偏移。 The demo is 该演示是

 var ctx = canvas.getContext('2d'), img = new Image; img.onload = draw; img.src = "http://i.stack.imgur.com/UFBxY.png"; function draw() { var dArr = [-1,-1, 0,-1, 1,-1, -1,0, 1,0, -1,1, 0,1, 1,1], // offset array s = 20, // thickness scale i = 0, // iterator x = 5, // final position y = 5; // draw images at offsets from the array scaled by s for(; i < dArr.length; i += 2) ctx.drawImage(img, x + dArr[i]*s, y + dArr[i+1]*s); // fill with color ctx.globalCompositeOperation = "source-in"; ctx.fillStyle = "red"; ctx.fillRect(0,0,canvas.width, canvas.height); // draw original image in normal mode ctx.globalCompositeOperation = "source-over"; ctx.drawImage(img, x, y); } 
 <canvas id=canvas width=500 height=500></canvas> 
. When the outline width is large, the outline result will be wrong. 当轮廓宽度较大时,轮廓结果将是错误的。

  1. check the edge of image base on the Marching Squares algorithm. 根据Marching Squares算法检查图像的边缘。 When the image shape is circle, the outline is with sawtooth. 当图像形状为圆形时,轮廓带有锯齿。 If make the outline more smoother, it won't fit the sharp shape like star. 如果使轮廓更平滑,将不适合星形之类的尖锐形状。

  2. copy and fill the image then scale it. 复制并填充图像,然后进行缩放。 When a image width is not equal with height, it doesn't work. 当图像宽度与高度不相等时,它将不起作用。

You can try with a math approach, without the offset array 您可以尝试使用数学方法,而无需偏移数组

 var ctx = canvas.getContext('2d'), img = new Image; img.onload = draw; img.src = "http://i.stack.imgur.com/UFBxY.png"; function draw() { var s = 20, // thickness scale x = 5, // final position y = 5; for (i=0; i < 360; i++) ctx.drawImage(img, x + Math.sin(i) * s, y + Math.cos(i) * s); // fill with color ctx.globalCompositeOperation = "source-in"; ctx.fillStyle = "red"; ctx.fillRect(0, 0, canvas.width, canvas.height); // draw original image in normal mode ctx.globalCompositeOperation = "source-over"; ctx.drawImage(img, x, y); } 
 <canvas id=canvas width=500 height=500></canvas> 

My idea comes from the way we draw a circle using a string: 我的想法来自我们使用字符串绘制圆的方式:
https://www.wikihow.com/Draw-a-Perfect-Circle-Using-a-Pin https://www.wikihow.com/Draw-a-Perfect-Circle-Using-a-Pin

Imagine that instead of a pencil at the end of the string we just have a shape 想象一下,我们只是用一个形状代替了字符串末尾的铅笔


Here is a visual comparison of my approach and yours, also I'm showing a third approach scaling the image, there is really not a best one, it's just a matter of personal preference. 这是我和您的方法的视觉比较,同时我正在展示第三种方法来缩放图像,实际上没有最佳方法,这只是个人喜好问题。

You could create a hybrid mode, if the hairline is important to you, get that portion of the image scaling it, then use a different way for the rest of the body. 您可以创建一个混合模式,如果发际线对您很重要,请缩放图像的那一部分,然后对身体的其余部分使用其他方式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM