亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

React圖片壓縮上傳統(tǒng)一處理方式

 更新時間:2022年11月18日 17:03:46   作者:每天都要進(jìn)步一點(diǎn)點(diǎn)  
這篇文章主要介紹了React圖片壓縮上傳統(tǒng)一處理方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

React圖片壓縮上傳統(tǒng)一處理

最近項(xiàng)目需要對上傳的圖片文件進(jìn)行壓縮后才上傳到服務(wù)器中,于是研究了一番,下面給出詳細(xì)的壓縮方法,筆者使用的是React Ant Design前端框架的Upload組件上傳圖片:

通過查看Ant Design官網(wǎng)文檔,在上傳文件前可以修改文件:

transformFile在上傳之前轉(zhuǎn)換文件。支持返回一個 Promise 對象Function(file): string | Blob | File | Promise<string | Blob | File>

壓縮相關(guān)代碼

圖片壓縮的原理:實(shí)際上根據(jù)圖片大小有沒有超過預(yù)定的最大最小時,如果超過指定的高度/寬度,在不怎么失真的前提下裁剪圖片,然后使用canvas畫布的drawImage()方法繪制圖片。

下面是關(guān)鍵的代碼:

//在上傳之前轉(zhuǎn)換文件
    transformFile = (file) => {
        /**
         * 針對圖片進(jìn)行壓縮,如果圖片大小超過壓縮閾值,則執(zhí)行壓縮,否則不壓縮
         */
        //判斷是否是圖片類型
        if (this.checkIsImage(file.name)) {
            const {compressThreshold = 5, isPictureCompress = false, pictureQuality = 0.92} = this.props;
            let fileSize = file.size / 1024 / 1024;
            // console.log('before compress, the file size is : ', fileSize + "M");
            //當(dāng)開啟圖片壓縮且圖片大小大于等于壓縮閾值,進(jìn)行壓縮
            if ((fileSize >= compressThreshold) && isPictureCompress) {
                //判斷瀏覽器內(nèi)核是否支持base64圖片壓縮
                if (typeof (FileReader) === 'undefined') {
                    return file;
                } else {
                    try {
                        this.setState({
                            spinLoading: true
                        });
                        return new Promise(resolve => {
                            //聲明FileReader文件讀取對象
                            const reader = new FileReader();
                            reader.readAsDataURL(file);
                            reader.onload = () => {
                                // 生成canvas畫布
                                const canvas = document.createElement('canvas');
                                // 生成img
                                const img = document.createElement('img');
                                img.src = reader.result;
                                img.onload = () => {
                                    const ctx = canvas.getContext('2d');
                                    //原始圖片寬度、高度
                                    let originImageWidth = img.width, originImageHeight = img.height;
                                    //默認(rèn)最大尺度的尺寸限制在(1920 * 1080)
                                    let maxWidth = 1920, maxHeight = 1080, ratio = maxWidth / maxHeight;
                                    //目標(biāo)尺寸
                                    let targetWidth = originImageWidth, targetHeight = originImageHeight;
                                    //當(dāng)圖片的寬度或者高度大于指定的最大寬度或者最大高度時,進(jìn)行縮放圖片
                                    if (originImageWidth > maxWidth || originImageHeight > maxHeight) {
                                        //超過最大寬高比例
                                        if ((originImageWidth / originImageHeight) > ratio) {
                                            //寬度取最大寬度值maxWidth,縮放高度
                                            targetWidth = maxWidth;
                                            targetHeight = Math.round(maxWidth * (originImageHeight / originImageWidth));
                                        } else {
                                            //高度取最大高度值maxHeight,縮放寬度
                                            targetHeight = maxHeight;
                                            targetWidth = Math.round(maxHeight * (originImageWidth / originImageHeight));
                                        }
                                    }
                                    // canvas對圖片進(jìn)行縮放
                                    canvas.width = targetWidth;
                                    canvas.height = targetHeight;
                                    // 清除畫布
                                    ctx.clearRect(0, 0, targetWidth, targetHeight);
                                    // 繪制圖片
                                    ctx.drawImage(img, 0, 0, targetWidth, targetHeight);
                                    // quality值越小,圖像越模糊,默認(rèn)圖片質(zhì)量為0.92
                                    const imageDataURL = canvas.toDataURL(file.type || 'image/jpeg', pictureQuality);
                                    // 去掉URL的頭,并轉(zhuǎn)換為byte
                                    const imageBytes = window.atob(imageDataURL.split(',')[1]);
                                    // 處理異常,將ascii碼小于0的轉(zhuǎn)換為大于0
                                    const arrayBuffer = new ArrayBuffer(imageBytes.length);
                                    const uint8Array = new Uint8Array(arrayBuffer);
                                    for (let i = 0; i < imageBytes.length; i++) {
                                        uint8Array[i] = imageBytes.charCodeAt(i);
                                    }
                                    let mimeType = imageDataURL.split(',')[0].match(/:(.*?);/)[1];
                                    let newFile = new File([uint8Array], file.name, {type: mimeType || 'image/jpeg'});
                                    // console.log('after compress, the file size is : ', (newFile.size / 1024 / 1024) + "M");
                                    resolve(newFile);
                                };
                            };
                            reader.onerror = () => {
                                this.setState({
                                    spinLoading: false
                                });
                                return file;
                            }
                        }).then(res => {
                            this.setState({
                                spinLoading: false
                            });
                            return res;
                        }).catch(() => {
                            this.setState({
                                spinLoading: false
                            });
                            return file;
                        });
                    } catch (e) {
                        this.setState({
                            spinLoading: false
                        });
                        //壓縮出錯,直接返回原file對象
                        return file;
                    }
                }
            } else {
                //不需要壓縮,直接返回原file對象
                return file;
            }
        } else {
            //非圖片文件,不進(jìn)行壓縮,直接返回原file對象
            return file;
        }
    };

相關(guān)屬性說明:

  • compressThreshold: 5,  //壓縮的閾值,圖片大小超過5M,則需要進(jìn)行壓縮
  • isPictureCompress: false, //是否開啟圖片壓縮
  • pictureQuality: 0.92, //指定壓縮的圖片質(zhì)量,取值范圍為0~1,quality值越小,圖像越模糊,默認(rèn)圖片質(zhì)量為0.92

使用方法

<NHUpload
    uploadType={'file'}
    multiple={true}
    fileCountLimit={fjsl}
    maxFileSize={20}
    fileTypeLimit={fileTypeList}
    onChange={this.fjOnChange}
    isPictureCompress={true} //是否開啟圖片壓縮
    pictureQuality={0.5}   //圖片質(zhì)量
    compressThreshold={1}  //壓縮閾值
/>

在使用時,我們可以根據(jù)業(yè)務(wù)需求動態(tài)設(shè)置需要壓縮的閾值,圖片質(zhì)量等等,對圖片壓縮可以大大節(jié)省服務(wù)器的資源,現(xiàn)在手機(jī)隨便拍一張照片就是10幾兆。

React圖片壓縮工具(可下載)

用到的插件:compressorjs

示例

ExampleCanvas.js

import React from 'react';
import { compressorImage } from './Compressor'
 
export default class UploadPic extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      previewPic: '',
      laterPic: ''
    };
    this.handleUpload = this.handleUpload.bind(this);
    this.downloadImg = this.downloadImg.bind(this);
  }
 
  downloadImg(){
    // console.log('download',this.state.laterPic);
    var blob=this.dataURLtoBlob(this.state.laterPic)
    const aLink = document.createElement('a');
        document.body.appendChild(aLink);
        aLink.style.display='none';
        const objectUrl = window.URL.createObjectURL(blob);
        aLink.href = objectUrl;
        // 修改目標(biāo)圖片名字
        // aLink.download = 'a.png';
         aLink.download =document.getElementById('file').value.substring(document.getElementById('file').value.lastIndexOf('\\') + 1);
        aLink.click();
  }
 
  dataURLtoBlob(dataurl) {
    var arr = dataurl.split(',');
     //注意base64的最后面中括號和引號是不轉(zhuǎn)譯的   
     var _arr = arr[1].substring(0,arr[1].length-2);
     var mime = arr[0].match(/:(.*?);/)[1],
       bstr =atob(_arr),
       n = bstr.length,
       u8arr = new Uint8Array(n);
     while (n--) {
       u8arr[n] = bstr.charCodeAt(n);
     }
     return new Blob([u8arr], {
       type: mime
     });
   }
 
  handleUpload(e) {
    // console.log('啊哈!', e.target.files[0]);
 
    var myFile = this.A(e.target.files[0]);
    // console.log('---------myFile----------', myFile);
    const reader = new FileReader();
    reader.readAsDataURL(e.target.files[0]);
    reader.onload = function (e) {
      // console.log(e.target.result);  // 上傳的圖片的編碼
      this.setState({
        previewPic:e.target.result
      });
    }.bind(this);
  }
 
  A = async (file) => {
    var myfile = await compressorImage(file, 'file', 0.6)
    // console.log('----myfie-----',myfile);
    const reader = new FileReader();
    reader.readAsDataURL(myfile);
    reader.onload = function (e) {
      // console.log(e.target.result);  // 上傳的圖片的編碼
      this.setState({
        previewPic:this.state.previewPic,
        laterPic: e.target.result
      });
    }.bind(this);
    return myfile
  }
 
  render() {
    const { previewPic, laterPic } = this.state;
    return (
      <div id="upload-pic">
        <input type="file" id='file' className="file" onChange={this.handleUpload} />
        <div><img src={previewPic} alt="" style={{ width: '675px' }} /></div>
        <div><img src={laterPic} alt="" style={{ width: '675px' }} /></div>
        <button onClick={this.downloadImg} >download</button>
      </div>
    )
  }
}

核心工具

Compressor.js

import React from 'react'
import Compressor from 'compressorjs';
 
 
/**
 * @param image 圖片
 * @param backType 需要返回的類型blob,file
 * @param quality 圖片壓縮比 0-1,數(shù)字越小,圖片壓縮越小
 * @returns
 */
export const compressorImage = (image, backType, quality) => {
  // console.log('image, backType, quality',image, backType, quality);
  return new Promise((resolve, reject) => {
    new Compressor(image, {
      quality: quality || 0.8,
      mimeType :'image/jpeg',
      success(result) {
        // console.log('result', result)
        let file = new File([result], image.name, { type: image.type })
 
        if (!backType || backType == 'blob') {
          resolve(result)
        } else if (backType == 'file') {
          resolve(file)
        } else {
          resolve(file)
        }
        console.log('圖片壓縮成功---->>>>>')
      },
      error(err) {
        console.log('圖片壓縮失敗---->>>>>', err)
        reject(err)
      }
    })
  })
}
 

以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論