从可变中心点

时间:2017-10-16 16:50:42

标签: php angularjs image math imagick

我正在构建Croppie的实现作为AngularJS指令,以便为用户提供用于裁剪其个人资料图像的UI。

我的后端是PHP,我需要一种方法让UI选择反映在服务器端操作中。

我的图像中心有150 x 150平方,正如链接的Croppie示例所示。然而,正如您所看到的,您可以移动和缩放图像,这意味着在Imagick中从中心裁剪并不总是有效,具体取决于用户如何将图像定位在中心点周围。

我知道我可以缩放图像,然后在Imagick中从中心裁剪,但我如何解释图像也将被翻译的事实?

当我在我的实现中移动图像时,我得到以下数据点来解析并发送到服务器:

{transform: "translate3d(-60px, -121px, 0px) scale(1)"}

例如,这表示图像已沿X轴和Y轴移动,并且尚未缩放。如何在Imagick中相应地移动图像的中心?

谢谢!

修改

我看到这些命令:Imagick::cropThumbnailImageImagick::cropImage有一些方法可以将它们组合在一起,当裁剪区域保持在中心时,图像会缩放,图像可以在x上移动还是y轴?

编辑2

好吧,我想我需要使用Imagick::cropImageImagick::scaleImage的组合,但我无法确定要发送到服务器的正确数学。

我正在附上一张图片,这样你就可以看到我的意思了,我已经非常接近,但是有些图片上的裁剪是关闭的:

Cropping An Image

我的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%;

因为图片中有widthnaturalWidthgetBoundingClientRect().width以及各个属性的高度 t),我不确定如何在此处完成此操作可以发送给Imagick只有XY 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));

边界宽度除以宽度是比例因子,但我需要以某种方式考虑自然宽度。问题是,您在Croppie - 类指令所在的模态中看到的图像已经缩放,因为它不是自然尺寸。最重要的是,我正在使用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 )

该等式摘录的第一部分得到offsetTop,它将保持不变,因为.enclosedCrop本身在容器的中心是静止的。 $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);

然而,它总是关闭几个像素,通常略微向下和向右。

有人可以解释这个等式,以便我可以更好地编辑它并发现错误吗?

1 个答案:

答案 0 :(得分:0)

css和js的这个棘手的部分。

标记HTML

<div class="viewBox layer-image">
  <img class="bigTuna">
  <div class="enclosedCrop small"></div>
  <div class="overlay small"></div>
</div>

<强>的CSS

.layer-image {
  background-image: url('sample/image.png');
  position: relative;
  height: 800px; /* actual height sample*/
  weight: 800px; /* actual weight sample*/
}

.enclosedCrop.small {
  position: absolute;
}

我们设置类图层具有背景图像和位置作为相对。你知道基本绝对位置是相对的。

<强>的Javascript

对于拖动,调整大小,您可以使用自己喜欢的库或使用自己的代码。最大的问题是如何获得x和y。如果您看到代码,我们已经知道如何获得x y。想象一下x从左上角开始。所以你需要的是从图层中获得.enclosedCrop.small的上边距和.enclosedCrop.small的边距。例如:

var offsetLayerBase = $('.enclosedCrop.small').offset();
var offsetCropping = $('.enclosedCrop.small').offset();
var yPositionCrop = offsetCropping.top - offsetLayerBase.top;
var xPositionCrop = offsetCropping.left - offsetLayerBase.left;

offsetLayerBase设置为窗口的基础(如果有自定义css,则需要任何自定义)。

让我知道是否适合你。干杯;)