6
Problem
Image resizing with Javascript
Possible solution
Use the widget canvas to redesign the image, resize it and then render the image again.
Below will be cited 2 cases of use merely illustrative, as the sizes of the images will not be fixed like these, being used only to illustrate the orientation (portrait/landscape) of the image.
Case 1
This case uses the Div of dimensions 851x315
Div:
Case 1.1:
Resize an image of dimensions 1080x1920 for presentation in this div.
Imagery:
Case 1.2:
Resize an image of dimensions 1920x1080 for presentation in this div.
Imagery:
Case 2
This case uses the Div of dimensions 500x450
Div:
Case 2.1:
Resize an image of dimensions 1080x1920 for presentation in this div.
Imagery:
Case 2.2:
Resize an image of dimensions 1920x1080 for presentation in this div.
Imagery:
Logic used:
Resizing should not be done in order to model the image to fit the div, but maintaining the proportionality of its dimensions, until one of these equals to one of the dimensions of div.
The code block below is self explanatory:
if (alturaImagem <= larguraImagem) {
proporcao = alturaDiv / alturaImagem;
novaLarguraImagem = larguraImagem * proporcao;
novaAlturaImagem = alturaDiv;
} else {
proporcao = larguraDiv / larguraImagem;
novaLarguraImagem = larguraDiv;
novaAlturaImagem = alturaImagem * proporcao;
}
The problem of using this code and an element canvas to resize the image is that, soon after the process, there is a big drop in the image quality, depending on its resolution.
If it is an image of dimensions close to the div, almost no drop in quality, but if the difference is too big (example: resize an image of dimensions 7680x4320 to a div 851x315) image quality drops too much and this is very apparent.
After doing a lot of research on this, I found a post in the Soen, which teaches how to resize using a method called step-down, which to my mind means step-by-step reduction (correct me otherwise), there is a formula to calculate the number of steps that will be used, as explained in post linked.
My code:
var file, img, width, height, ratio, nWidth, nHeight;
var _URL = (window.URL) ? window.URL : window.webkitURL;
if ((file = e.target.files[0])) {
img = new Image();
img.src = _URL.createObjectURL(file);
img.onload = function () {
width = this.width;
height = this.height;
// Criação do primeiro elemento canvas
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
// Altura e largura da div
tWidth = $("div#mp-change-bg").width();
tHeight = $("div#mp-change-bg").height();
// Criação do segundo elemento canvas, que será manipulado off-screen
var oc = document.createElement("canvas");
var octx = oc.getContext("2d");
oc.width = width * 0.5;
oc.height = height * 0.5;
// 1º passo
octx.drawImage(this, 0, 0, oc.width, oc.height);
// 2º passo
octx.drawImage(oc, 0, 0, oc.width * 0.5, oc.height * 0.5);
// Definição das novas dimensões da imagem
if (height <= width) {
ratio = tHeight / height;
canvas.width = width * ratio;
canvas.height = tHeight;
} else {
ratio = tWidth / width;
canvas.width = tWidth;
canvas.height = height * ratio;
}
// 3º e último passo
ctx.drawImage(oc, 0, 0, oc.width * 0.5, oc.height * 0.5, 0, 0, canvas.width, canvas.height);
$("img#mp-image-bg").attr("src", canvas.toDataURL("image/png")).css("display", "block");
};
}
I made the code practically based on the answer given in post of Soen, and this is functional for the Case 2 quoted at the beginning of the post.
The image below is the original:
Now, the same image applied to div:
As you can see, I’m using a plugin to reposition the image in div, with drag and drop. Regardless of the orientation of the image used, it is resized correctly, with the exception of Case 1, also quoted at the beginning of post.
Using the same jaguar image, look at the result.
The image, instead of being resized, was fully stretched. The problem may have to do with the number of steps to use, because through the calculation, the result found is 0, that is, it is not to use any step, but even omitting the steps and resizing directly, the result is the same.
I apologize if the post was very extensive, but I tried to be as clear as possible exposing my problem.
Any questions, or if anything is missing, ask in the comments. :)
worked perfectly for me! Thank you!
– Thomerson Roncally