我的后端是PHP,我需要一种方法来反映服务器端操纵中的UI选择。
我在我的图像中心有一个150x150的正方形,正如链接的Croppie示例所示。但是,正如您可以看到的那样,您可以移动和缩放图像,这意味着从Imagick的中心进行裁剪并不总是有效,具体取决于用户如何将其图像定位在中心点周围。
我知道我可以缩放图像,然后在Imagick中从中心进行裁剪,但是如何考虑到图像也将被平移?
当我在我的实现中移动图像时,我得到以下数据点以解析并发送到服务器:
{transform: "translate3d(-60px, -121px, 0px) scale(1)"}
例如,这显示图像已沿X和Y轴移动,并且未缩放。我如何相应地在Imagick中移动图像的中心?
谢谢!
编辑:
我看到这些命令: Imagick::cropThumbnailImage 和 Imagick::cropImage,有没有一种方法将它们结合起来,在图片缩放时保持剪裁区域居中,并且可以在x或y轴上移动图像?
编辑2:
好的,我找到了需要使用Imagick::cropImage和Imagick::scaleImage的组合,但我无法找出发送到服务器的正确数学公式。
我附上一张图片,让你看看我的意思,我已经非常接近了,但是某些图片的剪裁位置不对:
我的HTML如下:
<div class="viewBox">
<img class="bigTuna">
<div class="enclosedCrop small"></div>
<div class="overlay small"></div>
</div>
您所看到的图片,我想使用
.encloseCrop.small
进行裁剪,它是一个圆形,而这张图片是.bigTuna
。我正在使用以下代码计算图像的偏移量(我可以将其拖动到
.encloseCrop.small
周围),相对于图像的比例(.bigTuna
)。 .encloseCrop.small
的偏移量是.viewBox
,而图像占据了整个.viewBox
,具有max-width: 100%;
由于图像具有width
,naturalWidth
和getBoundingClientRect().width
(以及相应的高度属性),我不确定如何完成此操作,以便我可以仅向Imagick发送X
和Y
作为cropImage()
参数。这是我最接近的方法:
var Xvalue = (angular.element(".enclosedCrop")[0].offsetLeft + ( -1 * $scope.matrixobject.x )) * ((angular.element('.bigTuna')[0].getBoundingClientRect().width/angular.element('.bigTuna')[0].width)*(angular.element('.bigTuna')[0].naturalWidth/angular.element('.bigTuna')[0].width));
var Yvalue = (angular.element(".enclosedCrop")[0].offsetTop + ( -1 * $scope.matrixobject.y )) * ((angular.element('.bigTuna')[0].getBoundingClientRect().height/angular.element('.bigTuna')[0].height)*(angular.element('.bigTuna')[0].naturalHeight/angular.element('.bigTuna')[0].height));
边界宽度除以宽度是比例因子,但我认为还需要考虑自然宽度。问题在于,在类似于指令所在的模态窗口中看到的图像已经按比例缩放,因为它不是自然尺寸。此外,我正在使用CSS变换再次缩放(已经)缩放的图像。
但是当我将图像发送到PHP时,它不知道这一点。我只收到自然尺寸并想知道如何裁剪它。我需要该裁剪反映UI裁剪。 $scope.matrixobject.x是图像的变换值,即左移的像素数量。我可以很好地获得所有这些值,我只是不知道实际上使用这些值的正确方程式是什么。
编辑3:
我已经修改了我的方程式,但是这个方程式虽然对我来说最有意义,但给我带来了完全错误的裁剪。
var Xvalue = (angular.element(".enclosedCrop")[0].offsetLeft + ( -1 * $scope.matrixobject.x )) * (angular.element('.bigTuna')[0].naturalWidth/angular.element('.bigTuna')[0].getBoundingClientRect().width);
var Yvalue = (angular.element(".enclosedCrop")[0].offsetTop + ( -1 * $scope.matrixobject.y )) * (angular.element('.bigTuna')[0].naturalHeight/angular.element('.bigTuna')[0].getBoundingClientRect().height);
该方程首先试图获取150 x 150圆形(
.enclosedCrop
)相对于图像容器顶部和左侧的偏移量:
在高度方面,情况如下:
angular.element(".enclosedCrop")[0].offsetTop + ( -1 * $scope.matrixobject.y )
方程式摘录的第一部分获取了.enclosedCrop
的offsetTop
,由于它本身位于容器中心而保持不变。 $scope.matrixobject.y
是图像围绕容器的变换,通过反转它,我们可以获得所需的变换,如果.enclosedCrop
移动到图像上,则可以将其添加到偏移量中,我们就知道了图像上发生裁剪的位置。
然而,偏移量和变换是相对于容器中图像的大小(max-width:100%
)的,这意味着它们需要缩放以反映图像的自然大小和使用CSS scale
属性可能发生的任何变换。
因此,我将偏移量乘以此值:
* (angular.element('.bigTuna')[0].naturalHeight/angular.element('.bigTuna')[0].getBoundingClientRect().height);
自然高度除以图像高度。重要的是,这个“图像高度”是由
getBoundingClientRect()
得出的,这意味着它考虑了CSS缩放。那么我的逻辑有什么问题?我得到的裁剪结果遍布整个图像,而不是我指定的坐标。
编辑4:
根据以下方程式,我得到了非常接近的答案,但我并不真正理解(从Croppie的源代码中得到)。
var Xvalue = angular.element(".enclosedCrop")[0].getBoundingClientRect().left - angular.element(".bigTuna")[0].getBoundingClientRect().left + angular.element(".enclosedCrop")[0].offsetWidth + (angular.element(".enclosedCrop")[0].getBoundingClientRect().width - angular.element(".enclosedCrop")[0].offsetWidth) / 2;
var Yvalue = angular.element(".enclosedCrop")[0].getBoundingClientRect().top - angular.element(".bigTuna")[0].getBoundingClientRect().top + angular.element(".enclosedCrop")[0].offsetHeight + (angular.element(".enclosedCrop")[0].getBoundingClientRect().height - angular.element(".enclosedCrop")[0].offsetHeight) / 2;
Xvalue = parseFloat(Xvalue).toFixed(0);
Yvalue = parseFloat(Yvalue).toFixed(0);
然而,它总是少几个像素,通常稍微向下和向右。有人能解释一下这个方程式,以便我可以更好地编辑它并找到错误吗?
<canvas>
在客户端生成图像。 - bato3