Duplicating base64 data

我的未来我决定 提交于 2019-12-11 08:54:27

问题


This is a follow up from the following link on stackoverflow Iterating through : Reader.OnLoad

which Máté Safranka kindly helped me with earlier.

I'm almost finished with it, does anyone know why in the function function onAllImagesLoaded(imageList) the line console.log ("imageList: " + imageList); is duplicating the image data all the time, that's what it's doing at the moment and I can't figure it out. If I select more than 1 file, the image data is the same for each one! Arggghh

Thank you

function encodeImageFileAsURL() {

  var filesSelected = document.getElementById("inputFileToLoad").files;
  var arrayCounter = 0;
  var imageList = [];

  for (arrayCounter = 0; arrayCounter < filesSelected.length; arrayCounter++) {

    var fileToLoad = filesSelected[arrayCounter];
    var fileReader = new FileReader();

    fileReader.onload = (function(fileLoadedEvent) {
      return function(e) {
        var srcData = e.target.result; // base64 data

        getOrientation(fileToLoad, function(orientation) {
        
          if (orientation == 1) {
            imageList.push(srcData);
            if (imageList.length == filesSelected.length) {
          			//console.log ("imageList length: " + imageList.length);
            		//console.log ("filesSelected length: " + filesSelected.length);
                onAllImagesLoaded(imageList);
          	}
          }
          else {
            resetOrientation(URL.createObjectURL(fileToLoad), orientation, function(resetBase64Image) {
              imageList.push(resetBase64Image);
              if (imageList.length == filesSelected.length) {
          			//console.log ("imageList length: " + imageList.length);
            		//console.log ("filesSelected length: " + filesSelected.length);
                onAllImagesLoaded(imageList);
          		}
            });
          }
          
        });
			}
      
    })(fileToLoad);

    fileReader.readAsDataURL(fileToLoad);
  }
}



function onAllImagesLoaded(imageList) {
	console.log ("imageList: " + imageList);
}


function resetOrientation(srcBase64, srcOrientation, callback) {
  var img = new Image();

  img.onload = function() {
    var width = img.width,
      height = img.height,
      canvas = document.createElement('canvas'),
      ctx = canvas.getContext("2d");

    // set proper canvas dimensions before transform & export
    if (4 < srcOrientation && srcOrientation < 9) {
      canvas.width = height;
      canvas.height = width;
    } else {
      canvas.width = width;
      canvas.height = height;
    }

    // transform context before drawing image
    switch (srcOrientation) {
      case 2:
        ctx.transform(-1, 0, 0, 1, width, 0);
        break;
      case 3:
        ctx.transform(-1, 0, 0, -1, width, height);
        break;
      case 4:
        ctx.transform(1, 0, 0, -1, 0, height);
        break;
      case 5:
        ctx.transform(0, 1, 1, 0, 0, 0);
        break;
      case 6:
        ctx.transform(0, 1, -1, 0, height, 0);
        break;
      case 7:
        ctx.transform(0, -1, -1, 0, height, width);
        break;
      case 8:
        ctx.transform(0, -1, 1, 0, 0, width);
        break;
      default:
        break;
    }

    // draw image
    ctx.drawImage(img, 0, 0);

    // export base64
    callback(canvas.toDataURL());
  };

  img.src = srcBase64;
}



function getOrientation(file, callback) {
  var reader = new FileReader();
  reader.onload = function(e) {

    var view = new DataView(e.target.result);
    if (view.getUint16(0, false) != 0xFFD8) {
      return callback(-2);
    }
    var length = view.byteLength,
      offset = 2;
    while (offset < length) {
      if (view.getUint16(offset + 2, false) <= 8) return callback(-1);
      var marker = view.getUint16(offset, false);
      offset += 2;
      if (marker == 0xFFE1) {
        if (view.getUint32(offset += 2, false) != 0x45786966) {
          return callback(-1);
        }

        var little = view.getUint16(offset += 6, false) == 0x4949;
        offset += view.getUint32(offset + 4, little);
        var tags = view.getUint16(offset, little);
        offset += 2;
        for (var i = 0; i < tags; i++) {
          if (view.getUint16(offset + (i * 12), little) == 0x0112) {
            return callback(view.getUint16(offset + (i * 12) + 8, little));
          }
        }
      } else if ((marker & 0xFF00) != 0xFF00) {
        break;
      } else {
        offset += view.getUint16(offset, false);
      }
    }
    return callback(-1);
  };
  reader.readAsArrayBuffer(file);
}
<!-- Learn about this code on MDN: https://developer.mozilla.org/en-US/docs/Web/API/FileReader/readAsDataURL -->

<input id="inputFileToLoad" type="file" accept="image/*" multiple="true" style="opacity: 100" onchange="encodeImageFileAsURL();" />

回答1:


getOrientation() returned -2 for all of my images. Looking at the code, that happens when first two bytes of the image aren't 0xFFD8. Google tells me this particular byte sequence is called the "JPEG frame tag". I.e. getOrientation() is only compatible with JPEG images, whereas the ones I tried were all PNG. You'll need to find some way to handle that.




回答2:


I had a similar problem with getOrientation(). Because it's asynchronous it doesn't process the pics in order.

So you need to amend getOrientation() to return file as well as the exif value, like this...

...return callback(file, -2);
...return callback(file, -1);
...return callback(file, view.getUint16(offset + (i * 12) + 8, little));
etc

That way when it returns you can match the exif value with the file that went in.

Otherwise there's no way for your script to know & it will just use the data from the last file that went in for all files.



来源:https://stackoverflow.com/questions/50005305/duplicating-base64-data

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!