You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Sep 29, 2020. It is now read-only.
With the previous issues arising around retaining EXIF data, would provide added convenience in specific situations. But the implementation has some potential issues, which I'd like to address here for further discussion.
The first issue is EXIF orientation of jpg images. The current effect is when you are referencing a jpg that requires to be rotated based on EXIF data, the image is not being rotated within the library. If the EXIF data were to be merged into the new image, you would then have a problem with the text/overlays/watermarks being in the wrong orientation, now that they have been embedded into the image. Example
The solution to this would be to perform rotation of the images on initial load. But then the EXIF orientation data would be incorrect on the new image as the raw image has been rotated. This field would need to be updated if we expect to retain the EXIF data.
The next issue I can see is a situation where you include multiple images with EXIF data. What takes priority? Just the first image? Is there a way to store multiple EXIF records on one image? Or would an option to force user defined EXIF data be better?
Another consideration on a performance standpoint, would there be a way to copy the EXIF headers as one big binary chunk, and attach it to the new image. Instead of having to parse and recompile the data? And in reference to the rotation data, It might be easier to just pull the specific value from this chunk, instead of parsing the entire binary.
This stack overflow topic does provide such a script in Base64 image data where it's just copying the EXIF chunk and merging it into a new image https://stackoverflow.com/questions/18297120/html5-resize-image-and-keep-exif-in-resized-image
//Based on MinifyJpeg
//http://elicon.blog57.fc2.com/blog-entry-206.html
var ExifRestorer = (function()
{
var ExifRestorer = {};
ExifRestorer.KEY_STR = "ABCDEFGHIJKLMNOP" +
"QRSTUVWXYZabcdef" +
"ghijklmnopqrstuv" +
"wxyz0123456789+/" +
"=";
ExifRestorer.encode64 = function(input)
{
var output = "",
chr1, chr2, chr3 = "",
enc1, enc2, enc3, enc4 = "",
i = 0;
do {
chr1 = input[i++];
chr2 = input[i++];
chr3 = input[i++];
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output +
this.KEY_STR.charAt(enc1) +
this.KEY_STR.charAt(enc2) +
this.KEY_STR.charAt(enc3) +
this.KEY_STR.charAt(enc4);
chr1 = chr2 = chr3 = "";
enc1 = enc2 = enc3 = enc4 = "";
} while (i < input.length);
return output;
};
ExifRestorer.restore = function(origFileBase64, resizedFileBase64)
{
if (!origFileBase64.match("data:image/jpeg;base64,"))
{
return resizedFileBase64;
}
var rawImage = this.decode64(origFileBase64.replace("data:image/jpeg;base64,", ""));
var segments = this.slice2Segments(rawImage);
var image = this.exifManipulation(resizedFileBase64, segments);
return this.encode64(image);
};
ExifRestorer.exifManipulation = function(resizedFileBase64, segments)
{
var exifArray = this.getExifArray(segments),
newImageArray = this.insertExif(resizedFileBase64, exifArray),
aBuffer = new Uint8Array(newImageArray);
return aBuffer;
};
ExifRestorer.getExifArray = function(segments)
{
var seg;
for (var x = 0; x < segments.length; x++)
{
seg = segments[x];
if (seg[0] == 255 & seg[1] == 225) //(ff e1)
{
return seg;
}
}
return [];
};
ExifRestorer.insertExif = function(resizedFileBase64, exifArray)
{
var imageData = resizedFileBase64.replace("data:image/jpeg;base64,", ""),
buf = this.decode64(imageData),
separatePoint = buf.indexOf(255,3),
mae = buf.slice(0, separatePoint),
ato = buf.slice(separatePoint),
array = mae;
array = array.concat(exifArray);
array = array.concat(ato);
return array;
};
ExifRestorer.slice2Segments = function(rawImageArray)
{
var head = 0,
segments = [];
while (1)
{
if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 218){break;}
if (rawImageArray[head] == 255 & rawImageArray[head + 1] == 216)
{
head += 2;
}
else
{
var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],
endPoint = head + length + 2,
seg = rawImageArray.slice(head, endPoint);
segments.push(seg);
head = endPoint;
}
if (head > rawImageArray.length){break;}
}
return segments;
};
ExifRestorer.decode64 = function(input)
{
var output = "",
chr1, chr2, chr3 = "",
enc1, enc2, enc3, enc4 = "",
i = 0,
buf = [];
// remove all characters that are not A-Z, a-z, 0-9, +, /, or =
var base64test = /[^A-Za-z0-9\+\/\=]/g;
if (base64test.exec(input)) {
alert("There were invalid base64 characters in the input text.\n" +
"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\n" +
"Expect errors in decoding.");
}
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
do {
enc1 = this.KEY_STR.indexOf(input.charAt(i++));
enc2 = this.KEY_STR.indexOf(input.charAt(i++));
enc3 = this.KEY_STR.indexOf(input.charAt(i++));
enc4 = this.KEY_STR.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
buf.push(chr1);
if (enc3 != 64) {
buf.push(chr2);
}
if (enc4 != 64) {
buf.push(chr3);
}
chr1 = chr2 = chr3 = "";
enc1 = enc2 = enc3 = enc4 = "";
} while (i < input.length);
return buf;
};
return ExifRestorer;
})();
The text was updated successfully, but these errors were encountered:
Sign up for freeto subscribe to this conversation on GitHub.
Already have an account?
Sign in.
In reference to #34 and #42
With the previous issues arising around retaining EXIF data, would provide added convenience in specific situations. But the implementation has some potential issues, which I'd like to address here for further discussion.
The first issue is EXIF orientation of jpg images. The current effect is when you are referencing a jpg that requires to be rotated based on EXIF data, the image is not being rotated within the library. If the EXIF data were to be merged into the new image, you would then have a problem with the text/overlays/watermarks being in the wrong orientation, now that they have been embedded into the image. Example
The solution to this would be to perform rotation of the images on initial load. But then the EXIF orientation data would be incorrect on the new image as the raw image has been rotated. This field would need to be updated if we expect to retain the EXIF data.
The next issue I can see is a situation where you include multiple images with EXIF data. What takes priority? Just the first image? Is there a way to store multiple EXIF records on one image? Or would an option to force user defined EXIF data be better?
Another consideration on a performance standpoint, would there be a way to copy the EXIF headers as one big binary chunk, and attach it to the new image. Instead of having to parse and recompile the data? And in reference to the rotation data, It might be easier to just pull the specific value from this chunk, instead of parsing the entire binary.
This stack overflow topic does provide such a script in Base64 image data where it's just copying the EXIF chunk and merging it into a new image
https://stackoverflow.com/questions/18297120/html5-resize-image-and-keep-exif-in-resized-image
The text was updated successfully, but these errors were encountered: