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