2016-05-23 186 views
2

我正在使用圖像選擇器(​​)插件,以便從圖庫中獲取圖像並將其上傳到服務器。Cordova - 讀取大圖像損壞圖像

我使用的科爾多瓦與Android平臺5.1.1及以下插件6.1.1:

cordova-plugin-camera 2.2.0 "Camera" 
cordova-plugin-compat 1.0.0 "Compat" 
cordova-plugin-device 1.0.1 "Device" 
cordova-plugin-file 4.2.0 "File" 
cordova-plugin-imagepicker 1.1.0 "ImagePicker" 
cordova-plugin-inappbrowser 1.4.0 "InAppBrowser" 
cordova-plugin-media 2.3.0 "Media" 

至於回調插件,我我得到的路徑使用下面的代碼轉換爲文件。請注意,我使用resolveFile,因爲此代碼也在桌面上運行,在這種情況下,條目已經是File對象。

var resolveFile = function(entry) { 
    if (typeof(entry) === "string") { 
     var deferred = $q.defer(); 
     // first convert to local file system URL 
     window.resolveLocalFileSystemURL(entry, function(fileEntry) { 
      // now read/convert the file to file object. 
      fileEntry.file(function(file) { 
       console.log("File converted to file entry"); 
       deferred.resolve(file); 
      }, function(err) { 
       console.log("Failed to convert to file entry", err); 
       deferred.reject(err); 
      }); 
     }, function(err) { 
      console.log("Failed to resolve to file URL", err); 
      deferred.reject(err); 
     }); 

     return deferred.promise; 
    } else { 
     return $q.when(entry); 
    } 
}; 

這又是用來讀取圖像,並把它傳遞給它上傳到服務器的功能($files就是我從插件或輸入在桌面/瀏覽器的情況下獲得):

var upload = function() { 
    if (!$files[currentFile]) { 
     onAllFinished(); 
     return; 
    } 
    file = $files[currentFile]; 
    beforeLoad(file); 
    fileReader = new FileReader(); 
    fileReader.onload = onload; 
    fileReader.onprogress = progress; 
    resolveFile(file).then(function(actualFile) { 
     fileReader.readAsDataURL(actualFile); 
    }); 
    currentFile++; 
}; 

在上文中,有載削減的圖像數據(以下「的base64」,字符串),並把它發送到一個希望將BASE64串並上傳數據到服務器使用簡單的AJAX調用上傳代碼:

var uploadPhoto = function(url, photo, callback, error) 
    $http.post(url, { 
     photo: photo, 
    }) 
    .success(callback) 
    .error(function (data, status, headers, config) { 
     if (error) 
      error(data, status, headers, config); 
    }); 

最後一個函數也適用於相機插件camera plugin使用DATA_URI目標(我知道,這不是建議),它也返回一個base64字符串(所以我可以重用代碼)。

在我看來,文件讀取器輸出發生了一些問題(我猜測)。 (我想)暗示的是,小圖像(10s kb)加載得很好,並且已經準備好了來自相機插件的base64字符串,但是通過filereader的較大圖像(幾MB)(在Android上,在桌面上很好)被上傳損壞(見下文)。

有沒有人遇到過這樣的問題?任何人都可以提出一個修正(除了更改代碼使用FileTransfer插件)?

原始圖像:

original (almost, had to shrink it for upload to SO)

上傳(損壞)圖像。請注意,有一些是讀/精細上傳:

Uploaded to server after reading through FileReader

回答

9

,我發現你的問題,同時尋找一個類似的問題的解決方案。當使用fileReader.readAsDataURL時,來自相機的大圖像的DataURL將在用作圖像的源時顯示,但同一圖像受損。

我已經能夠通過使用fileReader.readAsBinaryData而不是fileReader.readAsDataURL,然後將binarystring轉換爲dataURL來繞過該問題。

window.resolveLocalFileSystemURL(imageUri, function done(fileEntry) { 
    fileEntry.file(function (fileObj) { 
     var image = new Image(); 
     var reader = new FileReader(); 
     reader.onloadend = function (e) { 
      image.src = "data:image/jpeg;base64," + window.btoa(e.target.result) 
     } 
     reader.readAsBinaryString(fileObj); 
    } 
} 

希望這可以幫助您找到自己的解決方法。

+0

這看起來很有希望。我會試着去測試它。無論如何,我決定切換到使用FILE_URI和FileTransfer。這需要改變我的服務器端,但這是推薦的方式,似乎是一種更安全的方法。 –

+0

嗨,這個作品很棒。現在我不確定是否使用FILE_URI/FileTransfer插件:)。謝謝! –

+0

不客氣。 –