2016-05-19 19 views
3

希望這不會被標記爲重複項,因爲沒有任何其他q /因爲SO已幫助我解決此問題,所以我認爲我需要更具體的幫助線。jCrop在更改圖像時使用正確的座標調整大小

我在我的網站上有一個個人資料頁面,允許用戶在沒有頁面重新加載(通過AJAX/jQuery)的情況下更改他們的個人資料圖片。

這一切工作正常。用戶打開「更改個人資料圖片」模式,選擇要上傳的文件並按下「裁剪此圖像」。當按下這個按鈕時,它使用發送文件和formData(我附加文件數據)的典型方式將文件上傳到網站。

它被送到後端有以下的jQuery:

// Upload the image for cropping (Crop this Image!) 
$("#image-upload").click(function(){ 

    // File data 
    var fileData = $("#image-select").prop("files")[0]; 

    // Set up a form 
    var formData = new FormData(); 

    // Append the file to the new form for submission 
    formData.append("file", fileData); 

    // Send the file to be uploaded 
    $.ajax({ 

     // Set the params 
     cache: false, 
     contentType: false, 
     processData: false, 

     // Page & file information 
     url: "index.php?action=uploadimage", 
     dataType: "text", 
     type: "POST", 

     // The data to send 
     data: formData, 

     // On success... 
     success: function(data){ 

      // If no image was returned 
      // "not-image" is returned from the PHP script if we return it in case of an error 
      if(data == "not-image"){ 
       alert("That's not an image, please upload an image file."); 
       return false; 
      } 

      // Else, load the image on to the page so we don't need to reload 
      $(profileImage).attr("src", data); 

      // If the API is already set, then we should apply a new image 
      if(jCropAPI){ 
       jCropAPI.setImage(data + "?" + new Date().getTime()); 
      } 

      // Initialise jCrop 
      setJCrop(); 

      //$("#image-profile").show(); 
      $("#send-coords").show(); 
     } 
    }) 
}); 

setJcrop做以下

function setJCrop(){ 

    // Get width/height of the image 
    var width = profileImage.width(); 
    var height = profileImage.height(); 

    // Var containing the source image 
    var imgSource = profileImage.attr("src"); 

    // New image object to work on 
    var image = new Image(); 
    image.src = imgSource; 

    // The SOURCE (ORIGINAL) width/height 
    var origWidth = image.width; 
    var origHeight = image.height; 

    // Set up the option to jCrop it 
    $(profileImage).Jcrop({ 
     onSelect: setCoords, 
     onChange: setCoords, 
     setSelect: [0, 0, 51, 51], 
     aspectRatio: 1,    // This locks it to a square image, so it fits the site better 
     boxWidth: width, 
     boxHeight: height,   // Fixes the size permanently so that we can load new images 
    }, function(){jCropAPI = this}); 

    setOthers(width, height, origWidth, origHeight); 
} 

一旦後端,它執行以下操作:

public function uploadImage($file){ 

    // See if there is already an error 
    if(0 < $file["file"]["error"]){ 
     return $file["file"]["error"] . " (error)"; 
    }else{ 

     // Set up the image 
     $image = $file["file"]; 
     $imageSizes = getimagesize($image["tmp_name"]); 

     // If there are no image sizes, return the not-image error 
     if(!$imageSizes){ 
      return "not-image"; 
     } 

     // SIZE LIMIT HERE SOON (TBI) 

     // Set a name for the image 
     $username = $_SESSION["user"]->getUsername(); 
     $fileName = "images/profile/$username-profile-original.jpg"; 

     // Move the image which is guaranteed a unique name (unless it is due to overwrite), to the profile pictures folder 
     move_uploaded_file($image["tmp_name"], $fileName); 

     // Return the new filename 
     return $fileName; 
    } 
} 

然後,用戶用選擇器在圖像上選擇他們的區域,並按下「更改個人資料圖片」以下

// Send the Coords and upload the new image 
$("#send-coords").click(function(){ 

    $.ajax({ 
     type: "POST", 
     url: "index.php?action=uploadprofilepicture", 
     data: { 
      coordString: $("#coords").text() + $("#coords2").text(), 
      imgSrc: $("#image-profile").attr("src") 
     }, 
     success: function(data){ 
      if(data == "no-word"){ 
       alert("Can not work with this image type, please try with another image"); 
      }else{ 

       // Append a date to make sure it reloads the image without using a cached version 
       var dateNow = new Date(); 
       var newImageLink = data + "?" + dateNow.getTime(); 
       $("#profile-picture").attr("src", newImageLink); 

       // Hide the modal 
       $("#profile-picture-modal").modal("hide"); 
      } 
     } 
    }); 
}) 

後端是:

public function uploadProfilePicture($coordString, $imgSrc){ 

    // Target dimensions 
    $tarWidth = $tarHeight = 150; 

    // Split the coords in to an array (sent by a string that was created by JS) 
    $coordsArray = explode(",", $coordString); 

    //Set them all from the array 
    $x =   $coordsArray[0]; 
    $y =   $coordsArray[1]; 
    $width =  $coordsArray[2]; 
    $height =  $coordsArray[3]; 
    $newWidth =  $coordsArray[4]; 
    $newHeight = $coordsArray[5]; 
    $origWidth = $coordsArray[6]; 
    $origHeight = $coordsArray[7]; 

    // Validate the image and decide which image type to create the original resource from 
    $imgDetails = getimagesize($imgSrc); 
    $imgMime = $imgDetails["mime"]; 

    switch($imgMime){ 
     case "image/jpeg": 
      $originalImage = imagecreatefromjpeg($imgSrc); 
      break; 
     case "image/png": 
      $originalImage = imagecreatefrompng($imgSrc); 
      break; 
     default: 
      return "no-work"; 
    } 

    // Target image resource 
    $imgTarget = imagecreatetruecolor($tarWidth, $tarHeight); 
    $img = imagecreatetruecolor($newWidth, $newHeight); 

    // Resize the original image to work with our coords 
    imagecopyresampled($img, $originalImage, 0, 0, 0, 0, 
     $newWidth, $newHeight, $origWidth, $origHeight); 

    // Now copy the CROPPED image in to the TARGET resource 
    imagecopyresampled(
     $imgTarget,  // Target resource 
     $img,   // Target image 
     0, 0,   // X/Y Coords of the target image; this will always be 0, 0 as we do not want any black nothingness 
     $x, $y,   // X/Y Coords (top left) of the target area 
     $tarWidth, 
     $tarHeight,  // width/height of the target 
     $width, 
     $height   // Width/height of the source image crop 
    ); 

    $username = $_SESSION["user"]->getUsername(); 
    $newPath = "images/profile/$username-profile-cropped.jpg"; 

    // Create that shit! 
    imagejpeg($imgTarget, $newPath); 

    // Return the path 
    return $newPath; 
} 

所以基本上這個回報率的新文件的路徑,而它與改變用戶的資料圖片(每次都相同的名稱),並上傳現場在?之後追加一個時間以正確刷新映像(無緩存)。

這一切都可以正常工作,但是如果用戶選擇另一張圖片上傳,在已經上傳一張圖片後,這些座標將全部搞砸(例如他們從50增加到250),並且他們最終裁剪出截然不同的部分圖像,大部分都是黑色的。

真的很抱歉在這個問題的荒謬數量的代碼,但我會很感激誰可能已經解決此問題的任何人的幫助。

一些代碼可能看起來不合適,但這只是我試圖調試它。

謝謝,再次,對於這個問題的大小抱歉。

CNC中

setCoords()setOthers()功能看起來像這樣:

//Set the coords with this method, that is called every time the user makes/changes a selection on the crop panel 
function setCoords(c){ 
    $("#coords").text(c.x + "," + c.y + "," + c.w + "," + c.h + ","); 
} 

//This one adds the other parts to the second div; they will be concatenated in to the POST string 
function setOthers(width, height, origWidth, origHeight){ 
    $("#coords2").text(width + "," + height + "," + origWidth + "," + origHeight); 
} 
+0

你的'setCoords'函數是什麼樣的? –

+0

編輯這個問題的亞:) –

回答

1

我現在已經解決了這個問題。

對我來說問題是,當使用setJCrop(); - 它沒有重新加載圖像。原因是上載並加載到JCrop窗口的圖像每次都有相同的名稱(用戶名作爲前綴,然後是profile-cropped.jpg)。

因此,爲了嘗試解決這個問題,我使用了setImage方法來加載一個全尺寸的圖像。

我身邊這讓通過設置boxWidth/boxHeight PARAMS,但他們只是給我留下的座標每次我在裝了新的圖像時是不正確的問題。

事實證明,這是加載從圖像緩存每次,即使當我在jQuery中使用new Image();

爲了解決這個問題,我現在使用了destroy();在jCropAPI上,然後每次重新初始化它,同時使用setImage();

我在圖像本身的CSS中設置了一個最大寬度,從而阻止它被鎖定到特定的寬度。

接下來的問題是,每次我第二次加載圖像時,它都會在那裏留下舊圖像的寬度/高度,這會使圖像看起來全都偏斜和錯誤。

爲了解決這個問題,我前重新設置圖像的源從新的上載的圖像與$(profileImage).css("width", ""); $(profileImage).css("height", "");重置寬度&圖像的高度,我使用jCrop上,以""

但我仍然在圖像上使用相同的名稱,然後導致它每次從緩存中加載的問題。

我對此的解決方案是在數據庫中添加一個「頭像」列並每次將圖像名稱保存在數據庫中。該圖像被命名爲$username-$time.jpg$username-$time.jpg-cropped.jpg,其中$ username是用戶的用戶名(derp),$ time在PHP內部僅爲time();

這意味着我每次上傳圖片時都會有一個新名稱,所以當對此圖片進行任何調用時,都沒有緩存。

追加像imageName + ".jpg?" + new Date.getTime();工作的一些事情,但後來發送圖像名稱後端時,它不能正常工作,並決定何時追加它/不追加它是一個痛苦,然後有一件事需要它被追加以強制重新加載,但後來附加時它不能正常工作,所以我不得不重新工作。

所以關鍵:(TL; DR)

不要jCrop使用相同的映像名稱,如果要加載一個新的形象;上傳一個不同名稱的圖像,然後參考那個。高速緩存問題是一種痛苦,如果不每次都使用新名稱,就不能真正解決它們,因爲這確保了絕對沒有問題(只要名稱始終是唯一的)。

然後,當你初始化jCrop時,如果有的話,請事先銷燬前一個。使用max-width代替width的圖像上,從鎖寬度阻止它,並重新設置圖像的寬度/高度,如果您加載到同一<img><div>

希望一個新的這可以幫助別人!

0

我用jcrop,我認爲這已經發生在我身上。當有新的圖像時,你必須「重置」jcrop。嘗試是這樣的:

function resetJCrop() 
{ 
    if (jCropAPI) { 
     jCropAPI.disable(); 
     jCropAPI.release(); 
     jCropAPI.destroy(); 
    } 
} 

$("#image-upload").click(function(){ 

    success: function(data){ 
    ... 

    resetJCrop(); // RESETTING HERE 

    // If the API is already set, then we should apply a new image 
    if(jCropAPI){ 
     jCropAPI.setImage(data + "?" + new Date().getTime()); 
    } 

    // Initialise jCrop 
    setJCrop(); 

    ... 
    } 
}); 

我不記得爲什麼我在我的具體情況使用禁用()和Release()和destroy()的細節。可能你只能使用其中的一種。試試吧,看看它是否適合你!

+0

不幸的是,我仍然有同樣的問題:( –

相關問題