« Ritorna al blog

Ritorna alla lista completa degli articoli

Come convertire le immagini in formato jpg o png in webp?

ASP.NET CORE - dicembre 15, 2022

Uno dei problemi ricorrenti, di quando si progetta un'applicazione web, è il caricamento delle immagini. Una buona gestione delle immagini migliora sensibilmente il caricamento della pagina web e quindi una migliore user experience.

Il formato .webp, sviluppato da Google, è stato creato proprio per ottimizzare il caricamento delle immagini sul web. Ma è davvero necessario implementare questo formato nelle proprie applicazioni? Dipende, in quanto ormai esistono numerosi modi o librerie per poter ottimizzare un'immagine nei formati canonici dopo il caricamento sul server. Il formato *.webp da il suo meglio quando si ha l'esigenza principale di mantenere la stessa risoluzione del file originale o quando bisogna memorizzare una sequenza di immagini per le animazioni.

Molto dibattuta è la questione a livello SEO. Non è detto che utilizzando il formato *.webp si abbia un vantaggio netto in termini di posizionamento della SERP (Search Engine Results Pages). Quando andiamo ad analizzare il sito, con gli strumenti offerti da Google, viene consigliato di pubblicare le immagini nel formato più recente riportando il valore potenziale per la compressione anche laddove le differenze sono minime; tuttavia, se un sito è snello e veloce nel suo insieme ottiene comunque una buona e corretta indicizzazione. I fattori che concorrono ad una corretto posizionamento sono molteplici e non possono essere riconducibili solo alla compressione delle immagini.

In questo tutorial ci concentriamo sulla conversione di un'immagine nel formato *.webp, salvandola sia nel formato originale che quello compresso.

Per prima cosa creiamo il nostro progetto ASP.NET CORE MVC (Model View Controller)

Come convertire le immagini in formato jpg o png in webp?

Il progetto si chiamerà UploadWebP

Come convertire le immagini in formato jpg o png in webp?

La versione del Framework è la 7.0

Come convertire le immagini in formato jpg o png in webp?

Per poter scrivere il codice che ci interessa dobbiamo installare alcuni pacchetti Nuget che si occupano di processare e convertire le immagini in webp. Avete due opzioni: 

1) Linea di comando utilizzando la Console di Gestione Pacchetti

Install-Package System.Drawing.Common
Install-Package ImageProcessor
Install-Package ImageProcessor.Plugins.WebP

2) Utilizzando l'interfaccia di Visual Studio. Cliccando, con il pulsante destro del mouse, sul nome della soluzione o del progetto dovete selezionare la voce gestisci pacchetti Nuget e cercare i pacchetti scrivendo l'iniziale del nome.

Completata l'installazione del pacchetti necessari, creiamo una cartella in wwwroot per l'upload dei file che chiameremo, con molta fantasia, images

Passiamo all'interfaccia del nostro piccolo programma iniziando dal modulo di caricamento. Posizioniamoci nella vista creata di default da Visual Studio chiamata Index.cshtml e scriviamo il seguente codice:

@model Images
@{
    ViewData["Title"] = "Home Page";
}

<div class="text-center">
    <h1 class="display-4">Welcome</h1>
    <p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>

<form method="post" enctype="multipart/form-data" asp-antiforgery="true">
    <div class="form-group mb-3">
        <label for="formFile" class="form-label">Carica immagine</label>
        <input class="form-control" name="image" type="file" id="formFile" />
        <small class="form-text text-muted">Formati consentiti: *.jpeg, *.png</small>
    </div>
    <div class="form-group mb-3">
        <input type="submit" value="Upload" class="btn btn-primary" />
    </div>
</form>

@if (Model != null)
{
    <picture>
        <source srcset="@Model.WebPImage" type="image/webp" />
        <img src="@Model.NormalImage" alt="Immagine non trovata" />
    </picture>
}

Aggiungiamo al file site.css che si trova nella cartella wwwroot/css questo codice css per dare un'altezza dinamica all'immagine una volta caricata:

picture, picture img {
    height: 50vh;
}

Il codice prevede un modulo formattato con Bootstrap e un'anterprima dell'immagine ottimizzata che andremo a caricare. E' interessante notare che nell'anteprima, in caso di mancato supporto dell'estensione webp, viene riportata l'immagine originaria; tuttavia, è una procedura di per se già obsoleta in quanto ormai i principali browser supportano già questa estensione. Lo riporto solo per completezza legata al tutorial. Ecco un'anteprima del nostro bellissimo programma:

Come convertire le immagini in formato jpg o png in webp?

Adesso non dobbiamo fare altro che scrivere la logica del programma andando nel Controller Home copiando o scrivendo il seguente codice nel nuovo metodo che si chiamerà, sempre con molta fantasia, Index:

[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Index(IFormFile image)
{
	// 1 - Controlla se è stata caricata un'immagine e se le estensioni sono corrette
	if (image == null || image.Length <= 0) return View();
	string[] allowedImageTypes = new string[] { "image/jpeg", "image/png" };
	if (!allowedImageTypes.Contains(image.ContentType.ToLower())) return View();

	// 2 - Percorso dove salvare l'immagine
	string imagesPath = Path.Combine(hostingEnvironment.WebRootPath, "images");
	string webPFileName = Path.GetFileNameWithoutExtension(image.FileName) + ".webp";
	string normalImagePath = Path.Combine(imagesPath, image.FileName);
	string webPImagePath = Path.Combine(imagesPath, webPFileName);

	// 3 - Salva l'immagine nel formato originale
	using (var normalFileStream = new FileStream(normalImagePath, FileMode.Create))
	{
		image.CopyTo(normalFileStream);
	}

	// 4 - Salva l'immagine nel formato WebP
	using (var webPFileStream = new FileStream(webPImagePath, FileMode.Create))
	{
		using ImageFactory imageFactory = new(preserveExifData: false);
		imageFactory.Load(image.OpenReadStream())
					.Format(new WebPFormat())
					.Quality(50)
					.Save(webPFileStream);
	}

	// 5 - Restituisce l'immagine originale e compressa
	Images viewModel = new()
	{
		NormalImage = "/images/" + image.FileName,
		WebPImage = "/images/" + webPFileName
	};

	return View(viewModel);
}

Il codice è molto semplice ma riporto comunque una breve spiegazione.

  1. Verifichiamo l'estensione del file. Quando si carica un file è bene fare gli opportuni controlli. In questo caso controlliamo che sia un'immagine con estensione *.png o *.jpg; inoltre, ricordatevi di verificare che l'estensione sia trasformata in minuscolo perché altrimenti il confronto non risulterebbe corretto.
  2. Impostiamo il percorso dell'immagine che punta alla cartella images precedentemente creata.
  3. Salviamo l'immagine nella sua dimensione e risoluzione originale.
  4. Salviamo l'immagine con estensione *.webp decidendo sia la qualità della compressione sia se preservare o meno l'EXIF (Exchangeable Image File Format) dell'immagine.
  5. Nell'ultimo step, la classe restituisce due percorsi che contengono sia l'immagine compressa che quella originale. In questo modo, potrete vedere le differenze e scegliere la percentuale di compressione ottimale a seconda del tipo di progetto.

Una volta caricata la foto, il programma mostrerà a video questo risultato:

Come convertire le immagini in formato jpg o png in webp?

Questo sorriso mette allegria… 

Andando nella cartella wwwroot/images troveremo due file. Aprite i due file e confrontate il peso e la qualità della foto con l'estensione *.webp. Nell'esempio in questione, ho caricato un'immagine di per se già molto ottimizzata e nonostante tutto la compressione è stata ottima e con una perdità di qualità quasi impercettibile.

Come convertire le immagini in formato jpg o png in webp?Come convertire le immagini in formato jpg o png in webp?

Tuttavia, in alcuni casi, facendo numerosi test e impostando una compressione pari a 100 ho notato che si potrebbe avere un risultato anomalo dovuto ad alcune immagini precedentemente trattate o già compresse. Qualcuno potrebbe pensare, a rigor di logica, che impostando la qualità a 100 otterrà un'immagine simile a quella originale in termini di peso. In realtà non è cosi. Ecco un esempio di compressione pari a 100 della stessa foto. Come si nota, l'immagine compressa in *.webp arriva addirittura a pesare molto di più del dovuto se si imposta una qualità o un livello di compressione pari a 100.

Come convertire le immagini in formato jpg o png in webp?Come convertire le immagini in formato jpg o png in webp?

 

 

 

Come convertire le immagini in formato jpg o png in webp?