我想将简单的矩形图像绘制到画布上。我有四点像;
渲染的矩形和图像如下;
这样做的最佳做法是什么?
答案 0 :(得分:0)
那很有趣。十多年来没有做过软件纹理映射。怀旧是伟大的,但openGL更好。 :d
基本上,我们的想法是绘制图像的垂直切片。 ctx只允许我们通过垂直或水平拉伸来绘制图像或部分图像。因此,为了解决这个问题,我们将图像分成垂直切片,拉伸每个切片以填充1像素宽的矩形以及从上边缘到下边缘。
首先,我们计算顶部和底部边缘的斜率。这对应于沿+ X方向行进的每个像素的边缘上升(或下降)的量。接下来,由于图像可能比要绘制的图像更大或更小,我们必须计算条带在画布中X方向对应1个像素的宽度。
注意 ,它不是透视图正确的。画布上右侧的每个步骤表示图像上相同宽度切片的一个步骤 - 透视正确的映射将逐步改变图像宽度的数量。随着图像越来越接近,图像越远离我们越远。
最后,应该注意的是,对输入的坐标做了一些假设。
坚持这些假设,我得到以下结论:
<强>结果强>
<强>代码:强>
<!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图片: