Open ZIP file
Create your own scripts by clicking 'Show script view' in the top right corner or select one of the preset scripts from below.
Description
This preset fixes the date taken field for images that are restored from backup for WhatsApp on Android. See the following article for more information.
Run custom scripts
WARNING - Running custom scripts in your browser can be DANGEROUS. Do not copy paste and run scripts if you do not know what they are doing and/or are from a source you do not trust. I do not take any responsbility for damage or harm caused by using this tool.
template
The top level structure must be of the following form:
{ settings: { // content here }, process: (relativePath, entry, content, newZip, settings) => { // function here // remember to save file to the new zip with the following line newZip.file(entry.name, content, { binary: true }); } }
settings
Is run once and allows you to set create initial values, objects or functions that can be used when iterating through the images.
process
Is the main function that is run for each image in the input zip file. This functions must have the following input/output definition:
(relativePath: string, entry: JSZipObject, content: string, newZip: JSZip, settings: any) => string
JSZipObject
interface JSZipObject { name: string; dir: boolean; date: Date; comment: string; /** The UNIX permissions of the file, if any. */ unixPermissions: number | string | null; /** The UNIX permissions of the file, if any. */ dosPermissions: number | null; }
JSZip
interface JSZip { file(name: string, content: string, type: object); }
global functions
This site uses a modified Typescript version of the original piexifjs library to modify the EXIF data. They are very similar and work in the same way, but does have some slight differences. There are 3 functions available in the loop function that can be used to modify the EXIF values. Read the documentation for the original code to understand how to use this library, but just be aware of this difference between the two.
load
Loads the EXIF data of some content (image) and returns it as an IExif object
load(content: string) => IExif
dump
Returns a byte dump of the EXIF input object as a byte string
dump(exif: IExif) => string
insert
Saves the new EXIF data to the input content (image) and returns a byte string
insert(exifBytes: string, content) => string
TagValues
Defined the EXIF key values. This object is defined here: TagValues
{
settings: {
re: /(.jpg|.png|.gif|.jpeg)$/,
pad: function pad(n, width, z) {
z = z || '0';
n = n + '';
return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n;
}
},
process: (relativePath, entry, content, newZip, settings) => {
let dateStr = relativePath.split(/[_-]/)[1];
let year = parseInt(dateStr.substring(0, 4));
let month = parseInt(dateStr.substring(4, 6));
let day = parseInt(dateStr.substring(6));
if (settings.re.test(entry.name)) {
const exif = load(content);
if (exif.Exif) {
if (!exif.Exif[TagValues.ExifIFD.DateTimeOriginal]) {
exif.Exif[TagValues.ExifIFD.DateTimeOriginal] = year + ":" + settings.pad(month, 2) + ":" + settings.pad(day, 2) + " 00:00:00";
}
} else {
exif.Exif = {
[TagValues.ExifIFD.DateTimeOriginal]: year + ":" + settings.pad(month, 2) + ":" + settings.pad(day, 2) + " 00:00:00",
};
}
const exifBytes = dump(exif);
content = insert(exifBytes, content);
}
newZip.file(entry.name, content, { binary: true, date: new Date(year, month - 1, day, 12, 0, 0) });
}
}