Article

Implementing Dynamic Theme Colors and Blur Preview with Blurhash and mdui

AI Summary

This blog post introduces how to combine Blurhash and the mdui framework to implement dynamic theme colors and blur preview effects for images on web pages. Blurhash is a library for generating blur effects, while mdui is a frontend framework based on Material Design. The author first introduces the goal of using the dominant color of the background image to set the page theme color, and optimizing page loading performance by pre-processing images to generate Blurhash. Next, a Python script is provided for batch generating Blurhash for images and storing them in a JSON file. Then, through JavaScript code, the Blurhash is converted to a base64 format image, from which the theme color is extracted. Finally, the author demonstrates the implementation effect and provides a GitHub link to the related project.

TechnologyPublished at·Updated at·Language Chinese -> English·AI Translation
#mdui#Blurhash#Original
Time CapsulePartially time-sensitive content

This post was last updated 1 years 9 months ago

The article relies on specific frameworks like Material Design 3 and mdui which may evolve or become deprecated, though it lacks explicit dates or highly volatile current events.

modern Web developmentMaterial Design 3mdui

In modern Web development, improving user experience often comes with optimizing details. Blurhash is a library for generating and decoding blur hashes, enabling blur preview effects for images. mdui provides us with a frontend framework based on Material Design 3 (Material You), including rich components and styles. In this blog post, we will combine Blurhash and mdui to implement a page that dynamically sets theme colors based on background images and optimizes image loading performance.

GoalsH2#

We want to attach a background image at the bottom of the page and use the dominant color of this background image as the theme color for the entire page.

Pre-processing Images to Generate Blurhash and Provide Directly Through Random Image APIH2#

To avoid computational overhead during page loading, we can pre-generate the Blurhash for each image and store it in a JSON file.

The following Python script can batch process images and generate Blurhash:

python
import concurrent.futures
import os
import json
import logging
from PIL import Image
from blurhash import encode

logging.basicConfig(level=logging.INFO)

current_path = os.path.abspath(os.path.dirname(__file__))

def encode_file(file):
    logging.info(f'Encoding {file} to blurhash')
    image = Image.open(os.path.join(current_path, file))
    blurhash = encode(image, x_components=4, y_components=3)
    return file, blurhash

current_files = [f for f in os.listdir(current_path) if f.endswith(('jpg', 'png', 'jpeg'))]
blurhashes = {}

with concurrent.futures.ThreadPoolExecutor() as executor:
    future_to_file = {executor.submit(encode_file, file): file for file in current_files}
    for future in concurrent.futures.as_completed(future_to_file):
        file = future_to_file[future]
        try:
            file, blurhash = future.result()
            blurhashes[file] = blurhash
        except Exception as exc:
            logging.error('%r generated an exception: %s' % (file, exc))

with open('blurhash.json', 'w') as f:
    json.dump(blurhashes, f)

Then our backend can read this json file to get the corresponding blurhash value for the image and provide it along with the image.

The provided data looks roughly like this:

json
{
    "code": "200",
    "image": "https://cdn.tnxg.top/images/wallpaper/5.jpg",
    "blurhash": "LcI~*}r=TJS$~VX8S2b^?HW;wIoe"
}

Setting Background Image and Theme ColorH2#

At this point, we already have the image URL and its corresponding blur hash.

We can now convert the blur hash to a base64 format image:

js
    const blurredImage = (blurhash) => {
      if (!blurhash) return '';
      const pixels = decode(blurhash, 32, 32);
      const canvas = document.createElement('canvas');
      canvas.width = 32;
      canvas.height = 32;
      const ctx = canvas.getContext('2d');
      const imageData = ctx.createImageData(32, 32);
      imageData.data.set(pixels);
      ctx.putImageData(imageData, 0, 0);
      return canvas.toDataURL();
    };

Then we can create a new image object with the base64 image and extract its theme color.

Since it's an image converted from the blur hash of the original image, the dominant color tone should be quite similar, so we can directly use this color as the theme color:

js
const blurredImageData = blurredImage(data.blurhash);
const ColorImage = new Image();
ColorImage.src = blurredImageData;
getColorFromImage(ColorImage)
    .then(color => {
        setColorScheme(color);
        console.log('Color scheme set.' + color);
    })

The generated base64 blurred image can also be used as the card background, keeping the background and card color tones harmonious.

For passing Blurhash, we can use the state management library Pinia to store the converted base64 image directly in the global state, so we don't need to recalculate it every time.

Final EffectH2#

Through the above steps, we achieved displaying a blur preview image first when the page loads, and dynamically setting the theme color based on its dominant color. When the high-definition background image finishes loading, it replaces the blur preview image, improving user experience and page performance.

Here's an example of the final effect:

Example Effect
Example Effect

Project in Use

I hope this blog post helps you better understand and use Blurhash with mdui to enhance the user experience of Web applications. If you have any questions or suggestions, feel free to leave a comment.

Copyright & License
© 2024 天翔TNXG
Implementing Dynamic Theme Colors and Blur Preview with Blurhash and mdui
CCCreative Commons License
BYAttribution: You must give appropriate credit
NCNonCommercial: You may not use the material for commercial purposes
SAShareAlike: You must distribute your contributions under the same license
License:BY-NC-SA