fluttercommunity / flutter_blurhash

Compact representation of a placeholder for an image. Encode a blurry image under 30 caracters for instant display like used by Medium. Maintainer: @Solido
https://pub.dev/packages/flutter_blurhash
MIT License
519 stars 65 forks source link

Extract color avarages from the BlurHash(for whole image and for seperate sides) #5

Open aytunch opened 4 years ago

aytunch commented 4 years ago

The data representation makes it quite easy to extract colour averages of the image for different areas. You can easily find approximations of things like the average colour of the top edge of the image, or of a corner. There is some code in the Swift BlurHashKit implementation to experiment with this. Also, the average colour of the entire image is just the DC component and can be decoded even without implementing any of the more complicated DCT stuff.

They stated that it is "easy" but I could not find a way to extract the main color of an image from the blurhash code. It also says we can easily extract this info for the sides of the image. Reminds me of Phillips ambilight TVs.

This can be a cool feature.

DagAgren commented 4 years ago

There is an advanced implementation in Swift that implements this stuff in https://github.com/woltapp/blurhash/tree/master/Swift/BlurHashKit, specifically https://github.com/woltapp/blurhash/blob/master/Swift/BlurHashKit/ColourProbes.swift.

ndahlquist commented 2 years ago

This is simpler than I expected: the average color is encoded in characters 3-6. (see https://github.com/woltapp/blurhash/blob/master/Algorithm.md#structure).

    // In a blurhash, chars 3-6 represent the average color.
    // Refer to https://github.com/woltapp/blurhash/blob/master/Algorithm.md
    final averageColorStr = blurhash.substring(2, 6);
    // _decode83 defined here: https://github.com/fluttercommunity/flutter_blurhash/blob/6bdec75a7352d1e52f3267296d5726e092d3ebec/lib/src/blurhash.dart#L159
    final averageColorInt = _decode83(averageColorStr);
    // Blurhashes don't include alpha. Set alpha to 0xFF.
    final averageColor = Color(0xFF000000 | averageColorInt);

    return BlurHash(
      hash: blurhash,
      color: averageColor,
      image: imageUrl,
    );

One problem is that I'm seeing a white flash between the solid color and the blurred image. Not sure how to fix that yet.

aytunch commented 2 years ago

@ndahlquist thanks for this it is very useful. Do you know how to do the same for the 4 sides of the blurhash image also?

ndahlquist commented 2 years ago

I think for the 4 sides, that's slightly more complicated. You need to add the DC component (the "averageColor" above) with the AC components sampled at the edges of the image (that's what https://github.com/woltapp/blurhash/blob/master/Swift/BlurHashKit/ColourProbes.swift seems to do). As an approximation, you can probably skip the higher-order AC components, and just add the DC + first AC component.