項目分享五:H5圖片壓縮與上傳


一、簡介

圖片的壓縮與上傳,是APP里一個很常用的功能。我們來年看 ChiTuStore 是怎樣做的。相關文件 App/Module/User/UserInfo.html,App/Module/User/UserInfo.ts

 

二、HTML布局

HTML 文件中,有如下二句,第一句就是上圖所看到的圖片,其中的 class 表示該圖片以圓形來顯示,並且靠右。第二句是一個 Input 控件,其類型為 file ,是用來上傳文件的。值得注意的是 style,這的作用是讓該控件與圖片重疊,並且透明(opacity:0),accept="image/*" 的作用是只上傳圖片。

 <img data-bind="attr:{src:userInfo.HeadImageUrl}" class="img-circle pull-right" style="width:70px;height:70px;">
 <input type="file" style="position:absolute;top:0px;left:0px;opacity:0;width:100%;height:90px;" accept="image/*">

 

三、圖片的壓縮

傳統 WEB 的做法,都是把圖片直接上傳到服務端,然后在服務端進行壓縮。但現在,在H5 中,是可以對圖片進行壓縮再上傳的。我們來看一下 JS 代碼,其中的 ImageFileResize 就是用來處理圖片的壓縮的。

    page.viewChanged.add(() => {
        var e = page.nodes().content.querySelector('[type="file"]');
        var imageFileResize = new ImageFileResize(<HTMLInputElement>e, { maxWidth: 100, maxHeight: 100 });
        imageFileResize.imageResized = (urls: string[], thumbs1: string[], thumbs2: string[]) => {
            model.userInfo.HeadImageUrl(thumbs1[0]);
            member.setUserInfo(mapping.toJS(model.userInfo));
        }
        ko.applyBindings(model, page.node());
    })

我們現在來看一下 ImageFileResize 中的關鍵代碼,這段代碼的作用是用來把 <input type="file"/> 選取的文件,進行壓縮的。其中有幾個關鍵的對象、函數,是 H5 中的 API,FileReader,createObjectURL,Image。

這幾個對象、函數的具體用法,在這里就不展開說了,網上搜一下就可以找到答案了。

 var reader = new FileReader();
 reader.readAsArrayBuffer(file);
 reader.onload = (ev: Event) => {
      var blob = new Blob([event.target['result']]);
      window['URL'] = window['URL'] || window['webkitURL'];
      var blobURL = window['URL'].createObjectURL(blob); // and get it's URL
      var image = new Image();
      image.src = blobURL;
      image.onload = () => {
           var url = this.resizeMe(image, max_width, max_height);
           var thumb = this.resizeMe(image, this.thumb2.maxWidth, this.thumb2.maxHeight);
           result.resolve({ index: index, url: url, data: url, thumb: thumb });
      }
 }

下面我們再來看一下 resizeMe 函數,這個函數的把的圖片(HTMLImageElement),轉換為了 base64 的字符串,其中一個重要的對象就是 canvas,它也是 H5 中的對象。通過它可以把圖片轉換為 base64 字符串。

 private resizeMe(img: HTMLImageElement, max_width: number, max_height: number) {

        var canvas = document.createElement('canvas');

        var width: number = img.width;
        var height: number = img.height;

        // calculate the width and height, constraining the proportions
        if (width > height) {
            if (width > max_width) {
                height = Math.round(height *= max_width / width);
                width = max_width;
            }
        } else {
            if (height > max_height) {
                width = Math.round(width *= max_height / height);
                height = max_height;
            }
        }

        canvas.width = width;
        canvas.height = height;
        var ctx = canvas.getContext("2d");
        ctx.drawImage(img, 0, 0, width, height);

        return canvas.toDataURL("image/jpeg", 0.7);

    }

 

四、服務端的保存

服務的保存有兩種方法

1、把 base64 字符串轉換為二進制流,然后再保存為圖片文件。

2、直接把 base64 保存數據庫。在這個項目,是把它保存到 MongoDB 數據庫。

 

五、瀏覽器的坑

即然是通過瀏覽器進行壓縮上傳,那么就無法避免會有坑。

1、在 QQ 瀏覽器中,不起作用。據說是不支持 canvas 。

2、在 APP 的混合開發中,在錘子 T2 的手機也不起作用。

 

六、小結

盡管在本地壓縮、預覽圖片有着很好的用戶體驗,但是兼容性差,如果是 APP 的開發,還是調用原生的接口吧。如果瀏覽器的 WEB APP 項目,還是得考慮兼容性。不支持 canvas 的瀏覽器,使用傳統的方法來上傳圖片。

 

代碼已經開源在 github,感興趣的朋友可以自行下載。https://github.com/ansiboy/ChiTuStore

 

項目分享四:購物車頁面的更新 

項目分享三:頁面之間的傳值

項目分享二:APP 小紅點中數字的處理

項目分享一:在項目中使用 IScroll 所碰到的那些坑

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM