From f0154143ed38fe4282766ff4ca9280faa699b9ee Mon Sep 17 00:00:00 2001 From: DJ2LS Date: Tue, 17 Sep 2024 11:20:30 +0200 Subject: [PATCH] image compression #784 --- .../src/components/chat_new_message.vue | 132 +++++++++++++++--- 1 file changed, 109 insertions(+), 23 deletions(-) diff --git a/freedata_gui/src/components/chat_new_message.vue b/freedata_gui/src/components/chat_new_message.vue index 8685623eb..798c32ef1 100644 --- a/freedata_gui/src/components/chat_new_message.vue +++ b/freedata_gui/src/components/chat_new_message.vue @@ -11,6 +11,10 @@ import { ref } from 'vue'; import { VuemojiPicker } from 'vuemoji-picker'; import { marked } from 'marked'; import DOMPurify from 'dompurify'; +import ImageCompressor from 'js-image-compressor'; // Import the compressor +import { displayToast } from "../js/popupHandler"; + + // Emoji Handling const handleEmojiClick = (detail) => { @@ -39,22 +43,107 @@ function handleDrop(event) { handleFiles(event.dataTransfer.files); } +// Handle files from file input or drag-and-drop // Handle files from file input or drag-and-drop function handleFiles(files) { - selectedFiles.value = []; - for (let file of files) { - const reader = new FileReader(); - reader.onload = () => { - const base64Content = btoa(reader.result); - selectedFiles.value.push({ - name: file.name, - size: file.size, - type: file.type, - content: base64Content, - }); - }; - reader.readAsBinaryString(file); + if (file.type.startsWith('image/')) { + // Compress the image if it's an image type + const options = { + file: file, + quality: 0.6, + mimeType: 'image/jpeg', + maxWidth: 500, // Set maximum width to 250px + maxHeight: 500, // Set maximum height to 250px + width: 500, // Resize width to 250px + height: 500, // Resize height to 250px + convertSize: Infinity, + loose: true, + redressOrientation: true, + + // Callback before compression + beforeCompress: function (result) { + console.log('Image size before compression:', result.size); + console.log('mime type:', result.type); + }, + + // Compression success callback + success: function (compressedFile) { + console.log('Image size after compression:', compressedFile.size); + console.log('mime type:', compressedFile.type); + console.log( + 'Actual compression ratio:', + ((file.size - compressedFile.size) / file.size * 100).toFixed(2) + '%' + ); + + // toast notification + let message = ` +
+ Compressed ${file.name} +
+ ${file.size} Bytes + + + + ${compressedFile.size} Bytes + + + Ratio:${((file.size - compressedFile.size) / file.size * 100).toFixed(2)}%. + + + +
+
+ `; + displayToast( + "success", + "bi-card-image", + message, + 5000 + ); + + // Convert compressed image to base64 + const reader = new FileReader(); + reader.onload = () => { + const base64Content = btoa(reader.result); + selectedFiles.value.push({ + name: compressedFile.name, + size: compressedFile.size, + type: compressedFile.type, + content: base64Content, + }); + }; + reader.readAsBinaryString(compressedFile); + }, + + // An error occurred + error: function (msg) { + console.error(msg); + displayToast( + "danger", + "bi-card-image", + `Error compressing image`, + 5000 + ); + }, + }; + + // Run image compression + new ImageCompressor(options); + } else { + // Handle non-image files + const reader = new FileReader(); + reader.onload = () => { + const base64Content = btoa(reader.result); + selectedFiles.value.push({ + name: file.name, + size: file.size, + type: file.type, + content: base64Content, + }); + }; + reader.readAsBinaryString(file); + } } } @@ -68,14 +157,14 @@ function removeFile(index) { // Transmit a new message function transmitNewMessage() { - if (typeof(chat.selectedCallsign) === 'undefined') { + if (typeof chat.selectedCallsign === 'undefined') { chat.selectedCallsign = Object.keys(chat.callsign_list)[0]; } chat.inputText = chat.inputText.trim(); if (chat.inputText.length === 0 && selectedFiles.value.length === 0) return; - const attachments = selectedFiles.value.map(file => ({ + const attachments = selectedFiles.value.map((file) => ({ name: file.name, type: file.type, data: file.content, @@ -84,8 +173,8 @@ function transmitNewMessage() { // Sanitize inputText before sending the message const sanitizedInput = DOMPurify.sanitize(marked.parse(chat.inputText)); - if (chat.selectedCallsign.startsWith("BC-")) { - return "new broadcast"; + if (chat.selectedCallsign.startsWith('BC-')) { + return 'new broadcast'; } else { if (attachments.length > 0) { newMessage(chat.selectedCallsign, sanitizedInput, attachments); @@ -95,7 +184,7 @@ function transmitNewMessage() { } chat.inputText = ''; - chatModuleMessage.value = ""; + chatModuleMessage.value = ''; resetFile(); } @@ -130,11 +219,8 @@ function applyMarkdown(formatType) { - -
+ +