简体   繁体   English

用点在画布上绘制图像

[英]Draw image to canvas with points

I want to draw simple rectangle image to canvas. 我想在画布上绘制简单的矩形图像。 I have a four point like a; 我有四个要点:

  • (0) 345,223 (0)345,223
  • (1) 262,191 (1)262,191
  • (2) 262,107 (2)262,107
  • (3) 347,77 (3)347,77

Rendered rectangle and image are bellow; 渲染的矩形和图像如下所示;

给予图片

What is the best practice to do this? 最佳做法是什么?

Well that was some fun. 好吧,那很有趣。 Haven't done software texture mapping in over 10 years. 十多年来没有做过软件纹理映射。 Nostalgia is great, but openGL is better. 怀旧很棒,但是openGL更好。 :D :D

Basically, the idea is to draw vertical slices of the image. 基本上,该想法是绘制图像的垂直切片。 The ctx only lets us draw images or parts of them with vertical or horizontal stretching. ctx仅允许我们以垂直或水平拉伸方式绘制图像或图像的一部分。 So, to get around this, we divide the image up into vertical slices, stretching each of them to fill a rectangle 1 pixel wide and from the top edge to the bottom edge. 因此,要解决此问题,我们将图像分成垂直切片,将每个切片拉伸以填充一个1像素宽的矩形(从顶部边缘到底部边缘)。

First, we calculate the slope of the top and bottom edges. 首先,我们计算上下边缘的斜率。 This corresponds to the amount that the edge rises (or falls) for each pixel travelled in the +X direction. 这对应于沿+ X方向行进的每个像素,边缘上升(或下降)的量。 Next, since the image may be larger or smaller than the are it will be draw onto, we must calculate how wide the strips are that correspond to 1 pixel in the X direction in the canvas. 接下来,由于图像可能大于或小于将在其上绘制的图像,因此我们必须计算对应于画布中X方向上1个像素的条带的宽度。

Note , it isn't perspective-correct. 注意 ,它不是透视正确的。 Each step to the right on the canvas represents a step of the same width slice on the image - perspective correct mapping would step by varying amounts across the width of the image. 画布右侧的每个步骤代表图像上相同宽度切片的步骤-透视图正确映射将通过改变图像宽度上的量来逐步进行。 Less as the image got closer, more as the image was further away from us. 随着图像距离的增加,图像变得越来越少,而离我们图像的距离越来越远。

Finally, it should be noted that there are a few assumptions made about the entered coordinates. 最后,应注意,对输入的坐标有一些假设。

  1. The coords appear as pairs of x and y 坐标显示为x和y对
  2. The coords list starts with the top-left corner 坐标列表从左上角开始
  3. The coords must be listed in a clockwise direction 必须按顺时针方向列出坐标
  4. The left-edge and the right-edge must be vertical. 左边缘和右边缘必须垂直。

With these assumptions adhered to, I get the following: 遵循这些假设,我得到以下信息:

Result 结果 在此处输入图片说明

Code: 码:

<!DOCTYPE html>
<html>
<head>
<script>
function byId(e){return document.getElementById(e);}
function newEl(tag){return document.createElement(tag);}

window.addEventListener('load', onDocLoaded, false);

function onDocLoaded()
{
    var mImg = newEl('img');
    mImg.onload = function() { stretchImage(this, quadPoints, byId('tgtCanvas') ); }
    mImg.src = imgSrc;
}

var quadPoints = [ [262,107], [347,77], [347,223], [262,191]  ];
var imgSrc = "img/rss128.png";

function stretchImage(srcImgElem, points, canvasElem)
{
    var ctx = canvasElem.getContext('2d');

    var yTopStart = points[0][1];
    var yTopEnd = points[1][1];
    var tgtWidth = points[1][0] - points[0][0];
    var dX = tgtWidth;
    var topDy = (yTopEnd-yTopStart) / dX;

    var yBotStart = points[3][1];
    var yBotEnd = points[2][1];
    tgtWidth = points[2][0] - points[3][0];
    dX = tgtWidth;
    var botDy = (yBotEnd-yBotStart) / dX;

    var imgW, imgH, imgDx;
    imgW = srcImgElem.naturalWidth;
    imgH = srcImgElem.naturalHeight;
    imgDx = imgW / dX;

    var curX, curYtop, curYbot, curImgX;
    var i = 0;
//  ctx.beginPath();
    for (curX=points[0][0]; curX<points[1][0]; curX++)
    {
        curYtop = yTopStart + (i * topDy);
        curYbot = yBotStart + (i * botDy);

        curImgX = i * imgDx;

//      ctx.moveTo(curX, curYtop);
//      ctx.lineTo(curX, curYbot);

        var sliceHeight = curYbot - curYtop;
//      console.log(sliceHeight);
        ctx.drawImage(srcImgElem, curImgX, 0, 1,imgH, curX, curYtop, imgDx, sliceHeight);

        i++;
    }
//  ctx.closePath();
//  ctx.stroke();
}

</script>
<style>
canvas
{
    border: solid 1px black;
}
</style>
</head>
<body>
    <canvas width=512 height=512 id='tgtCanvas'></canvas>
</body>
</html>

Src image: 来源图片: 在此处输入图片说明

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

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