1. 程式人生 > >Ionic—圖片上傳元件開發

Ionic—圖片上傳元件開發

一.修改頭像功能頁面的整體結構講解

1.安裝必要的元件

使用原生的功能時將採用ionic native

  • 安裝四個外掛

    npm install --save @ionic-native/camera @ionic-native/file @ionic-native/file-path @ionic-native/transfer
    #camera用於相機
    #file用於訪問本地相簿
    #file-path用於檔案路徑相關處理
    #transfer用於傳輸相關檔案
    
  • 使用ionic cordova新增外掛【cordova主要用於android和ios底層通訊】

    sudo ionic cordova plugin add cordova-plugin-camera --save
    sudo ionic cordova plugin add cordova-plugin-file --save
    sudo ionic cordova plugin add cordova-plugin-file-transfer --save
    sudo ionic cordova plugin add cordova-plugin-filepath --save
    
  • 全域性Provider中匯入File,Transfer,FilePath,Camera

二.修改頭像功能頁面的佈局開發

1.功能設計

  • 建立上傳頭像頁面ionic g page headface
  • 將上傳頭像頁面在全域性app.modules檔案中定義
  • 在user檔案中的頭像新增跳轉headface頁面(使用navController)
  • 編輯headface頁面內容

2.例項程式碼

  • user.html新增內容

    <button ion-item (click)="uploadUserAvatar()">
        <ion-avatar item-start>
            <img [src]="
    avatarUrl"
    >
    </ion-avatar> <h2> Edit user avatar </h2> </button>
  • user.ts新增內容

    //upload user avatar
    uploadUserAvatar() {
        this.navCtrl.push(HeadfacePage);
    }
    
  • headface.html新增內容

    <ion-header>
      <ion-navbar>
        <ion-title>Upload Avatar</ion-title>
      </ion-navbar>
    </ion-header>
    
    <ion-content padding>
      <img src="{{pathForImage(lastImage)}}" style="width:100%" [hidden]="lastImage === null">
      <h3 [hidden]="lastImage !== null">Please select a picture from photo library</h3>
    </ion-content>
    
    <ion-footer>
      <ion-toolbar color="primary">
        <ion-buttons>
          <button ion-button icon-left (click)="presentActionSheet()">
            <ion-icon name="camera"></ion-icon>選擇...
          </button>
          <button ion-button icon-left (click)="uploadImage()" [disabled]="lastImage === null">
            <ion-icon name="cloud-upload"></ion-icon>上傳
          </button>
        </ion-buttons>
      </ion-toolbar>
    </ion-footer>
    

三.獲取圖片的邏輯處理

1.開發思路

  • 使用者ID的獲取
  • 顯示選擇圖片的方式
  • 共用獲取圖片的方法處理

2.功能設計

  • 給“選擇…”的button新增監聽事件用於開啟ActionSheet【ActionSheetController元件】

    //部分程式碼
    viewActionSheet() {
        let action = this.actionSheetCtrl.create({
          title:'Select Picture',
          buttons:[
            {
              text:'Select From Photo Library',
              handler:()=>{
    			//選擇本地圖片邏輯
                this.takePicture(this.camera.PictureSourceType.PHOTOLIBRARY);
              }
            },
            {
              text:'Use Camera',
              handler:()=>{
    			//使用相機拍照邏輯
                this.takePicture(this.camera.PictureSourceType.CAMERA);
              }
            },
            {
              text:'Cancel',
              role:'cancel'//關閉actionSheet邏輯
            }
          ]
        });
        action.present();
      }
    
  • 定義使用者屬性:userId,errorMessage,lastImage(最後一個使用者選擇的圖片的位置),注入相關Controller

  • 新增ionViewDidEnter函式從storage中獲取使用者Id用於之後訪問後臺API

  • 匯入之前安裝的外掛,並新增對應的構造引數

    //匯入之前安裝的元件
    import {File} from '@ionic-native/file';
    import {Transfer,TransferObject} from '@ionic-native/transfer';
    import {FilePath} from '@ionic-native/file-path';
    import {Camera} from '@ionic-native/camera';
    
  • 匯入第三方的庫到TS專案中

    declare var cordova:any;
    
  • 新增拍照呼叫的函式

    //照相的函式
    takePicture(sourceType){
        //定義相機的一些引數
        let options = {
            quality:100,//定義圖片質量
            sourceType:sourceType,
            saveToPhotoAlbum:false,//是否把拍攝的照片存到相簿中去
            correctOrientation:true//是否糾正拍攝照片的方向
        };
        //獲取圖片的方法
        this.camera.getPicture(options).then((imagePath)=>{
            //特別處理android平臺的檔案路徑問題
            if(this.platform.is('android') && sourceType === this.camera.PictureSourceType.PHOTOLIBRARY){//通過platform判斷是什麼平臺,Platform也同樣需要匯入
                //獲取android平臺下的真實路徑
                this.filePath.resolveNativePath(imagePath).then(filePath=>{
                    //獲取正確的路徑
                    let correctPath = filePath.substr(0,filePath.lastIndexOf('/')+1);
                    //獲取正確的檔名
                    let correntName = imagePath.substring(imagePath.lastIndexOf('/')+1,imagePath.lastIndexOf('?'));
                    this.copyFileToLocalDir(correctPath,correntName,this.createFileName())
                });
            }
            else{//其他平臺的處理
                //獲取正確的路徑
                let correctPath = imagePath.substr(0,imagePath.lastIndexOf('/')+1);
                //獲取正確的檔名
                let correntName = imagePath.substring(imagePath.lastIndexOf('/')+1);
                this.copyFileToLocalDir(correctPath,correntName,this.createFileName());
            }
        },(error)=>{
            super.showToast(this.toastCtrl,'It`s wrong to choose picture, please operate in app or check permission.');
        })
    }
    
    //將獲取到的圖片或者相機拍攝到的圖片進行一下另存為,用於後期的圖片上傳使用
    copyFileToLocalDir(namePath,currentName,newFileName){
        //使用cordova專門儲存臨時檔案的目錄
        this.file.copyFile(namePath,currentName,cordova.file.dataDirectory,newFileName).then(success=>{
            this.lastImage = newFileName;
        },error =>{
            super.showToast(this.toastCtrl,"Something wrong when storage picture into local.");
        });
    }
    
    //為檔案生成一個新的檔名
    createFileName() {
        let d = new Date();
        let n = d.getTime();
        let newFileName = n + '.jpg';
        return newFileName;
    }
    
    //處理圖片的路徑為可以上傳的路徑
    public pathForImage(img) {
        if(img === null){
            return '';
        }else{
            return normalizeURL(cordova.file.dataDirectory + img);
        }
    }
    
    //上傳圖片邏輯
    uploadImage() {
        let url = "";//上傳的url路徑
        let targetPath = this.pathForImage(this.lastImage);
        let fileName = this.userId + ".jpg";//定義上傳後的檔名
        //上傳的引數
        let options = {
            fileKey:"file",
            fileName:fileName,
            chunkedMode:false,
            mimeType:"mulipart/form-data",
            params:{
                'fileName':fileName,
                'userId':this.userId
            } 
        }
        const fileTransfer:TransferObject = this.transfer.create();
        let loading = super.showLoading(this.loadingCtrl,"上傳中...");
        //開始正式上傳
        fileTransfer.upload(targetPath,url,options).then((data)=>{
            loading.dismiss();
            super.showToast(this.toastCtrl,"Upload avatar successfully!");
            //在使用者看清彈窗提示後進行頁面的關閉
            setTimeout(()=>{
                this.viewCtrl.dismiss();
            },2000);
        },err=>{
            loading.dismiss();
            super.showToast(this.toastCtrl,"Upload avatar failed, please retry...");
        });
    }
    

四.不同的系統下測試上傳圖片功能

執行ionic build命令實現專案打包,將src的原始檔打包成對應的已經新增的平臺

1.IOS測試

  • 新增build ios的環境
    • sudo cordova platform rm ios
    • sudo cordova platform add ios
    • sudo ionic build ios
  • 使用xcode開啟.codeproj檔案

2.Android測試

  • 新增build android的環境
    • sudo cordova platform rm android
    • sudo cordova platform add android
    • sudo ionic cordova build android打包生成的檔案地址專案根目錄/platforms/android/build/outputs/apk/android-debug.apk
  • 使用android studio中開啟模擬器執行專案