Mobile Development 8 min read

Evaluation of Four Blur Solutions for Image Processing in a Flutter Music App

The study compares four image‑blur approaches for a Flutter music app—real‑time BackdropFilter, CPU‑intensive StackBlur, server‑side GaussianBlur, and compact BlurHash—showing that BackdropFilter causes frame‑rate stutter, StackBlur adds decode overhead, server GaussianBlur offloads work with caching benefits, while BlurHash minimizes storage at the cost of visual fidelity, guiding developers to select the method that fits their performance and quality needs.

Tencent Music Tech Team
Tencent Music Tech Team
Tencent Music Tech Team
Evaluation of Four Blur Solutions for Image Processing in a Flutter Music App

Blurring images is a common development scenario. In the optimization of the MOO Music App, we summarized several experiences with blur in Flutter. When determining a blur solution we faced two decision points: the implementation of blur logic and the choice of blur algorithm. To address these, we designed four solutions for comparison.

Solution 1: BackdropFilter (Flutter)

Flutter provides the BackdropFilter widget, which can apply ImageFilter.blur to achieve a Gaussian blur effect. It is used by wrapping the target widget with BackdropFilter . The implementation works in the RenderObject#paint method, processing the current layer’s image data. The advantage is real‑time blur, even for animated GIF backgrounds. The drawback is that in scroll‑heavy or animation‑heavy scenes the continuous repaint incurs noticeable latency, leading to stutter.

Experimental data (see image) shows that SkCanvas#flush average time increases from 1.448 ms (without BackdropFilter) to 3.314 ms (with BackdropFilter), an increase of about 2 ms per frame, which can affect the 16 ms frame budget.

Solution 2: StackBlur (Dart)

StackBlur is an algorithm that approximates Gaussian blur with faster computation. During image loading, the original image data is decoded, the blur is computed, and the result is set back to the ImageWidget . However, StackBlur requires decoded image data while Flutter’s Image widget only accepts encoded data, so an extra decode (step 1) and encode (step 2) are needed, increasing latency. To mitigate this, the heavy computation can be offloaded to a separate isolate using Dart’s Isolate , but this introduces memory overhead because the image must be copied between the main thread and the isolate.

Solution 3: Server‑side GaussianBlur (Golang)

The blur computation is performed on the server, and the client only downloads and displays the blurred image. This allows caching of blurred results, avoiding duplicate calculations and relieving the client from heavy processing. Experiments with four images of different sizes focused on rendering time, showing reduced GPU load on the client side.

Solution 4: Server‑side BlurHash (Golang)

BlurHash generates a short hash string (20‑30 characters) that represents a blurred version of the image. The server computes the hash, and the client renders the image from this hash. The method divides the image into rectangles, computes color vectors for each, and stores them in the hash. The main advantage is a much smaller storage size compared to full blurred images. The downside is a noticeable loss of visual fidelity compared to other blur methods.

Performance tests on three image sizes (50×50, 200×200, 500×500) showed that BlurHash latency is mainly affected by the decode dimensions. Since typical app usage requires a 200×200 region, we compared the 200×200 data with Solutions 2 and 3.

Overall comparison of storage size and blur quality is illustrated in the following figures:

Summary

Solution 1 supports dynamic blur but may cause stutter in heavily repainted scenes. Solution 2 has slower decoding speed and larger memory usage. Solution 3 reduces client load and benefits from server‑side caching, but depends on network conditions. Solution 4 offers the smallest storage size but sacrifices blur quality.

Choosing the appropriate solution depends on the scenario: prefer Solution 1 when real‑time blur is required; for previewing small images, Solution 4 is acceptable; otherwise, Solution 3 is generally the best choice.

FlutterPerformancebackend processingBlurHashImage BlurStackBlur
Tencent Music Tech Team
Written by

Tencent Music Tech Team

Public account of Tencent Music's development team, focusing on technology sharing and communication.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.