Plugin: Image Optimizer

name

Image Optimizer

description

Optimize and compress images in your notes effortlessly. Reduce file sizes, enhance performance, and maintain quality, including support for all major image formats.

Optimize and compress images in your notes to ensure faster load times, making public notes more accessible and seamless for viewers with low bandwidth. Reduce file sizes while maintaining quality, enhancing the user experience for shared content.

- How to use -

Click the three dots in the top-right corner and select "Image Compressor: Optimize" Enter your desired maximum image size (in KB), and the plugin will automatically optimize and update all images in the note to meet the specified limit while preserving quality.

Contact - @Capta1nCool on discord.

icon

image


linkCode

{
compressedCound: 0,
noteOption: {
"Optimize": {
check: async function() {
return true
},
run: async function(app, noteUUID) {
const noteHandle = { uuid: noteUUID };
const note = await app.notes.find(app.context.noteUUID);
const images = await app.getNoteImages(noteHandle);
const maxSize = await app.prompt("Enter max image size (KB)");
 
await this._loadRecordRTC("https://cdn.jsdelivr.net/npm/browser-image-compression@2.0.2/dist/browser-image-compression.min.js")
 
const options = {
maxSizeMB: maxSize / 1024,
useWebWorker: true,
}
 
for (const img of images) {
const image = await fetch(`https://amplenote-plugins-cors-anywhere.onrender.com/${img.src}`);
const blob = await image.blob();
 
if (Math.round(blob.size / 1024) <= maxSize) continue;
 
// Compression logic
if (img.src.endsWith(".gif")) {
return
} else {
const compressedImg = await imageCompression(blob, options);
const dataURL = await this._dataURLFromBlob(compressedImg);
const fileURL = await app.attachNoteMedia(noteHandle, dataURL);
console.log(fileURL);
this.compressedCount += 1;
await note.updateImage(img, { src: fileURL });
}
}
 
app.alert(`Compression complete! A total of ${this.compressedCount} image(s) were successfully compressed and updated.`);
}
}
},
 
compressGIF(blob, quality = 10) {
return new Promise((resolve, reject) => {
const gif = new GIF({
workers: 2,
quality: quality, // Lower quality values reduce size
});
 
const reader = new FileReader();
reader.onload = (event) => {
const img = new Image();
img.src = event.target.result;
img.onload = () => {
gif.addFrame(img, { delay: 100 });
gif.on('finished', (blob) => {
// Convert compressed Blob back to dataURL
const compressedDataURL = URL.createObjectURL(blob);
resolve(compressedDataURL);
});
gif.on('error', (error) => reject(error));
gif.render();
};
};
 
reader.onerror = (error) => reject(error);
reader.readAsDataURL(blob);
});
},
 
async uploadImage(image, result, app) {
const note = await app.notes.find(app.context.noteUUID);
const noteHandle = { uuid: app.context.noteUUID };
const dataURL = await this._dataURLFromBlob(result);
 
const fileURL = await app.attachNoteMedia(noteHandle, dataURL);
 
await note.updateImage(image, { src: fileURL });
},
 
_dataURLFromBlob(blob) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
 
reader.onload = event => {
resolve(event.target.result);
};
 
reader.onerror = function(event) {
reader.abort();
reject(event.target.error);
};
 
reader.readAsDataURL(blob);
});
},
 
_loadRecordRTC(url) {
if (this._haveLoadedRecordRTC) return Promise.resolve(true);
 
return new Promise(function(resolve) {
const script = document.createElement("script");
script.setAttribute("type", "text/javascript");
script.setAttribute("src", url);
script.addEventListener("load", function() {
this._haveLoadedRecordRTC = true;
resolve(true);
});
document.body.appendChild(script);
});
}
}