How to save a image to HTML5 filesystem with the url of image

后端 未结 5 1527
青春惊慌失措
青春惊慌失措 2021-01-03 05:26

I am trying to use HTML5 system to store images of my website, and I find there are many example to show how to store a local image to your chrome file system but I can\'t f

相关标签:
5条回答
  • 2021-01-03 05:48

    Here the function I use. It use Blob constructor so it works on latest Chrome (thats lacks deprecated BlobBuilder) and works also on old iOS 6 that lacks 'blob' for xhr.responseType.

    In comments you also see code for the deprecated BlobBuilder.

    Notice: you are using XHR so CORS must be enabled!

    window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
    window.requestFileSystem(window.PERSISTENT, 2*1024*1024, onFileSystemSuccess, fail);
    
    
    function onFileSystemSuccess(fileSystem) {
        fs = fileSystem;
        console.log('File system initialized');
    
        saveAsset('http://www.example-site-with-cors.com/test.png');
    }
    
    
    function saveAsset(url, callback, failCallback) {
        var filename = url.substring(url.lastIndexOf('/')+1);
    
        // Set callback when not defined
        if (!callback) {
            callback = function(cached_url) {
                console.log('download ok: ' + cached_url);
            };
        }
        if (!failCallback) {
            failCallback = function() {
                console.log('download failed');
            };
        }
    
        // Set lookupTable if not defined
        if (!window.lookupTable)
            window.lookupTable = {};
    
        // BlobBuilder shim
        // var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder;
    
        var xhr = new XMLHttpRequest();
        xhr.open('GET', url, true);
        // xhr.responseType = 'blob';
        xhr.responseType = 'arraybuffer';
    
        xhr.addEventListener('load', function() {
    
            fs.root.getFile(filename, {create: true, exclusive: false}, function(fileEntry) {
                fileEntry.createWriter(function(writer) {
    
                    writer.onwrite = function(e) {
                        // Save this file in the path to URL lookup table.
                        lookupTable[filename] = fileEntry.toURL();
                        callback(fileEntry.toURL());
                    };
    
                    writer.onerror = failCallback;
    
                    // var bb = new BlobBuilder();
                    var blob = new Blob([xhr.response], {type: ''});
                    // bb.append(xhr.response);
                    writer.write(blob);
                    // writer.write(bb.getBlob());
    
                }, failCallback);
            }, failCallback);
        });
    
        xhr.addEventListener('error', failCallback);
        xhr.send();
    
        return filename;
    }
    
    
    
    function fail(evt) {
        console.log(evt.target.error.code);
    }
    
    0 讨论(0)
  • 2021-01-03 05:55

    On a modern browser supporting XMLHttpRequest Level 2 the method documented in this answer should work.

    The relevant standard is explained in this blog post

    0 讨论(0)
  • 2021-01-03 05:57

    The problem is that browser will parse xhr response data as UTF-8, So the point is to override MimeType:

    window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
    
    var xhr = new XMLHttpRequest();
    var photoUrl = 'http://localhost:3000/image.jpg';
    xhr.open('GET', photoUrl, true);
    
    // This stops the browser from parsing the data as UTF-8:
    xhr.overrideMimeType('text/plain; charset=x-user-defined');
    
    function stringToBinary(response) {
      var byteArray = new Uint8Array(response.length);
      for (var i = 0; i < response.length; i++) {
        byteArray[i] = response.charCodeAt(i) & 0xff;
      }
      return byteArray
    }
    
    function onInitFs(fs) {
      xhr.onreadystatechange = function() {
        if (xhr.readyState == 4 && xhr.status == 200) {
          fs.root.getFile('image.jpg', {'create': true}, function(fileEntry) {
            fileEntry.createWriter(function(fileWriter) {
              fileWriter.onwriteend = function(event) {
                $('body').append('<img src="' + fileEntry.toURL() + '"/>');
              }
    
              buffer = stringToBinary(xhr.response);
              var blob = new Blob([ buffer ], { type: 'image/jpeg' } )
    
              fileWriter.write(blob);
            }, errorHandler );
          });
        }
      }
      xhr.send();
    }
    
    var errorHandler = function(err) {
      console.log(err);
    }
    
    $(function() {
      webkitStorageInfo.requestQuota(PERSISTENT, 5*1024*1024, function(grantedBytes) {
        requestFileSystem(PERSISTENT, grantedBytes, onInitFs, errorHandler)
      }, errorHandler)
    })
    
    0 讨论(0)
  • 2021-01-03 06:00

    The trick is to use xhr.responseType = 'blob'

    var fs = .... // your fileSystem
    function download(fs,url,file,win,fail) {
      var xhr = new XMLHttpRequest();
      xhr.open('GET', url);
      xhr.responseType = "blob";
      xhr.onreadystatechange = function() {
        if (xhr.readyState == 4) {
          if(xhr.status === 200){
            fs.root.getFile(file,{create:true},function(fileEntry){
              fileEntry.createWriter(function(writer){
                writer.onwriteend = win;
                writer.onerror = fail;
                writer.write(xhr.response);
              })
            },fail)
          } else {
            fail(xhr.status);
          }
        }
      };
      xhr.send();
      return xhr;
    };
    

    Based on cordova-promise-fs (disclosure: I'm the author)

    0 讨论(0)
  • 2021-01-03 06:01

    I find a way to do this.

    use canvans.toDataURL to transfer data format.

    var img = new Image();
                    var cvs = document.createElement('canvas');
                    var ctx  = cvs.getContext("2d");
                    img.src = file;
                    img.onload = function(){
                        cvs.width = img.width;
                        cvs.height = img.height;
                        ctx.drawImage(img, 0, 0);
                        var imd = cvs.toDataURL(contentType[extname]);
                        var ui8a = convertDataURIToBinary(imd);
                        var bb = new BlobBuilder();
                        bb.append(ui8a.buffer);
                        fs.root.getFile(path, {create: true}, function(fileEntry) {
                            // Create a FileWriter object for our FileEntry (log.txt).
                            fileEntry.createWriter(function(fileWriter) {
                                fileWriter.onwriteend = function(e) {
                                    console.log('Write completed.');
                                    callback && callback("test.jpg");
                                };
    
                                fileWriter.onerror = function(e) {
                                    console.log('Write failed: ' + e.toString());
                                };
    
                                fileWriter.write(bb.getBlob(contentType[extname]));
                            });
                        });
                    };
    
    
    
        function convertDataURIToBinary(dataURI) {
        var BASE64_MARKER = ';base64,';
        var base64Index = dataURI.indexOf(BASE64_MARKER) + BASE64_MARKER.length;
        var base64 = dataURI.substring(base64Index);
        var raw = window.atob(base64);
        var rawLength = raw.length;
        var array = new Uint8Array(new ArrayBuffer(rawLength));
    
        for (i = 0; i < rawLength; i++) {
            array[i] = raw.charCodeAt(i);
        }
        return array;
    }
    

    I get help from here jsfiddle

    0 讨论(0)
提交回复
热议问题