【问题标题】:Save a File Image to localstorage HTML将文件图像保存到 localstorage HTML
【发布时间】:2015-10-29 07:19:01
【问题描述】:

我正在尝试将图像保存到本地存储并在需要时取回相同的图像,我对如何保存图像感到困惑,因为我提到了与我的同一个问题相关的问题,但它们很复杂,最后我得到了一些东西对我来说看起来很完美,但我很困惑如何使用代码将图像保存在本地存储中
Hear is the code in JSFIDDEL

HTML:

<input type="file" id="bannerImg"  />


<img src="" id="tableBanner" />

JS:

bannerImage = document.getElementById('bannerImg');
imgData = getBase64Image(bannerImage);
localStorage.setItem("imgData", imgData);


function getBase64Image(img) {
    var canvas = document.createElement("canvas");
    canvas.width = img.width;
    canvas.height = img.height;

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

    var dataURL = canvas.toDataURL("image/png");

    return dataURL.replace(/^data:image\/(png|jpg);base64,/, "");
}

function fetchimage ()
{
var dataImage = localStorage.getItem('imgData');
var bannerImg = document.getElementById('tableBanner');
 bannerImg.src = "data:image/png;base64," + dataImage;
}

【问题讨论】:

  • 可用的本地存储空间因浏览器而异(see this good post about it)。我认为平均为 3~5MB,请确保您的图像不重。
  • @Kaiido,感谢您提供我不知道的信息,您是否有调整图像大小的想法???
  • @Kaiido,如果你真的不介意如何添加,我零线索可以加入我听到jsfiddle.net/cv0gx6yL/#&togetherjs=nOmAGPoeQx
  • 有点长,所以添加它作为答案。

标签: javascript jquery html


【解决方案1】:

您只是缺少一个FileReader 来将输入文件读取到 dataURL。 Jsfiddle

HTML:

<input type="file" id="bannerImg"  />
<img src="" id="tableBanner" />
<!-- for result output -->
<div id="res"></div>

javascript:

// Get all variables
var bannerImage = document.getElementById('bannerImg');
var result = document.getElementById('res');
var img = document.getElementById('tableBanner');

// Add a change listener to the file input to inspect the uploaded file.
bannerImage.addEventListener('change', function() {
    var file = this.files[0];
    // Basic type checking.
    if (file.type.indexOf('image') < 0) {
        res.innerHTML = 'invalid type';
        return;
    }

    // Create a file reader
    var fReader = new FileReader();

    // Add complete behavior
    fReader.onload = function() {
        // Show the uploaded image to banner.
        img.src = fReader.result;

        // Save it when data complete.
        // Use your function will ensure the format is png.
        localStorage.setItem("imgData", getBase64Image(img));
        // You can just use as its already a string.
        // localStorage.setItem("imgData", fReader.result);
    };

    // Read the file to DataURL format.
    fReader.readAsDataURL(file);
});

function getBase64Image(img) {
    var canvas = document.createElement("canvas");
    canvas.width = img.width;
    canvas.height = img.height;

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

    var dataURL = canvas.toDataURL("image/png");

    return dataURL.replace(/^data:image\/(png|jpg);base64,/, "");
}

function fetchimage () {
    var dataImage = localStorage.getItem('imgData');
    img.src = "data:image/png;base64," + dataImage;
    // If you don't process the url with getBase64Image, you can just use
    // img.src = dataImage;
}

// Call fetch to get image from localStorage.
// So each time you reload the page, the image in localstorage will be 
// put on tableBanner
fetchimage();

不是 jsfiddle 执行这个脚本onload,所以你可以将它们包装在你自己网站的 window.onload 中。

【讨论】:

  • 因为图片类型应该是image/png或者image/jpeg,使用那个函数就可以保证得到image/png,那我就更新一下吧。
  • 我只是首先认为 OP 与该 imageurl 有关,因为他正在剥离 data....base64 部分。他可能对此有些担心,我认为最好让 OP 决定是直接存储还是使用其他进程,因为答案是关于 FileReader :P。
  • 好的,那么我将在代码中注释说明如果 OP 只想存储图像,getBase64Image 不是必须的。
  • @fuyushimoya 我有个小问题,如果你不介意图片只能通过点击按钮保存
  • 是的,将localStorage.setItem("imgData", getBase64Image(img)); 移至该按钮的点击回调。然后它只会在上传时显示图像,在您单击提到的按钮之前不会保存到 localStorage。
【解决方案2】:

由于您使用 localStorage 获得了limited storage quota,您可能需要检查上传图片的大小。

根据@fuyushimoya 的回答,这是一种方法,如果您不需要将每种类型的图像都转换为 png。否则,你有点搞砸了,因为它是最重的图像类型之一。

这个解决方案可能不是最好的,但它似乎可以处理一些情况:

JS

// Get all variables
var bannerImage = document.getElementById('bannerImg');
var result = document.getElementById('res');
var img = document.getElementById('tableBanner');

bannerImage.addEventListener('change', function() {
  var file = this.files[0];
  // declare a maxSize (3Mb)
  var maxSize = 3000000;

  if (file.type.indexOf('image') < 0) {
    res.innerHTML = 'invalid type';
    return;
  }
  var fReader = new FileReader();
  fReader.onload = function() {
    img.onload = function() {
      // if localStorage fails, it should throw an exception
      try {
        // pass the ratio of the file size/maxSize to your toB64 func in case we're already out of scope
        localStorage.setItem("imgData", getBase64Image(img, (file.size / maxSize), file.type));
      } catch (e) {
        var msg = e.message.toLowerCase();
        // We exceeded the localStorage quota
        if (msg.indexOf('storage') > -1 || msg.indexOf('quota') > -1) {
          // we're dealing with a jpeg image :  try to reduce the quality
          if (file.type.match(/jpe?g/)) {
            console.log('reducing jpeg quality');
            localStorage.setItem("imgData", getBase64Image(img, (file.size / maxSize), file.type, 0.7));
          }
          // we're dealing with a png image :  try to reduce the size
          else {
            console.log('reducing png size');
            // maxSize is a total approximation I got from some tests with a random pixel generated img
            var maxPxSize = 750000,
              imgSize = (img.width * img.height);
            localStorage.setItem("imgData", getBase64Image(img, (imgSize / maxPxSize), file.type));
          }
        }
      }
    }
    img.src = fReader.result;
  };

  fReader.readAsDataURL(file);
});

function getBase64Image(img, sizeRatio, type, quality) {
  // if we've got an svg, don't convert it, svg will certainly be lighter than any pixel image
  if (type.indexOf('svg+xml') > 0) return img.src;

  // if we've got a jpeg
  if (type.match(/jpe?g/)) {
    // and the sizeRatio is okay, don't convert it
    if (sizeRatio <= 1) return img.src;
  }
  // if we've got some other image type
  else type = 'image/png';

  if (!quality) quality = 1;
  var canvas = document.createElement("canvas");
  // if our image file is too large, then reduce its size
  canvas.width = (sizeRatio > 1) ? (img.width / sizeRatio) : img.width;
  canvas.height = (sizeRatio > 1) ? (img.height / sizeRatio) : img.height;

  var ctx = canvas.getContext("2d");
  ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
  // if we already tried to reduce its size but it's still failing, then reduce the jpeg quality
  var dataURL = canvas.toDataURL(type, quality);

  return dataURL;
}

function fetchimage() {
  var dataImage = localStorage.getItem('imgData');
  img.src = dataImage;
}

// Call fetch to get image from localStorage.
fetchimage();

HTML

<input type="file" id="bannerImg" />
<img src="" id="tableBanner" />
<div id="res"></div>

▶︎ Fiddle

【讨论】:

    【解决方案3】:

    美国 esta directiva:

    directives.directive('baseSixtyFourInput', ['$window', function($window) {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function(scope, elem, attrs, ngModel) {
            var fileObject = {};
            scope.readerOnload = function(e) {
                var base64 = _arrayBufferToBase64(e.target.result);
                fileObject.base64 = base64;
                scope.$apply(function() {
                    ngModel.$setViewValue(angular.copy(fileObject));
                });
            };
    
            var reader = new FileReader();
            reader.onload = scope.readerOnload;
    
            elem.on('change', function() {
                var file = elem[0].files[0];
                fileObject.filetype = file.type;
                fileObject.filename = file.name;
                fileObject.filesize = file.size;
                reader.readAsArrayBuffer(file);
            });
    
            //http://stackoverflow.com/questions/9267899/arraybuffer-to-base64-encoded-string
            function _arrayBufferToBase64(buffer) {
                var binary = '';
                var bytes = new Uint8Array(buffer);
                var len = bytes.byteLength;
                for (var i = 0; i < len; i++) {
                    binary += String.fromCharCode(bytes[i]);
                }
                return $window.btoa(binary);
            }
        }
    };
    

    }]);

    【讨论】:

      猜你喜欢
      • 2016-11-24
      • 2013-05-31
      • 1970-01-01
      • 1970-01-01
      • 2011-05-08
      • 1970-01-01
      • 2018-05-30
      • 2021-07-11
      相关资源
      最近更新 更多