php - Php Imagick来自可变中心点的裁剪图像

标签 php angularjs image math imagick

我正在构建一个Croppie的实现,作为angularjs指令,为用户提供一个ui来裁剪他们的配置文件图像。
我的后端是php,我需要一种在服务器端操作中反映ui选择的方法。
我的图像中心有一个150×150的正方形,如链接的裁剪示例所示。但是,正如您所看到的,您可以移动和缩放图像,这意味着在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(以及各自的高度属性),所以我不确定如何实现这一点,我可以将X参数的YcropImage()发送给imagick。
这是我最近得到的:
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-like指令所在的模式中看到的图像已经缩放,因为它不是自然维度。除此之外,我正在使用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%)相关,这意味着它们需要缩放以反映图像的自然大小以及使用cssscale属性可能发生的任何变换。
所以我把偏移量乘以这个:
* (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);

不过,它总是有几个像素关闭,通常是稍微向下和向右。
有人能解释一下这个公式吗?这样我就可以更好地编辑它并找出错误?

最佳答案

这是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 y从左上角开始。因此,您只需要从图层图像中获取.enclosedCrop.small的页边距顶部和.enclosedCrop.small的页边距左侧。对于EX:
var offsetLayerBase = $('.enclosedCrop.small').offset();
var offsetCropping = $('.enclosedCrop.small').offset();
var yPositionCrop = offsetCropping.top - offsetLayerBase.top;
var xPositionCrop = offsetCropping.left - offsetLayerBase.left;

offsetLayerBase设置为来自窗口的基(如果有css自定义,则需要任何自定义)。
如果为你工作,请告诉我。干杯!)

关于php - Php Imagick来自可变中心点的裁剪图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46775277/

相关文章:

php - PHP 中的关联数组数组

javascript - 尽管验证错误仍提交 Angular 表单

javascript - Restangular POST 总是空的

html - z-index 在 tumblr 上不起作用?图像不断重叠。

php - 搜索查询在 Laravel 中不起作用

php - 函数参数中的 gmdate() 给出解析错误

AngularJS 1.5.x $onChanges 不适用于单向绑定(bind)更改

javascript - 跟踪在 JavaScript 中加载图像的进度

image - 将文本添加到 .jpg/png/gif

php - 用 “CSS” 创建 “PHP”