2016-05-23 288 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

不客气。 –