簡體   English   中英

如何使用crome.js 允許用戶上傳他們的個人資料圖片?

[英]How can I use cropme.js to allow users upload their profile image?

這是一個知識共享問答。

Cropme是一個不錯的 JS 插件,用於使用可視滑塊裁剪和旋轉圖像。 作者提供了很好的文檔,但是構建一個有效的實現並不像它應該的那么簡單。

我想回答的問題是這樣的:

我想允許我的網站用戶上傳他們的個人資料圖片。 該圖像必須恰好為 240x292 像素。 用戶應該能夠縮放和旋轉他們的圖像,然后將其裁剪為特定尺寸並將其上傳到我的網站。 我怎么能用crome做所有這些?

這些是需要的步驟:

  1. 為我們希望用戶加載的圖像顯示一個空的占位符。
  2. 通過單擊“獲取圖像”按鈕,用戶可以 select 從其本地文件中獲取圖像。
  3. 所選文件被加載到 memory 中,並使用“cropme”進行編輯。 用戶可以使用視覺滑塊來旋轉和放大/縮小
  4. 點擊“裁剪”后,用戶會看到裁剪后的圖像,用戶可以決定是保存還是取消。
  5. 點擊“保存”后,裁剪后的圖片上傳到PHP服務器,模態window關閉,占位圖片替換為剛剛上傳圖片的鏈接。

那么我們該怎么做呢?

Cropme modal-popup 用於即時編輯

此處提供了一個完整的演示:

https://codepen.io/ishahak/pen/XWjVzLr

我將逐步解釋一些細節。

注意:通常在我的代碼中,當您看到obj[0]時,它只是從 jQuery object 轉換為簡單的 JS object。

1. 顯示圖像的占位符。

我們可以使用以下代碼即時創建真正的 SVG 圖像:

getImagePlaceholder: function(width, height, text) {
  //based on https://cloudfour.com/thinks/simple-svg-placeholder/
  var svg = '\
    <svg xmlns="http://www.w3.org/2000/svg" width="{w}" \
    height="{h}" viewBox="0 0 {w} {h}">\
    <rect fill="#ddd" width="{w}" height="{h}"/>\
    <text fill="rgba(0,0,0,0.5)" font-family="sans-serif"\
    font-size="30" dy="10.5" font-weight="bold"\
    x="50%" y="50%" text-anchor="middle">{t}</text>\
    </svg>';
  var cleaned = svg
    .replace(/{w}/g, width)
    .replace(/{h}/g, height)
    .replace('{t}', text)
    .replace(/[\t\n\r]/gim, '') // Strip newlines and tabs
    .replace(/\s\s+/g, ' ') // Condense multiple spaces
    .replace(/'/gim, '\\i'); // Normalize quotes

  var encoded = encodeURIComponent(cleaned)
    .replace(/\(/g, '%28') // Encode brackets
    .replace(/\)/g, '%29');

  return 'data:image/svg+xml;charset=UTF-8,' + encoded;
}

2.通過單擊“獲取圖像”按鈕,用戶可以從其本地文件中獲取圖像。

這個過程涉及一個“文件”類型的輸入元素,它沒有可見的外觀(我們使用“d-none”類設置它),以及一個“點擊”它以打開對話框的按鈕元素:

  <button id="btnGetImage" class="btn btn-primary">Get Image</button>
  <input class="d-none" type="file" id="fileUpload" accept="image/*" />

以及相關代碼:

$('#btnGetImage').on('click', function(){
  //force 'change' event even if repeating same file:
  $('#fileUpload').prop("value", ""); 
  $('#fileUpload').click();
});
$('#fileUpload').on('change', function(){
  CiM.read_file_from_input(/*input elem*/this, function() {
    console.log('image src fully loaded');
    $('#imgModal-dialog').modal('show');
  });           
});    

當一個文件被選中時,'change' 事件被觸發,導致我們將文件讀入 memory。

3. 將選中的文件加載到 memory 中,並使用“cropme”進行編輯。 用戶可以使用視覺滑塊來旋轉和放大/縮小

我們上面提到的read_file_from_input是這樣實現的:

imgHolder: null,
imgHolderCallback: null,
read_file_from_input: function(input, callback) {
  if (input.files && input.files[0]) {
      imgHolderCallback = callback;
      var reader = new FileReader();
      if (!CiM.imgHolder) {
        CiM.imgHolder = new Image();
        CiM.imgHolder.onload = function () {
           if (imgHolderCallback) { 
             imgHolderCallback();
           }
        }
      }
      reader.onload = function (e) {
        console.log('image data loaded!');
        CiM.imgHolder.src = e.target.result; //listen to img:load...
      }
      reader.readAsDataURL(input.files[0]);
  }
  else {
    console.warn('failed to read file');
  }
}

當 FileReader 准備好時,我們為我們的內部圖像持有者設置src ,並等待“加載”事件,這表明img元素已准備好接收新內容。

我們監聽那個“加載”事件,當觸發時我們顯示模態。 Bootstrap 中的模式有幾個事件。 我們聽那個表示模態顯示的信號,這意味着寬度和設置,我們可以根據它來計划我們的 Cropme 尺寸。

update_options_for_width: function(w) {
  var o = CiM.opt, //shortcut
      vp_ratio = o.my_final_size.w / o.my_final_size.h,
      h, new_vp_w, new_vp_h;
  w = Math.floor(w * 0.9);
  h = Math.floor(w / o.my_win_ratio);
  o.container.width = w;
  o.container.height = h;
  new_vp_h = 0.6 * h;
  new_vp_w = new_vp_h * vp_ratio;
  // if we adapted to the height, but it's too wide:
  if (new_vp_w > 0.6 * w) { 
    new_vp_w = 0.6 * w;
    new_vp_h = new_vp_w / vp_ratio;
  }
  new_vp_w = Math.floor(new_vp_w);
  new_vp_h = Math.floor(new_vp_h);
  o.viewport.height = new_vp_h;
  o.viewport.width = new_vp_w;    
}

我們等待設置模態框的大小,因為必須使用特定的視口尺寸設置crome 在我們的showed.bs.modal處理程序結束時,我們創建我們的Cropme實例。

4、點擊“裁剪”后,用戶會看到裁剪后的圖像,用戶可以決定是保存還是取消。

這是保存按鈕處理程序:

$('#imgModal-btnSave').on('click', function(){
  uploadImage(croppedImg[0], function(path_to_saved) {
    savedImg[0].src = path_to_saved;
    $('#imgModal-dialog').modal('hide');
  });
});

uploadImage function 是這樣的:

uploadImage: function(img, callback){
  var imgCanvas = document.createElement("canvas"),
  imgContext = imgCanvas.getContext("2d");

  // Make sure canvas is as big as the picture (needed??)
  imgCanvas.width = img.width;
  imgCanvas.height = img.height;

  // Draw image into canvas element
  imgContext.drawImage(img, 0, 0, img.width, img.height);

  var dataURL = imgCanvas.toDataURL();

  $.ajax({
    type: "POST",
    url: "save-img.php", // see code at the bottom
    data: { 
       imgBase64: dataURL
    }
  }).done(function(resp) {
    if (resp.startsWith('nok')) {
      console.warn('got save error:', resp);
    } else {
      if (callback) callback(resp);
    }
  });
}

它與一個簡單的 PHP 腳本相匹配,該腳本出現在 codepen 中HTML的末尾。 我認為這個答案太長了,所以我會在這里完成。

祝你好運 - 玩得開心:)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM