#21 Displaying The Optimized Images
Saturday, March 9, 2019
In this article we will see how to create the ui for displaying the original and optimized images from the previous article. One of the more interesting parts is seeing how to read the sizes of the files located on the server and to organize the results using linq for efficient display on the screen.
Parts
- Part 29: Offset Pager Urls
- Part 28: Offset Pager Start
- Part 27: Mock Context Builder
- Part 26: Mock Repository
- Part 25: Mock Async
- Part 24: Picture Tag Helper
- Part 23: Img DPR Tag Helper
- Part 22: Img Responsive Tag Helper
- Part 21: Img Optimized Display
- Part 20: Img Optimization
- Part 19: Img Lazy Loading
- Part 18: Img Responsive
- Part 17: Bottom Nav
- Part 16: Main Nav Cookie
- Part 15: Main Nav Mobile
- Part 14: Main Nav Search
- Part 13: Main Nav Auth
- Part 12: Main Nav Anchors
- Part 11: Main Nav Logo
- Part 10: Search Results
- Part 9: Search Manager
- Part 8: Search Start
- Part 7: Seeding the Database
- Part 6: Domain Database
- Part 5: Emailing Exceptions
- Part 4: Mailkit
- Part 3: View Renderer
- Part 2: Upgrade to 2.1
- Part 1: Quick Start
Code behind
- WebUi
- Pages
- Optimizing-Images.cshtml.cs
- Pages
To display our images so that we can visual compare the original with the optimized versions we will start by adding the code that we need to our code behind (a). To make things easier for this example I have included three different classes in this one file which normally I would not suggest doing.
Optimizing-Images.cshtml.cs
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace WebUi.Pages {
public class OptimizingImagesModel : PageModel
{
private readonly IHostingEnvironment _env;
public OptimizingImagesModel(IHostingEnvironment env)
{
_env = env;
Images = new List<ImageCollection>();
}
public List<ImageCollection> Images { get; }
public void OnGet()
{
var originals = Directory
.EnumerateFiles($"{_env.WebRootPath}/images/optimizing-images/originals/")
.Select(x => new FileInfo(x))
.ToArray();
var optimized = Directory
.EnumerateFiles($"{_env.WebRootPath}/images/optimizing-images/")
.Select(x => new FileInfo(x))
.AsQueryable();
foreach (var info in originals)
{
var images = new ImageCollection(info);
var infoNameWithoutExtension = Path.GetFileNameWithoutExtension(info.Name);
var filteredOptimized = optimized
.Where(x => Path.GetFileNameWithoutExtension(x.Name) == infoNameWithoutExtension);
images.AddRange(filteredOptimized);
Images.Add(images);
}
}
}
public class ImageCollection
{
private readonly Image _original;
public ImageCollection(FileInfo info)
{
_original = new Image(info, true);
Images = new List<Image>{ _original };
Type = info.Extension.Replace(".", "").ToUpper();
}
public List<Image> Images { get; }
public string Type { get; }
public void AddRange(IQueryable<FileInfo> images)
{
Images.AddRange(images.Select(x => new Image(x, false, _original.Length)));
}
}
public class Image
{
public Image(FileInfo file, bool isOriginal, long originalLength = 1)
{
var extension = file.Extension;
Length = file.Length;
NameWithExtension = file.Name;
NameWithoutExtension = NameWithExtension.Replace(extension, "");
ReductionPercentage = isOriginal
? string.Empty
: (1 - Length / (float)originalLength).ToString("P");
Size = $"{Length / 1000f}kb";
if (isOriginal)
{
Label = "Original";
Src = $"/images/optimizing-images/originals/{NameWithExtension}";
}
else
{
switch (extension)
{
case ".jpeg":
Label = "MozJPEG";
break;
case ".png":
Label = "OptiPNG";
break;
case ".webp":
Label = "WebP";
break;
default:
Label = extension;
break;
}
Src = $"/images/optimizing-images/{NameWithExtension}";
}
}
public string Label { get; }
public long Length { get; }
public string NameWithExtension { get; }
public string NameWithoutExtension { get; }
public string ReductionPercentage { get; }
public string Size { get; }
public string Src { get; }
}
}
Displaying the results
- WebUi
- Pages
- Optimizing-Images.cshtml
- Pages
With our model created it takes just a few lines of code to be able to see the results of our image optimization along side of the original images (b).
Optimizing-Images.cshtml
@page
@model WebUi.Pages.OptimizingImagesModel
@{
ViewData["Title"] = "Optimizing Images";
}
<div style="font-size: 32px;">
@foreach (var imagesCollection in Model.Images)
{
<h2>@imagesCollection.Type</h2>
<div style="display: flex;">
@foreach (var image in imagesCollection.Images)
{
<div>
<label>@image.Label @image.ReductionPercentage (@image.Size)</label>
<img src="@image.Src">
</div>
}
</div>
}
</div>