From 1445959d0521b9249846d749cad0addc8ec09ee8 Mon Sep 17 00:00:00 2001 From: "DESKTOP-T0O5CDB\\DESK-555BD" Date: Thu, 17 Oct 2024 10:34:00 -0600 Subject: [PATCH] thumbnail resize using Hermite interpolation --- Views/Vehicle/_VehicleModal.cshtml | 4 +- wwwroot/js/shared.js | 117 ++++++++++++++++++++++++++++- 2 files changed, 118 insertions(+), 3 deletions(-) diff --git a/Views/Vehicle/_VehicleModal.cshtml b/Views/Vehicle/_VehicleModal.cshtml index cf7c374..2716385 100644 --- a/Views/Vehicle/_VehicleModal.cshtml +++ b/Views/Vehicle/_VehicleModal.cshtml @@ -124,12 +124,12 @@ @if (!string.IsNullOrWhiteSpace(Model.ImageLocation)) { - + } else { - + } diff --git a/wwwroot/js/shared.js b/wwwroot/js/shared.js index aaf57b8..5f459fe 100644 --- a/wwwroot/js/shared.js +++ b/wwwroot/js/shared.js @@ -162,9 +162,124 @@ function toggleOdometerAdjustment() { $("#odometerAdjustments").collapse('hide'); } } +function uploadThumbnail(event) { + var originalImage = event.files[0]; + var maxHeight = 290; + try { + //load image and perform Hermite resize + var img = new Image(); + img.onload = function () { + URL.revokeObjectURL(img.src); + var imgWidth = img.width; + var imgHeight = img.height; + if (imgHeight > maxHeight) { + //only scale if height is greater than threshold + var imgScale = maxHeight / imgHeight; + var newImgWidth = imgWidth * imgScale; + var newImgHeight = imgHeight * imgScale; + var resizedCanvas = hermiteResize(img, newImgWidth, newImgHeight); + resizedCanvas.toBlob((blob) => { + let file = new File([blob], originalImage.name, { type: "image/jpeg" }); + uploadFileAsync(file); + }, 'image/jpeg'); + } else { + uploadFileAsync(originalImage); + } + } + img.src = URL.createObjectURL(originalImage); + } catch (error) { + console.log(`Error while attempting to upload and resize thumbnail - ${error}`); + uploadFileAsync(originalImage); + } +} +//Resize method using Hermite interpolation +//JS implementation by viliusle +function hermiteResize(origImg, width, height) { + var canvas = document.createElement("canvas"); + var ctx = canvas.getContext("2d"); + canvas.width = origImg.width; + canvas.height = origImg.height; + ctx.drawImage(origImg, 0, 0); + + var width_source = canvas.width; + var height_source = canvas.height; + width = Math.round(width); + height = Math.round(height); + + var ratio_w = width_source / width; + var ratio_h = height_source / height; + var ratio_w_half = Math.ceil(ratio_w / 2); + var ratio_h_half = Math.ceil(ratio_h / 2); + + + var img = ctx.getImageData(0, 0, width_source, height_source); + var img2 = ctx.createImageData(width, height); + var data = img.data; + var data2 = img2.data; + + for (var j = 0; j < height; j++) { + for (var i = 0; i < width; i++) { + var x2 = (i + j * width) * 4; + var weight = 0; + var weights = 0; + var weights_alpha = 0; + var gx_r = 0; + var gx_g = 0; + var gx_b = 0; + var gx_a = 0; + var center_y = (j + 0.5) * ratio_h; + var yy_start = Math.floor(j * ratio_h); + var yy_stop = Math.ceil((j + 1) * ratio_h); + for (var yy = yy_start; yy < yy_stop; yy++) { + var dy = Math.abs(center_y - (yy + 0.5)) / ratio_h_half; + var center_x = (i + 0.5) * ratio_w; + var w0 = dy * dy; //pre-calc part of w + var xx_start = Math.floor(i * ratio_w); + var xx_stop = Math.ceil((i + 1) * ratio_w); + for (var xx = xx_start; xx < xx_stop; xx++) { + var dx = Math.abs(center_x - (xx + 0.5)) / ratio_w_half; + var w = Math.sqrt(w0 + dx * dx); + if (w >= 1) { + //pixel too far + continue; + } + //hermite filter + weight = 2 * w * w * w - 3 * w * w + 1; + var pos_x = 4 * (xx + yy * width_source); + //alpha + gx_a += weight * data[pos_x + 3]; + weights_alpha += weight; + //colors + if (data[pos_x + 3] < 255) + weight = weight * data[pos_x + 3] / 250; + gx_r += weight * data[pos_x]; + gx_g += weight * data[pos_x + 1]; + gx_b += weight * data[pos_x + 2]; + weights += weight; + } + } + data2[x2] = gx_r / weights; + data2[x2 + 1] = gx_g / weights; + data2[x2 + 2] = gx_b / weights; + data2[x2 + 3] = gx_a / weights_alpha; + } + } + //clear and resize canvas + canvas.width = width; + canvas.height = height; + ctx.clearRect(0, 0, width, height); + + //draw + ctx.putImageData(img2, 0, 0); + return canvas; +} function uploadFileAsync(event) { let formData = new FormData(); - formData.append("file", event.files[0]); + if (event.files != undefined && event.files.length > 0) { + formData.append("file", event.files[0]); + } else { + formData.append("file", event); + } sloader.show(); $.ajax({ url: "/Files/HandleFileUpload",