简体   繁体   中英

Duplicating base64 data

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();" /> 

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". Ie 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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM