9.3 KiB
sidebar_position | title |
---|---|
2 | Image display |
Use Base64 images
The image files is not the best way to save image, in many architecture the image are saving in the database.
We modify the code to save the image in the database ;)
Update the model
Open the item model and add a property which will contain the base64 image.
public class Item
{
public int Id { get; set; }
public string DisplayName { get; set; }
public string Name { get; set; }
public int StackSize { get; set; }
public int MaxDurability { get; set; }
public List<string> EnchantCategories { get; set; }
public List<string> RepairWith { get; set; }
public DateTime CreatedDate { get; set; }
public DateTime? UpdatedDate { get; set; }
// highlight-next-line
public string ImageBase64 { get; set; }
}
public class ItemModel
{
...
// highlight-next-line
public string ImageBase64 { get; set; }
}
Update the local service
We will also modify the local service to save the image in base64, we remove all reference to save image.
Remove the highlight code !
public async Task Add(ItemModel model)
{
// Get the current data
var currentData = await _localStorage.GetItemAsync<List<Item>>("data");
// Simulate the Id
model.Id = currentData.Max(s => s.Id) + 1;
// Add the item to the current data
currentData.Add(ItemFactory.Create(model));
// highlight-start
// Save the image
var imagePathInfo = new DirectoryInfo($"{_webHostEnvironment.WebRootPath}/images");
// Check if the folder "images" exist
if (!imagePathInfo.Exists)
{
imagePathInfo.Create();
}
// Determine the image name
var fileName = new FileInfo($"{imagePathInfo}/{model.Name}.png");
// Write the file content
await File.WriteAllBytesAsync(fileName.FullName, model.ImageContent);
// highlight-end
// Save the data
await _localStorage.SetItemAsync("data", currentData);
}
public async Task Update(int id, ItemModel model)
{
// Get the current data
var currentData = await _localStorage.GetItemAsync<List<Item>>("data");
// Get the item int the list
var item = currentData.FirstOrDefault(w => w.Id == id);
// Check if item exist
if (item == null)
{
throw new Exception($"Unable to found the item with ID: {id}");
}
// highlight-start
// Save the image
var imagePathInfo = new DirectoryInfo($"{_webHostEnvironment.WebRootPath}/images");
// Check if the folder "images" exist
if (!imagePathInfo.Exists)
{
imagePathInfo.Create();
}
// Delete the previous image
if (item.Name != model.Name)
{
var oldFileName = new FileInfo($"{imagePathInfo}/{item.Name}.png");
if (oldFileName.Exists)
{
File.Delete(oldFileName.FullName);
}
}
// Determine the image name
var fileName = new FileInfo($"{imagePathInfo}/{model.Name}.png");
// Write the file content
await File.WriteAllBytesAsync(fileName.FullName, model.ImageContent);
// highlight-end
// Modify the content of the item
ItemFactory.Update(item, model);
// Save the data
await _localStorage.SetItemAsync("data", currentData);
}
public async Task Delete(int id)
{
// Get the current data
var currentData = await _localStorage.GetItemAsync<List<Item>>("data");
// Get the item int the list
var item = currentData.FirstOrDefault(w => w.Id == id);
// Delete item in
currentData.Remove(item);
// highlight-start
// Delete the image
var imagePathInfo = new DirectoryInfo($"{_webHostEnvironment.WebRootPath}/images");
var fileName = new FileInfo($"{imagePathInfo}/{item.Name}.png");
if (fileName.Exists)
{
File.Delete(fileName.FullName);
}
// highlight-end
// Save the data
await _localStorage.SetItemAsync("data", currentData);
}
Update the factory
This is in the factory that we transform the image to base64.
Change the code of the factory :
public static ItemModel ToModel(Item item, byte[] imageContent)
{
return new ItemModel
{
Id = item.Id,
DisplayName = item.DisplayName,
Name = item.Name,
RepairWith = item.RepairWith,
EnchantCategories = item.EnchantCategories,
MaxDurability = item.MaxDurability,
StackSize = item.StackSize,
ImageContent = imageContent,
// highlight-next-line
ImageBase64 = string.IsNullOrWhiteSpace(item.ImageBase64) ? Convert.ToBase64String(imageContent) : item.ImageBase64
};
}
public static Item Create(ItemModel model)
{
return new Item
{
Id = model.Id,
DisplayName = model.DisplayName,
Name = model.Name,
RepairWith = model.RepairWith,
EnchantCategories = model.EnchantCategories,
MaxDurability = model.MaxDurability,
StackSize = model.StackSize,
CreatedDate = DateTime.Now,
// highlight-next-line
ImageBase64 = Convert.ToBase64String(model.ImageContent)
};
}
public static void Update(Item item, ItemModel model)
{
item.DisplayName = model.DisplayName;
item.Name = model.Name;
item.RepairWith = model.RepairWith;
item.EnchantCategories = model.EnchantCategories;
item.MaxDurability = model.MaxDurability;
item.StackSize = model.StackSize;
item.UpdatedDate = DateTime.Now;
// highlight-next-line
item.ImageBase64 = Convert.ToBase64String(model.ImageContent);
}
Update the views
Remove the highlight code !
...
protected override async Task OnInitializedAsync()
{
var item = await DataService.GetById(Id);
var fileContent = await File.ReadAllBytesAsync($"{WebHostEnvironment.WebRootPath}/images/default.png");
// highlight-start
if (File.Exists($"{WebHostEnvironment.WebRootPath}/images/{itemModel.Name}.png"))
{
fileContent = await File.ReadAllBytesAsync($"{WebHostEnvironment.WebRootPath}/images/{item.Name}.png");
}
// highlight-end
// Set the model with the item
itemModel = ItemFactory.ToModel(item, fileContent);
}
...
...
<p>
<label>
Current Item image:
<img src="data:image/png;base64, @(itemModel.ImageBase64)" class="img-thumbnail" title="@itemModel.DisplayName" alt="@itemModel.DisplayName" style="min-width: 50px; max-width: 150px"/>
</label>
</p>
...
...
<DataGridColumn TItem="Item" Field="@nameof(Item.Id)" Caption="Image">
<DisplayTemplate>
@if (!string.IsNullOrWhiteSpace(context.ImageBase64))
{
<img src="data:image/png;base64, @(context.ImageBase64)" class="img-thumbnail" title="@context.DisplayName" alt="@context.DisplayName" style="min-width: 50px; max-width: 150px" />
}
else
{
<img src="images/default.png" class="img-thumbnail" title="@context.DisplayName" alt="@context.DisplayName" style="max-width: 150px"/>
}
</DisplayTemplate>
</DataGridColumn>
...
Concept: Base64 Images
To understand base64 images, first let’s understand why we need it. Web developers from all around the world is currently trying to minimise unusual data to maximise their website performance. Website performance can be optimised by reducing page size, reducing number of requests, position of scripts and stylesheets & many other factors affect webpage speed. Base64 method is used to minimise the server requests by integrating image data in HTML code.
Base64 method uses Data URI and its syntax is as below:
data:[<MIMETYPE>][;charset=<CHARSET>][;base64],<DATA>
To integrate it in HTML you have to write html img tag code like this:
<img alt="coderiddles" src="data:image/jpg;base64,S)OWE902WEIWUOLKASJODIIWJ9878978JKKJKIWEURU4954590EJ09JT9T99TIR32EQ2EKJDKSDFDNXZCNBAC3SASDASD45ASD5ASD5A4SDASD54DS56DB67V6VBN78M90687LKJKSDFJSDF76F7S7D78F9SDF78S6FSDF9SDFSFSDGFSDFSDLFJSDF7SD86FSDFSDFSDFS8F89SDIFOSDFSFJHKJL" />
We can easily convert base64 images using online tool.
We can also integrate base64 images inside stylesheet (background-image property).
.imagediv
{
background: url(data:image/jpg;base64,S)OWE902WEIWUOLKASJODIIWJ9878978JKKJKIWEURU4954590EJ09JT9T99TIR32EQ2EKJDKSDFDNXZCNBAC3SASDASD45ASD5ASD5A4SDASD54DS56DB67V6VBN78M90687LKJKSDFJSDF76F7S7D78F9SDF78S6FSDF9SDFSFSDGFSDFSDLFJSDF7SD86FSDFSDFSDFS8F89SDIFOSDFSFJHKJL);
}
Base64 images can increase performance?
If we encode all our websites small images, wrap them inside css or html code. Doing this will reduce the number of HTTP requests because client (browser) don’t have to issue separate request for images. That will definitely increase performance of website. Because most of page load time is taken for transferring data over internet. Not to process it on server.
Advantages of Base64 images:
- Removes separate HTTP Requests for image loading by wrapping encoded image code inside css or HTML.
- Image encoded data can be saved inside database and can generate image file. Just incase we lost image file copy.
Disadvantages Base64 images:
- Though Base64 increases performance but be careful. Doing so will increase image size approximately 20-25%. than what it is actually in its binary form. So more data has to be transferred on internet. For mobile devices it is a bit drawback.
- Even if we apply gzip compression, doing so will only decrease css file size to around 10-12%.
- IE6 & IE7 not supports Data URI which means base64 images will not be loaded in ie6 & ie7 browsers.
- If you apply base64 encoding to lots of medium sized images it will increase HTML content size or CSS content size. So browser has to do roundtrip to get full content.