ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

javascript – 使用偏移原点在Canvas中缩放图像

2019-06-12 00:23:59  阅读:414  来源: 互联网

标签:javascript canvas html image-scaling


我几天来一直在努力解决这个问题.我的问题基于你可以在这里找到的代码 – http://codepen.io/theOneWhoKnocks/pen/VLExPX.在这个例子中你会看到3个图像,第一个是从[0,0]原点开始,第二个是从画布中心开始,第三个是我想要的从偏移图像的中心开始缩放.

基本上我希望图像向上或向下缩放,但保持在角色虹膜上居中.下面你会找到一段控制第三张图像渲染的代码片段.

function renderOffset(){
  var dims = getScaledDims();

  paintBG(ctx3);
  ctx3.drawImage(loadedImg, offsetX, offsetY, dims.width, dims.height);
  drawCenterAxis(ctx3);
}

经过大量的谷歌搜索和浏览论坛,我认为我需要利用transformMatrix,但到目前为止我没有尝试过任何工作.我期待您的任何想法或建议,并感谢您的时间.

进一步澄清

我正在创建一个图像编辑器.对于我在这里呈现的特定用例,用户已将图像移动到左侧108px&高达8px.

var offsetX = -108;
var offsetY = 8;

当用户缩放偏移图像时,我希望它在可视画布区域的中心(红色十字线,或者在这种情况下是字符虹膜)缩放.

更新

我已经更新了codepen链接以指向最终代码.以下是添加列表:

>在接受的答案中提到的一些代码中添加了.
>添加了拖动图像的功能.
>为偏移添加了可视跟踪器.

解决方法:

诀窍是理解规模改变许多变量的方式.首先,它会更改画布上可见的源图像的大小.接下来,这与缩放的期望中心点相结合影响我们应该从图像开始绘制的位置.

在1.0的比例下,所显示的源图像的像素数等于dst画布具有的像素数.即,如果画布是150×150,我们可以看到150×150的输入像素.但是,如果比例是2.0,那么我们希望画出2倍大小的东西.这意味着我们只希望在dst画布的150×150像素上显示src图像的75×75像素.同样,如果我们希望以0.5的比例绘制,我们应该期望看到在dst画布的150×150中显示的src图像的300×300像素.也许你现在可以看到比例尺和画布尺寸之间的关系.

考虑到这一点,我们可以着手确定我们希望看到多少src图像.这很简单:

var srcWidth = canvas.width / scale;
var srcHeight = canvas.height / scale;

现在我们知道将显示多少图像,我们可以设置确定图像中应该从哪里开始绘制.由于我们有一个指定的缩放中心点,我们知道这一点应该始终保持在画布的中心.

如果我们从等式中删除缩放,并使用前面的数字,我们可以看到我们想要显示src图像的150×150像素,并且我们需要开始在我们的中心点的上方和左侧绘制75个像素.这样做将绘制150×150像素的源图像,并将我们的中心点放在画布中间.

如果我们再重新考虑缩放,我们知道我们并不总是要绘制src图像的150×150像素,这意味着我们不能盲目地开始75像素左上方和我们的中心点之上 – 我们将不得不缩放这75个像素.由于这75个像素等于我们将要显示的图像部分宽度的一半和高度的一半,我们可以通过将srcWidth和srcHeight除以2来计算开始绘制图像的点.然后从中心点减去这个值.

这样做给了我们以下表达式:

ctx.drawImage(image, imgCenterX-(srcWidth/2), imgCenterY-(srcHeight/2), srcWidth, srcHeight, 0,0, canvas.width, canvas.height);

当我将这两者放在一个正常运行的样本中时,我最终得到了这个:

"use strict";

var imgOriginX = 182, imgOriginY = 66;

function byId(id,parent){return (parent == undefined ? document : parent).getElementById(id);}
window.addEventListener('load', onDocLoaded, false);
function onDocLoaded()
{
    var targetCanvas = byId('canvas3');
    var srcImage = byId('img1');

    drawImageScaled(targetCanvas, srcImage, imgOriginX, imgOriginY)
    drawCrosshair( byId('canvas3') );

    byId('scaleSlider').addEventListener('input', onScaleSliderChange, false);
}

/*
    code for scaling an image about an arbitrary point
*/

// canvas - target canvas element
// image - target canvas element
// imgCenterX - x coord of point of scaling centre-point (unit: pixels)
// imgCenterY - y coord of point of scaling centre-point (unit: pixels)
// scale - 1.0 = 100%
function drawImageScaled(canvas, image, imgCenterX, imgCenterY, scale)
{
    if (scale === undefined)
        scale = 1.0;

    var ctx = canvas.getContext('2d');
    ctx.clearRect(0,0,canvas.width,canvas.height);

    var srcWidth = canvas.width / scale;
    var srcHeight = canvas.height / scale;
    ctx.drawImage(image, imgCenterX-(srcWidth/2), imgCenterY-(srcHeight/2), srcWidth, srcHeight, 0,0, canvas.width, canvas.height);
}

function drawCrosshair(canvas)
{
    var ctx = canvas.getContext('2d');
    var width, height;
    width = canvas.width;
    height = canvas.height;
        ctx.save();
    ctx.beginPath();
        ctx.moveTo(width/2, 0);
        ctx.lineTo(width/2, height);
        ctx.moveTo(0, height/2);
        ctx.lineTo(width, height/2);
    ctx.closePath();
    ctx.strokeStyle = "red";
    ctx.stroke();
    ctx.restore();
}

function onScaleSliderChange(evt)
{
    var curValue = this.value;
    var scale = curValue / 100;
    var tgt, src;

    tgt = byId('canvas3');
    src = byId('img1');
    drawImageScaled(tgt, src, imgOriginX, imgOriginY, scale);
    drawCrosshair(tgt);
}
input[type=range]
{
    width: 18px;
    height: 122px;
    -webkit-appearance: slider-vertical;
}
canvas
{
    border: solid 1px #888;
}

img{ display:none;}
<img id='img1' src='https://i.stack.imgur.com/aFbEw.png'/>
<hr>
<canvas id='canvas3' width=150 height=150>Canvas not supported. :(</canvas>
<input id='scaleSlider' type="range" class="scale-slider js-scaleSlider" min="0" max="200" value="100" orient="vertical"/>

标签:javascript,canvas,html,image-scaling
来源: https://codeday.me/bug/20190611/1222051.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有