- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
这几天我一直在为这个问题苦苦挣扎。我的问题基于您可以在此处找到的代码 - http://codepen.io/theOneWhoKnocks/pen/VLExPX .在示例中,您将看到 3 张图像,第一张从 [0,0] 原点缩放,第二张从 Canvas 中心缩放,第三张我想从偏移图像的中心缩放。
基本上我希望图像按比例放大或缩小,但保持在 Angular 色虹膜的中心。您将在下方找到控制第三张图片渲染的代码片段。
function renderOffset(){
var dims = getScaledDims();
paintBG(ctx3);
ctx3.drawImage(loadedImg, offsetX, offsetY, dims.width, dims.height);
drawCenterAxis(ctx3);
}
经过多次谷歌搜索和浏览论坛后,我认为我需要使用 transformMatrix,但到目前为止我尝试过的任何东西都没有奏效。我期待着您的任何想法或建议,感谢您抽出宝贵时间。
进一步说明
我正在创建一个图像编辑器。对于我在此展示的特定用例,用户已将图像向左移动 108 像素并向上移动 8 像素。
var offsetX = -108;
var offsetY = 8;
当用户缩放偏移图像时,我希望它在可视 Canvas 区域的中心缩放(红色十字准线,或者在本例中为字符虹膜)。
更新
我已经更新了 codepen 链接以指向最终代码。以下是添加列表:
最佳答案
诀窍是了解比例改变多个变量的方式。首先,它改变了 Canvas 上可见的源图像的数量。接下来,这与所需的缩放中心点相结合会影响我们应该从图像中的哪个位置开始绘制。
比例为 1.0 时,显示的源图像的像素数等于 dst Canvas 的像素数。也就是说,如果 Canvas 是 150x150,我们可以看到 150x150 的输入像素。但是,如果比例为 2.0,那么我们希望绘制两倍大小的东西。这意味着我们只希望在 dst Canvas 的 150x150 像素上显示 src 图像的 75x75 像素。同样,如果我们希望以 0.5 的比例绘制,我们应该期望看到 300x300 像素的 src 图像显示在 150x150 的 dst Canvas 中。也许您现在可以看到比例和 Canvas 大小之间的关系。
考虑到这一点,我们可以着手确定我们希望看到多少 src 图像。这很简单:
var srcWidth = canvas.width / scale;
var srcHeight = canvas.height / scale;
既然我们知道了将显示多少图像,我们就可以着手确定应该从图像中的什么位置开始绘制了。由于我们有一个指定的缩放中心点,我们知道这个点应该始终保持在 Canvas 的中心。
如果我们从等式中删除缩放比例,并使用之前的数字,我们可以看到我们想要显示 src 图像的 150x150 像素,并且我们需要开始在中心左侧上方 75 像素处绘制 -观点。这样做会绘制 150x150 像素的源图像,并将我们的中心点放在 Canvas 的中间。
如果我们随后重新考虑缩放,我们知道我们并不总是要绘制 src 图像的 150x150 像素,这意味着我们不能盲目地从中心点左侧和上方 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='/image/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 中缩放图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31633355/
我试图弄清楚如何获取所有可见窗口的框架。我尝试了以下代码,但它仅适用于应用程序本身,其他窗口报告 {0,0,0,0} NSArray *windowArray = [NSWindow wind
左矩形=新矩形(0,0,WIDTH/9,HEIGHT);在此代码中,如果我增加宽度,为什么它看起来会进一步延伸到 JFrame 的左侧?如果我减少它为什么它会向右延伸?这不是像坐标平原一样工作吗?高度
假设我有一个 AffineTransform (transform) 并调用它的一堆方法。假设我旋转并平移它。然后我用它转换图形对象 (g2d): g2d.transform(transform);
我认为当你对物体施加力时,它会施加到 body 的原点(可能是质心)。现在我正在尝试创建类似俄罗斯方 block 的 block ,并通过应用 LinearPulse 使它们跳跃,如下所示: body
我正在阅读 Big Nerd Ranch 指南第 4 版,但在处理 View 和 View 层次结构的章节中,我遇到了一些与 View 来源有关的问题。 我已经在我的 View Controller
我想把原点放在中心,所以我做了: SetViewportOrgEx(hdc,width/2,height/2,NULL); (如下面的代码所示) 现在,在实现双缓冲后它似乎无法正常工作。任何想法为什么
当我的 Sprite 旋转原点固定在窗口的左上角时,我遇到了这个问题(与 sprite.Draw 和 sprite.Draw2D 相同)无论哪种方式,如果我改变旋转中心它仍然在左上角。我需要 Spri
有人告诉我,您可以通过以下方式向与当前 Git 分支名称相匹配的远程分支推送和 pull : git push origin HEAD 或 git pull origin HEAD 它以前一直对我有用
我正在使用自定义 View 和 Canvas 在屏幕上绘制对象。 View 位于距屏幕原点的 Y 偏移处。我想平移 Canvas ,然后绘制一个对象。但是,当我使用 setmatrix 平移 Canv
尝试拖动组。为什么 origin 在这里不起作用?注意到当你第一次点击它时它是如何跳跃的吗? JSFIDDLE基于此:http://bl.ocks.org/mbostock/1557377 var d
我正在尝试使用以下立方体的透视视角: http://jsfiddle.net/TrySpace/JvFSQ/5/ 但是我没有按照我的预期去做,我想要改变实际的视角。所以当transformOrigin
我的 OpenShift Origin 安装似乎有问题。 当我获得路由器的端点时,我得到以下信息: oc get endpoints --namespace=default --selector=ro
这是怎么做到的?我正在寻找 iOS7/8 解决方案。 KeyboardWillShow 并不令人满意,因为我需要在键盘实际显示之前根据键盘高度调整 View 大小。 最佳答案 keyboardWill
我正在 iframe 上监听其内容何时发生变化。当它发生时,我想知道内容的当前来源是什么。 我无法访问该内容,因为它违反了相同的域策略,但我只要根据网址或主机知道它显示的内容就可以了。 我可以通过 j
我一直致力于使用 CSS3 创建动画条形图。它在钢筋的两侧运行良好,但钢筋的顶部和底部一直存在问题。 我一直在通过 jQuery 改变它们的 css“高度”属性来缩放边,但我意识到这不是最好的方法。我
Edit3:我的问题与我预期的功能完全不同。我让代码保留下来,也许这对某人有帮助 :)(并且不要忘记调试!)。 我试图找到直线与三角形相交的 vector 。 当前状态:随机交叉,即使鼠标不在地板上和
我需要在原始 View 的坐标中计算 UIView subview 的可见 CGRect。如果比例为 1,我可以正常工作,但如果其中一个 super View 或 View 本身被缩放(收缩),可见的
这个问题类似于以前回答的问题 Fast interpolation over 3D array ,但无法解决我的问题。 我有一个维度为(时间、高度、纬度、经度)的 4D 数组,标记为 y.shape=
我正在制作自定义贴纸包。这是一个 iMessage 扩展应用程序。我继承了 UICollectionView 而不是使用基本的 MSMessagesViewController。因此,只有当我在展开
我使用 CGWindowListCopyWindowInfo 获取所有窗口的列表。它根据屏幕的 左上角 原点为我提供每个窗口的坐标。 如果我使用 NSWindow 的 setFrame 方法,坐标基于
我是一名优秀的程序员,十分优秀!