使用React上載,操縱圖像

zhenghuan 8年前發布 | 24K 次閱讀 React Web框架

下面是由 Damon Bauer 發的一篇帖子,他做著一份很常見的web開發工作: 給用戶提供圖片上傳的方法. 很難說這件事比較簡單, 但是在一些強大的工具幫助下也可以完成這樣的工作, 而且比之前更加容易. demon甚至全部在瀏覽器中完成這項工作 實例 鏈接 ! web開發者常做的一件事情就是提供用戶上傳圖片的解決方案,看上去微不足道的,但是當構建一個上傳組件的時候 需要考慮以下幾點:

  • 你允許用戶上傳什么格式的圖片?

  • 圖片需要保證多大? 這將如何影響性能?

  • 圖片應該是什么樣的長寬比?

  • 圖像將如何組織?不合適的圖像如何被捕獲?

  • 圖片將托管在哪里?如何進行管理?

服務端工具 如 PaperclipImageProcessor 為以上考慮提供了解決方案. 不幸的是,在單頁應用中沒有一個現成的工具可以使用 (我發現). 在這里我將會告訴你如何在 React 應用中不使用后端語言實現它.

下面是我們將會構建的示例圖:

工具包

我用到了以下這些工具:

建立一個 Cloudinary

Cloudinary 是一個基于云的服務,您可以存儲,處理,管理和提供圖像。我選擇使用Cloudinary,因為它有一個免費的版本,包括我需要的所有功能。你至少需要一個免費帳戶上手。

比方說,你要裁切,重新調整和為上傳的圖片加一個篩選器。 Cloudinary有 transformations 的概念,就是它需要和你需要修改的圖像鏈接在一起。上傳后,轉換就會發生,修改和保存新的圖片。

在 Cloudinary 控制臺, 選擇 Settings > Upload 之后 選擇 "Add upload preset" 在上傳預置項中.

在下面的屏幕,修改“模式”為“無簽名”。這是必要的,這樣你可以不使用服務器端語言協商的私鑰上傳到Cloudinary。

通過在“傳入轉換”中選擇“編輯”添加你想要的轉換。在這里,您可以裁剪,調整大小,質量的變化,旋轉,過濾等保存預設,就是這樣!現在,您可以上傳,處理,存儲和圖像服務為您的應用程序。注意 preset ,我們將在以后使用它。現在讓我們繼續前進的代碼。

獲取用戶輸入

為了處理圖像上傳, 我使用了 react-dropzone . 它包括的功能,如拖放,文件類型限制,多文件上傳。

首先,安裝的依賴關系。在命令行中運行:

npm install react react-dropzone superagent --save`

然后在你組件中 引入 React , react-dropzone , 和 superagent . 我使用 the ES6 import 語法:

import React from 'react';
import Dropzone from 'react-dropzone';
import request from 'superagent';

我們之后會使用 superagent . 但現在, 在你組件的渲染方法中, 包括一個 react-dropzone 實例:

export default class ContactForm extends React.Component {

  render() {
    <Dropzone
      multiple={false}
      accept="image/*"
      onDrop={this.onImageDrop.bind(this)}>
      <p>Drop an image or click to select a file to upload.</p>
    </Dropzone>
  }

下面是組件運行的要點:

  • multiple={false} 允許用戶只能一次性上傳一張圖片.

  • accept="image/*" 允許任何種類的圖片.你可以更明確的限制只有特定的文件類型, e.g. accept="image/jpg,image/png" .

  • onDrop 當圖像被上傳的觸發方法.

當時有 React ES5 類 語法 ( React.createClass ), 所有方法都是 "自動綁定" 到類實例. 這篇文章代碼使用ES6類型語法 ( extends React.Component ), 不提供自動綁定. 這是我們為什么使用 .bind(this) 在 onDrop 屬性. (如果你不熟悉 .bind , 你可以 read about it here .

處理圖像拖放

現在,讓我們設置一個圖像上傳之后的方法。

首先, 設置一個 const 包括上傳重要的兩條信息:

  1. 上傳預設ID(在創建上傳預設自動創建)

  2. 你的 Cloudinary 上傳 URL

// import statements

const CLOUDINARY_UPLOAD_PRESET = 'your_upload_preset_id';
const CLOUDINARY_UPLOAD_URL = 'https://api.cloudinary.com/v1_1/your_cloudinary_app_name/upload';

export default class ContactForm extends React.Component {
// render()

接下來,添加組件初始化狀態入口(using this.setState );我稱之為 UploadedFileCloudinaryUrl 。最終,這將持有Cloudinary創建上傳的圖片的URL。稍后,我們將使用這一塊的狀態。

export default class ContactForm extends React.Component {

  constructor(props) {
    super(props);

    this.state = {
      uploadedFileCloudinaryUrl: ''
    };
  }

react-dropzone 文檔狀態 總是會 返回一個上傳文件的數組, 之后我們會傳遞參數到 files 參數 在 onImageDrop 方法. 只要我們允許一次只能傳遞一張圖片, 我們知道,在圖像始終處于所述數組的第一位置.

Call handleImageUpload , 傳遞圖片 ( files[0] ) 到這個方法. 我把它分成幾個獨立的方法, 遵從 Single responsibility principle 的規則. 重要地, 這個原則教你的方法保持緊湊,只做一件事。

export default class ContactForm extends React.Component {

  constructor(props) { ... }

  onImageDrop(files) {
    this.setState({
      uploadedFile: files[0]
    });

    this.handleImageUpload(files[0]);
  }

  render() { ... }

}

處理圖像上載和傳送

首先, 使用 superagent 上傳到 Cloudinary 使用我們之前設置的倆個 const . 使用 .field method 可以對POST請求綁定數據.這個類型的數據包括所有的Cloudinary 處理圖片的信息. 通過調用 .end , 請求被執行 并且會提供一個回調.

export default class ContactForm extends React.Component {

  constructor(props) { ... }

  onImageDrop(files) { ... }

  handleImageUpload(file) {
    let upload = request.post(CLOUDINARY_UPLOAD_URL)
                        .field('upload_preset', CLOUDINARY_UPLOAD_PRESET)
                        .field('file', file);

    upload.end((err, response) => {
      if (err) {
        console.error(err);
      }

      if (response.body.secure_url !== '') {
        this.setState({
          uploadedFileCloudinaryUrl: response.body.secure_url
        });
      }
    });
  }

  render() { ... }

}

在 .end 回調里,我記錄返回的任何錯誤。同時這也可能是最好的方法告訴大家,發生了錯誤。

下一步,我們檢查我們是否收到包含一個URL的響應的非空字符串。如果答案是肯定的,那么圖像上載和操縱和Cloudinary產生一個URL。例如,如果一個用戶編輯他們的個人資料并上傳的圖片,您可以從Cloudinary獲得新的圖像URL并存儲在數據庫中。

因此到目前為止,我已經寫的代碼,用戶可以刪除一個圖像 并且組件將其發送到Cloudinary之后提供變換的圖像URL讓我們使用。

繼續渲染

組件的最后一部分是一個 div 預覽上傳的圖片。

export default class ContactForm extends React.Component {

  constructor(props) { ... }

  onImageDrop(files) { ... }

  handleImageUpload(file) { ... }

  render() {
    <div>
      <div className="FileUpload">
        ...
      </div>

      <div>
        {this.state.uploadedFileCloudinaryUrl === '' ? null :
        <div>
          <p>{this.state.uploadedFile.name}</p>
          <img src={this.state.uploadedFileCloudinaryUrl} />
        </div>}
      </div>
    </div>
  }

三元運算符輸出 null (nothing) 如果 uploadedFileCloudinaryUrl 狀態是一個空的字符串.默認重新調用, 我們設置組件的 uploadedFileCloudinaryUrl 狀態為一個空的字符串; 這意味著當組件渲染了, 這個 div 將會為空.

然而, 當 Cloudinary 回應一個 URL, 狀態不再是一個空的URL, 因為我們在 handleImageUpload 中更新了狀態. 這時, 組件將會重新渲染, 顯示上傳文件的名稱 并且展示修改后的圖像.

打包

這僅僅是一個圖像上傳組件的基礎。還有很多你可以添加的特性,如:

  • 允許上傳多張圖片

  • 刪除上傳的圖片

  • 如果上傳由于某種原因失顯示錯誤

  • 使用移動設備的攝像頭作為上載源

到目前為止,這種設置很適合我的需求。必須硬編碼上傳的預設是不完美的,但我還沒有遇到任何與它相關問題。

幸運地,你已經理解了如何使用React上傳,存儲,并沒有使用的服務器端語言來處理圖像。如果您有任何問題或意見,我很樂意聽到他們的聲音!我創建了一個庫,在這里,你可以 點擊這里 看到.

 

來自:http://www.zcfy.cc/article/image-upload-and-manipulation-with-react-1114.html

 

Save

 

 本文由用戶 zhenghuan 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!