As imagens adequadamente otimizadas carregam mais rápido e também fornecem uma melhor experiência do usuário. Construir o nosso também será um ótimo exercício para aprender JavaScript. Então, vamos construir um!
Resultado final
Aqui está o que estamos construindo:
Construindo a interface
Teremos uma interface HTML simples como esta:
1 |
|
2 |
|
3 |
Resize images to a smaller size without losing quality.
|
4 |
|
5 |
|
6 |
|
7 |
type="file" |
8 |
id="file-input" |
9 |
style="display: none" |
10 |
accept="image/*" |
11 |
/>
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
Em nosso HTML, temos um campo para fazer upload da imagem, uma área de visualização para exibir a imagem carregada e um Compressa e Download botão para comprimir e baixar a imagem final
Modelando a ferramenta de compressor de imagem
Hora de alguns CSs. Vamos começar estilizando o corpo e o contêiner de visualização:
1 |
@import url("https://fonts.googleapis.com/css2?family=DM+Mono:ital,wght@0,300;0,400;0,500;1,300;1,400;1,500&display=swap"); |
2 |
|
3 |
body { |
4 |
display: flex; |
5 |
justify-content: center; |
6 |
align-items: center; |
7 |
flex-direction: column; |
8 |
height: 100vh; |
9 |
margin: 0; |
10 |
background-color: #ffffff; |
11 |
text-align: center; |
12 |
font-family: "DM Mono", monospace; |
13 |
}
|
14 |
.container, .preview { |
15 |
width: 80%; |
16 |
max-width: 500px; |
17 |
margin: 0 auto; |
18 |
text-align: center; |
19 |
background-color: #ffffff; |
20 |
padding: 30px; |
21 |
border-radius: 8px; |
22 |
border: #f3ecec solid 1px; |
23 |
}
|
Por padrão, escondemos o contêiner de visualização usando display: none;
. Isso garantirá que ele se torne visível quando um usuário enviar uma imagem. Adicione os seguintes estilos aos elementos de visualização.
1 |
.preview { |
2 |
display: none; |
3 |
}
|
4 |
|
5 |
.preview-image { |
6 |
max-width: 100%; |
7 |
max-height: 200px; |
8 |
margin-top: 20px; |
9 |
}
|
Finalmente, vamos estilizar o rótulo e o botão de compressão para uma melhor interatividade do usuário.
1 |
label{ |
2 |
display: inline-block; |
3 |
}
|
4 |
|
5 |
label, |
6 |
.compress-button { |
7 |
padding: 12px 24px; |
8 |
background-color: #3498db; |
9 |
color: white; |
10 |
cursor: pointer; |
11 |
border-radius: 6px; |
12 |
transition: all 0.3s ease; |
13 |
font-weight: bold; |
14 |
text-transform: uppercase; |
15 |
font-size: 0.9rem; |
16 |
border: none; |
17 |
margin-top: 20px; |
18 |
}
|
Implementando recursos de compactação de imagem e download
Com a interface pronta, é hora de adicionar os recursos de compactação de imagem e baixar com JavaScript. Primeiro, vamos obter todos os elementos que precisam de manipulação.
1 |
const fileInput = document.getElementById("file-input"); |
2 |
const previewImage = document.querySelector(".preview-image"); |
3 |
const compressBtn = document.querySelector(".compress-button"); |
4 |
const container = document.querySelector(".container"); |
5 |
const fileName = document.getElementById("fileName"); |
6 |
const preview = document.querySelector(".preview"); |
Upload de imagem
Para lidar com uploads de imagem, usaremos o JavaScript FileReader
API. Esta API nos permite ler o conteúdo dos arquivos selecionados pelo usuário, tornando -o perfeito para nossas necessidades. O primeiro passo é adicionar um ouvinte de evento ao elemento de entrada do arquivo e ouvir o change
evento.
1 |
fileInput.addEventListener("change", (e) => { |
2 |
const file = e.target.files[0]; |
3 |
console.log(file); |
4 |
if (file) { |
5 |
const reader = new FileReader(); |
6 |
reader.onload = (e) => { |
7 |
// preview image code |
8 |
}; |
9 |
reader.readAsDataURL(file); |
10 |
} else { |
11 |
alert("no file selected"); |
12 |
} |
13 |
}); |
Quando um arquivo é selecionado, o change
o evento será acionado e o arquivo recuperado usando e.target.files[0]
. O FileReader
API fornece vários métodos, mas aqui usaremos o onload
Evento que é disparado automaticamente quando o arquivo é lido com sucesso.
O FileReader.readAsDataURL
O método lê o conteúdo do arquivo de imagem e produz um URL representando os dados da imagem. Este URL de dados é armazenado no atributo resultado do objeto de evento. A partir do atributo de resultado, podemos atribuir o URL de dados da imagem ao src
propriedade de um elemento de imagem para visualização.
Atualize o código da seguinte forma.
1 |
fileInput.addEventListener("change", (e) => { |
2 |
const file = e.target.files[0]; |
3 |
console.log(file); |
4 |
if (file) { |
5 |
const reader = new FileReader(); |
6 |
reader.onload = (e) => { |
7 |
previewImage.src = e.target.result; |
8 |
previewImage.style.display = "inline-block"; |
9 |
fileName.textContent = file.name; |
10 |
preview.style.display = "block"; |
11 |
container.style.display = "none"; |
12 |
};
|
13 |
reader.readAsDataURL(file); |
14 |
} else { |
15 |
alert("no file selected"); |
16 |
}
|
17 |
});
|
Agora, quando você envia uma imagem, pode ver uma visualização da imagem antes da compactação.



Compressa e baixe a imagem
O último recurso é a capacidade de comprimir e baixar a imagem compactada. Para fazer isso, faremos o seguinte:
- Crie um novo
Image
objeto e carregue a imagem a ser compactada - Usar
Para redimensionar a imagem
- Converta o conteúdo da tela em uma bolha.
- Baixe a nova imagem compactada
Adicione um evento de clique no botão de compactação.
1 |
compressBtn.addEventListener("click", () => { |
2 |
|
3 |
});
|
Em seguida, crie um objeto de imagem e defina seu src
atributo à fonte da imagem de visualização; Isso garante que a imagem carregada seja a que está sendo redimensionada e compactada. Então defina seu onload
Evento para garantir que a imagem esteja totalmente carregada antes de executar quaisquer operações. Em seguida, crie um elemento de tela e defina as dimensões para 50% das imagens height
e width
.
Usando o drawImage()
Método, desenhe a imagem redimensionada na tela.
1 |
compressBtn.addEventListener("click", () => { |
2 |
const img = new Image(); |
3 |
img.src = previewImage.src; |
4 |
|
5 |
img.onload = () => { |
6 |
const canvas = document.createElement("canvas"); |
7 |
const ctx = canvas.getContext("2d"); |
8 |
const width = img.width * 0.5; |
9 |
const height = img.height * 0.5; |
10 |
canvas.width = width; |
11 |
canvas.height = height; |
12 |
ctx.drawImage(img, 0, 0, width, height); |
13 |
};
|
14 |
|
15 |
});
|
Nossa imagem já foi redimensionada. O próximo passo é aplicar compressão.
Compressa a imagem redimensionada
A última etapa é exportar os dados do Canvas como um arquivo de imagem em um formato JPEG e executar compactação. Para fazer isso, usaremos o canvas.toBlob()
Método que gera uma representação do BLOB do conteúdo da tela. O .toBlob()
aceita uma função de retorno de chamada e dois argumentos opcionais: o MIME
Tipo (ou seja image/jpeg
ou image/png
) e um parâmetro de qualidade opcional (0,7 aqui) para controlar o nível de compressão.
No nosso caso, o código será assim.
1 |
compressBtn.addEventListener("click", () => { |
2 |
const img = new Image(); |
3 |
|
4 |
img.onload = () => { |
5 |
const canvas = document.createElement("canvas"); |
6 |
const ctx = canvas.getContext("2d"); |
7 |
const width = img.width * 0.5; |
8 |
const height = img.height * 0.5; |
9 |
canvas.width = width; |
10 |
canvas.height = height; |
11 |
ctx.drawImage(img, 0, 0, width, height); |
12 |
|
13 |
|
14 |
canvas.toBlob( |
15 |
(blob) => { |
16 |
|
17 |
const url = URL.createObjectURL(blob); |
18 |
const a = document.createElement("a"); |
19 |
a.href = url; |
20 |
a.download = "compressed_" + fileName.textContent; |
21 |
document.body.appendChild(a); |
22 |
a.click(); |
23 |
document.body.removeChild(a); |
24 |
URL.revokeObjectURL(url); |
25 |
},
|
26 |
"image/jpeg", |
27 |
0.7
|
28 |
);
|
29 |
};
|
30 |
img.src = previewImage.src; |
31 |
});
|
Para baixar a imagem, seguimos estas etapas:
-
const url = URL.createObjectURL(blob);
Cria um URL temporário para a imagem compactada. -
const a = document.createElement("a");
cria umelemento. O
O elemento acionará um download quando clicado.
-
a.href
Define o atributo href ao URL temporário para garantir que o link esteja associado à imagem compactada. -
a.download = "compressed_" + fileName.textContent;
Atribui um nome à imagem compactada -
document.body.appendChild(a);
Adiciona o link da imagem ao DOM -
a.click() ;
Isso desencadeia o processo de download -
document.body.removeChild(a);
eURL.revokeObjectURL(url);
Responsável pela limpeza do código após o processo de download.
Aqui está a demonstração final como um lembrete:
Conclusão
Para demonstrar, peguei uma imagem do Unsplash e a compactei com a nossa ferramenta. Com as configurações atuais, carrego o original (3,3 MB) e baixei uma versão compactada (314KB). É verdade que a imagem resultante é metade das dimensões do pixel (6.000 x 3.000px vs. 3.000 x 1.500px), mas as duas imagens são indistinguíveis ao olho humano.



Alterar o parâmetro de qualidade para apenas 0,2 nos fornece outra imagem indistinguível, mas desta vez 76kb. Claramente, haverá diferenças de qualidade, por isso é uma questão de você encontrar o equilíbrio certo. Você pode até fazer um controle na interface do usuário para especificar a quantidade de compactação.
Então, lá vamos nós – utilizando JavaScript e o elemento Canvas, vimos como podemos facilmente comprimir imagens sem comprometer a qualidade. Felizmente, isso oferecerá uma solução confiável quando você precisar otimizar as imagens para a Web.