diff --git a/client/index.js b/client/index.js new file mode 100644 index 0000000..1737db1 --- /dev/null +++ b/client/index.js @@ -0,0 +1,39 @@ +/** + * ============================================================================== + * Imports + * ============================================================================== + */ +import imageInputFileToBase64 from "./media/imageInputFileToBase64"; +import imageInputToBase64 from "./media/imageInputToBase64"; + +/** ****************************************************************************** */ +/** ****************************************************************************** */ +/** ****************************************************************************** */ +/** ****************************************************************************** */ +/** ****************************************************************************** */ +/** ****************************************************************************** */ + +/** + * ============================================================================== + * Media Functions Object + * ============================================================================== + */ +const media = { + imageInputToBase64: imageInputToBase64, + imageInputFileToBase64: imageInputFileToBase64, +}; + +/** + * ============================================================================== + * Main Export + * ============================================================================== + */ +const datasquirelClient = { + media: media, +}; + +export default datasquirelClient; + +/** ********************************************** */ +/** ********************************************** */ +/** ********************************************** */ diff --git a/client/media/imageInputFileToBase64.js b/client/media/imageInputFileToBase64.js new file mode 100644 index 0000000..efba0aa --- /dev/null +++ b/client/media/imageInputFileToBase64.js @@ -0,0 +1,104 @@ +/** + * @typedef {{ + * imageBase64: string, + * imageBase64Full: string, + * imageName: string, + * imageSize: number, + * }} FunctionReturn + */ + +/** + * ============================================================================== + * Main Function + * ============================================================================== + * @async + * + * @param {{ + * imageInputFile: { name:string }, + * maxWidth: number, + * imagePreviewNode: HTMLImageElement, + * }} params - Single object passed + * + * @returns { Promise } - Return Object + */ +export default async function imageInputFileToBase64({ imageInputFile, maxWidth, imagePreviewNode }) { + /** + * Make https request + * + * @description make a request to datasquirel.com + */ + console.log(typeof imageInputFile); + + let imageName = imageInputFile.name.replace(/\..*/, ""); + let imageDataBase64; + let imageSize; + let canvas = document.createElement("canvas"); + + const MIME_TYPE = imageInputFile.type; + const QUALITY = 0.95; + const MAX_WIDTH = maxWidth ? maxWidth : null; + + const file = imageInputFile; // get the file + const blobURL = URL.createObjectURL(file); + const img = new Image(); + + /** ********************* Add source to new image */ + img.src = blobURL; + + imageDataBase64 = await new Promise((res, rej) => { + /** ********************* Handle Errors in loading image */ + img.onerror = function () { + URL.revokeObjectURL(this.src); + console.log("Cannot load image"); + }; + + /** ********************* Handle new image when loaded */ + img.onload = function () { + URL.revokeObjectURL(this.src); + + if (MAX_WIDTH) { + const scaleSize = MAX_WIDTH / img.naturalWidth; + + canvas.width = img.naturalWidth < MAX_WIDTH ? img.naturalWidth : MAX_WIDTH; + canvas.height = img.naturalWidth < MAX_WIDTH ? img.naturalHeight : img.naturalHeight * scaleSize; + } else { + canvas.width = img.naturalWidth; + canvas.height = img.naturalHeight; + } + + const ctx = canvas.getContext("2d"); + ctx.drawImage(img, 0, 0, canvas.width, canvas.height); + + const srcEncoded = canvas.toDataURL(MIME_TYPE, QUALITY); + + if (imagePreviewNode) { + document.querySelectorAll(`[data-imagepreview='image']`).forEach((img) => { + img.src = srcEncoded; + }); + } + + res(srcEncoded); + }; + }); + + imageSize = await new Promise((res, rej) => { + canvas.toBlob( + (blob) => { + res(blob.size); + }, + MIME_TYPE, + QUALITY + ); + }); + + return { + imageBase64: imageDataBase64.replace(/.*?base64,/, ""), + imageBase64Full: imageDataBase64, + imageName: imageName, + imageSize: imageSize, + }; +} + +/** ********************************************** */ +/** ********************************************** */ +/** ********************************************** */ diff --git a/client/media/imageInputToBase64.js b/client/media/imageInputToBase64.js new file mode 100644 index 0000000..df59a2f --- /dev/null +++ b/client/media/imageInputToBase64.js @@ -0,0 +1,91 @@ +/** + * @typedef {{ + * imageBase64: string, + * imageBase64Full: string, + * imageName: string, + * }} FunctionReturn + */ + +/** + * ============================================================================== + * Main Function + * ============================================================================== + * @async + * + * @param {{ + * imageInput: HTMLInputElement, + * maxWidth: number, + * mimeType: [string='image/jpeg'] + * }} params - Single object passed + * + * @returns { Promise } - Return Object + */ +export default async function imageInputToBase64({ imageInput, maxWidth, mimeType }) { + /** + * Make https request + * + * @description make a request to datasquirel.com + */ + let imagePreviewNode = document.querySelector(`[data-imagepreview='image']`); + let imageName = imageInput.files[0].name.replace(/\..*/, ""); + let imageDataBase64; + + const MIME_TYPE = mimeType ? mimeType : "image/jpeg"; + const QUALITY = 0.95; + const MAX_WIDTH = maxWidth ? maxWidth : null; + + const file = imageInput.files[0]; // get the file + const blobURL = URL.createObjectURL(file); + const img = new Image(); + + /** ********************* Add source to new image */ + img.src = blobURL; + + imageDataBase64 = await new Promise((res, rej) => { + /** ********************* Handle Errors in loading image */ + img.onerror = function () { + URL.revokeObjectURL(this.src); + window.alert("Cannot load image!"); + }; + + /** ********************* Handle new image when loaded */ + img.onload = function () { + URL.revokeObjectURL(this.src); + + const canvas = document.createElement("canvas"); + + if (MAX_WIDTH) { + const scaleSize = MAX_WIDTH / img.naturalWidth; + + canvas.width = img.naturalWidth < MAX_WIDTH ? img.naturalWidth : MAX_WIDTH; + canvas.height = img.naturalWidth < MAX_WIDTH ? img.naturalHeight : img.naturalHeight * scaleSize; + } else { + canvas.width = img.naturalWidth; + canvas.height = img.naturalHeight; + } + + const ctx = canvas.getContext("2d"); + ctx.drawImage(img, 0, 0, canvas.width, canvas.height); + + const srcEncoded = canvas.toDataURL(MIME_TYPE, QUALITY); + + if (imagePreviewNode) { + document.querySelectorAll(`[data-imagepreview='image']`).forEach((img) => { + img.src = srcEncoded; + }); + } + + res(srcEncoded); + }; + }); + + return { + imageBase64: imageDataBase64.replace(/.*?base64,/, ""), + imageBase64Full: imageDataBase64, + imageName: imageName, + }; +} + +/** ********************************************** */ +/** ********************************************** */ +/** ********************************************** */ diff --git a/package.json b/package.json index 0ac3bcf..ce501c9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "datasquirel", - "version": "1.1.26", + "version": "1.1.27", "description": "Cloud-based SQL data management tool", "main": "index.js", "scripts": {