rgba_image.dart 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. import 'dart:typed_data';
  2. import 'dart:ui' as ui;
  3. import 'package:flutter/foundation.dart';
  4. import 'package:flutter/painting.dart';
  5. class RgbaImage extends ImageProvider<RgbaImage> {
  6. final Uint8List bytes;
  7. final int width;
  8. final int height;
  9. final double scale;
  10. const RgbaImage(
  11. this.bytes, {
  12. required this.width,
  13. required this.height,
  14. this.scale = 1.0,
  15. });
  16. Future<ui.Codec> _loadAsync(
  17. RgbaImage key,
  18. DecoderCallback decode,
  19. ) async {
  20. assert(key == this);
  21. final buffer = await ui.ImmutableBuffer.fromUint8List(bytes);
  22. final descriptor = ui.ImageDescriptor.raw(
  23. buffer,
  24. width: width,
  25. height: height,
  26. pixelFormat: ui.PixelFormat.rgba8888,
  27. );
  28. return await descriptor.instantiateCodec();
  29. }
  30. @override
  31. Future<RgbaImage> obtainKey(ImageConfiguration configuration) {
  32. return SynchronousFuture<RgbaImage>(this);
  33. }
  34. @override
  35. bool operator ==(Object other) {
  36. if (other.runtimeType != runtimeType) return false;
  37. return other is RgbaImage && other.bytes == bytes && other.scale == scale;
  38. }
  39. @override
  40. int get hashCode => Object.hash(bytes.hashCode, scale);
  41. @override
  42. String toString() =>
  43. '${objectRuntimeType(this, 'RgbaImage')}(${describeIdentity(bytes)}, scale: $scale)';
  44. @override
  45. ImageStreamCompleter load(RgbaImage key, DecoderCallback decode) {
  46. return MultiFrameImageStreamCompleter(
  47. codec: _loadAsync(key, decode),
  48. scale: key.scale,
  49. debugLabel: 'RgbaImage(${describeIdentity(key.bytes)})',
  50. );
  51. }
  52. }