2017-10-16 89 views
4

我正在構建一個Croppie作爲AngularJS指令的實現,以便爲用戶提供一個UI來裁剪他們的配置文件圖像。Php Imagick來自變量中心點的作物圖像

我的後端是PHP,我需要一種方式讓UI選擇反映在服務器端操作中。

我的圖片中心有一個150×150的方塊,因爲相關的Croppie示例同樣顯示。但是,您可以看到,您可以移動和縮放圖像,這意味着在Imagick中從中剪切並不總是有效,這取決於用戶如何將圖像置於中心點周圍。

我知道我可以縮放圖像,然後從Imagick中心剪下,但是我怎麼解釋圖像也會被翻譯的事實呢?

當我在執行中移動的圖像,我得到以下數據點分析和發送到服務器:

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

由此可見例如,圖像已被一起轉移X軸和Y軸,並沒有被縮放。我如何在Imagick中相應地移動圖像的中心?

謝謝!

編輯:

我看到這些命令:Imagick::cropThumbnailImageImagick::cropImage是有一些方法,其中作爲對圖像進行縮放和圖像可以在被轉移的耕地面積保持在中心那種將它們組合x或y軸?

EDIT 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,並且圖像佔據整個.viewBoxmax-width: 100%;

由於圖像具有widthnaturalWidthgetBoundingClientRect().width和相應屬性喚起注意噸)我不能確定如何做到這一點在那裏我可以發送給Imagick一個XYcropImage()參數。

這是我得到的最接近:

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×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); 

但是它始終是幾個像素關閉,通常稍微向下並且向右。

有人可以解釋這個公式,所以我可以更好地編輯它並找到錯誤嗎?

+0

作爲一種替代方法,您可以在客戶端裁剪圖像,並將其發送到服務器 – 2017-10-25 18:23:36

+0

我認爲您應該只在縮放後發送x,y和圖像尺寸。從服務器上的圖像中讀取尺寸,然後計算出您需要的值。 OT:使用''在客戶端生成圖像。 – bato3

+0

@RomanCortes我寧願在服務器端進行裁剪。 –

回答

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。想象一下xy從左上角開始。因此,您需要的是從。-layer圖像獲取.enclosedCrop.small的margin margin和.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定製)。

讓我知道,如果你的工作。乾杯;)

+0

我知道如何再次獲得x和y我有我的UI中的所有變量我只是不知道如何轉換到只獲取原始圖像的服務器,並且需要縮放到自然寬度和高度的座標。 –

+0

請參閱更新的問題。 –

+0

@SummerDeveloper是否要在客戶端或服務器上計算? – hendrathings