diff --git a/.github/workflows/prepare.yaml b/.github/workflows/prepare.yaml index 356514e..4528117 100644 --- a/.github/workflows/prepare.yaml +++ b/.github/workflows/prepare.yaml @@ -43,7 +43,7 @@ jobs: - name: Build example app working-directory: example - run: flutter build web --debug + run: flutter build web - name: Dry run pub publish # We don't want it to fail the CI, it's just to see how would `pub publish` behave. diff --git a/lib/src/blurhash.dart b/lib/src/blurhash.dart index d671ebc..0902a23 100644 --- a/lib/src/blurhash.dart +++ b/lib/src/blurhash.dart @@ -121,19 +121,39 @@ Future optimizedBlurHashDecode({ return Future.value(pixels); } -/// Approximated version using square roots for faster computation -/// This will produce slightly different (darker) results but is faster +// Create this once as a static variable +final List _sRGBLookupTable = _createSRGBLookupTable(256); + +List _createSRGBLookupTable(int size) { + final table = List.filled(size, 0); + for (int i = 0; i < size; i++) { + final v = i / (size - 1); + if (v <= 0.0031308) { + table[i] = v * 12.92; + } else { + table[i] = 1.055 * pow(v, 1 / 2.4) - 0.055; + } + } + return table; +} + int _approximatedLinearTosRGB(double value) { final v = max(0.0, min(1.0, value)); - if (v <= 0.0031308) { - return (v * 12.92 * 255 + 0.5).toInt(); - } else { - // Faster approximation with square roots - final vv = sqrt(v); - final vvv = sqrt(vv); - return ((1.055 * vv * vvv - 0.055) * 255 + 0.5).toInt(); + // Find the closest indices in the lookup table + final pos = v * (_sRGBLookupTable.length - 1); + final idx = pos.floor(); + final fract = pos - idx; + + // Edge case for the maximum value + if (idx >= _sRGBLookupTable.length - 1) { + return (_sRGBLookupTable[_sRGBLookupTable.length - 1] * 255 + 0.5).toInt(); } + + // Linear interpolation between the two closest values + final result = + _sRGBLookupTable[idx] * (1 - fract) + _sRGBLookupTable[idx + 1] * fract; + return (result * 255 + 0.5).toInt(); } Future blurHashDecode({ diff --git a/test/blur_hash_widget_test.dart b/test/blur_hash_widget_test.dart new file mode 100644 index 0000000..7e72c13 --- /dev/null +++ b/test/blur_hash_widget_test.dart @@ -0,0 +1,31 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:flutter_blurhash/flutter_blurhash.dart'; + +void main() { + testWidgets('BlurHash widget basic smoke test', (WidgetTester tester) async { + const String testHash = 'LGF5]+Yk^6#M@-5c,1J5@[or[Q6.'; + + await tester.pumpWidget( + MaterialApp( + home: Scaffold( + body: Center( + child: SizedBox( + width: 200, + height: 200, + child: BlurHash( + hash: testHash, + ), + ), + ), + ), + ), + ); + + expect(find.byType(BlurHash), findsOneWidget); + + final BlurHash blurHash = tester.widget(find.byType(BlurHash)); + expect(blurHash.hash, equals(testHash)); + expect(blurHash.image, isNull); + }); +}