You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			105 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Dart
		
	
			
		
		
	
	
			105 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Dart
		
	
import 'package:flutter/foundation.dart';
 | 
						|
import 'package:flutter/material.dart';
 | 
						|
 | 
						|
import 'package:blurhash_dart/blurhash_dart.dart' as b;
 | 
						|
import 'package:image/image.dart' as image;
 | 
						|
 | 
						|
class BlurHash extends StatefulWidget {
 | 
						|
  final double width;
 | 
						|
  final double height;
 | 
						|
  final String blurhash;
 | 
						|
  final BoxFit fit;
 | 
						|
 | 
						|
  const BlurHash({
 | 
						|
    super.key,
 | 
						|
    String? blurhash,
 | 
						|
    required this.width,
 | 
						|
    required this.height,
 | 
						|
    this.fit = BoxFit.cover,
 | 
						|
  }) : blurhash = blurhash ?? 'LEHV6nWB2yk8pyo0adR*.7kCMdnj';
 | 
						|
 | 
						|
  @override
 | 
						|
  State<BlurHash> createState() => _BlurHashState();
 | 
						|
}
 | 
						|
 | 
						|
class _BlurHashState extends State<BlurHash> {
 | 
						|
  Uint8List? _data;
 | 
						|
 | 
						|
  static Future<Uint8List> getBlurhashData(
 | 
						|
    BlurhashData blurhashData,
 | 
						|
  ) async {
 | 
						|
    final blurhash = b.BlurHash.decode(blurhashData.hsh);
 | 
						|
    final img = blurhash.toImage(blurhashData.w, blurhashData.h);
 | 
						|
    return Uint8List.fromList(image.encodePng(img));
 | 
						|
  }
 | 
						|
 | 
						|
  Future<Uint8List?> _computeBlurhashData() async {
 | 
						|
    if (_data != null) return _data!;
 | 
						|
    final ratio = widget.width / widget.height;
 | 
						|
    var width = 32;
 | 
						|
    var height = 32;
 | 
						|
    if (ratio > 1.0) {
 | 
						|
      height = (width / ratio).round();
 | 
						|
    } else {
 | 
						|
      width = (height * ratio).round();
 | 
						|
    }
 | 
						|
 | 
						|
    return _data ??= await compute(
 | 
						|
      getBlurhashData,
 | 
						|
      BlurhashData(
 | 
						|
        hsh: widget.blurhash,
 | 
						|
        w: width,
 | 
						|
        h: height,
 | 
						|
      ),
 | 
						|
    );
 | 
						|
  }
 | 
						|
 | 
						|
  @override
 | 
						|
  Widget build(BuildContext context) {
 | 
						|
    return FutureBuilder<Uint8List?>(
 | 
						|
      future: _computeBlurhashData(),
 | 
						|
      initialData: _data,
 | 
						|
      builder: (context, snapshot) {
 | 
						|
        final data = snapshot.data;
 | 
						|
        if (data == null) {
 | 
						|
          return Container(
 | 
						|
            width: widget.width,
 | 
						|
            height: widget.height,
 | 
						|
            color: Theme.of(context).colorScheme.onInverseSurface,
 | 
						|
          );
 | 
						|
        }
 | 
						|
        return Image.memory(
 | 
						|
          data,
 | 
						|
          fit: widget.fit,
 | 
						|
          width: widget.width,
 | 
						|
          height: widget.height,
 | 
						|
        );
 | 
						|
      },
 | 
						|
    );
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
class BlurhashData {
 | 
						|
  final String hsh;
 | 
						|
  final int w;
 | 
						|
  final int h;
 | 
						|
 | 
						|
  const BlurhashData({
 | 
						|
    required this.hsh,
 | 
						|
    required this.w,
 | 
						|
    required this.h,
 | 
						|
  });
 | 
						|
 | 
						|
  factory BlurhashData.fromJson(Map<String, dynamic> json) => BlurhashData(
 | 
						|
        hsh: json['hsh'],
 | 
						|
        w: json['w'],
 | 
						|
        h: json['h'],
 | 
						|
      );
 | 
						|
 | 
						|
  Map<String, dynamic> toJson() => {
 | 
						|
        'hsh': hsh,
 | 
						|
        'w': w,
 | 
						|
        'h': h,
 | 
						|
      };
 | 
						|
}
 |