pref: calculate image hash from raw bytes

This commit is contained in:
Fabian Freund
2025-02-21 11:54:26 +01:00
parent a3c900cf62
commit a9cad61d36
9 changed files with 22 additions and 32 deletions
+6 -6
View File
@@ -1,18 +1,18 @@
import 'dart:ui';
import 'package:lensai/extensions/image.dart';
class EquatableImage {
final Image value;
final int? _imageHash;
EquatableImage(this.value, {required int? hash}) : _imageHash = hash;
static Future<EquatableImage> calculate(Image image) async {
final imageHash = await image.calculateHash();
//For now we only calculate the has from encoded image on decoding
return EquatableImage(image, hash: imageHash);
}
// static Future<EquatableImage> calculate(Image image) async {
// final imageHash = await image.calculateHash();
// return EquatableImage(image, hash: imageHash);
// }
@override
int get hashCode => _imageHash.hashCode;
+3 -4
View File
@@ -1,6 +1,5 @@
import 'dart:ui';
import 'package:lensai/domain/entities/equatable_image.dart';
import 'package:xxh3/xxh3.dart';
extension ImageHash on Image {
@@ -14,7 +13,7 @@ extension ImageHash on Image {
return null;
}
Future<EquatableImage> toEquatable() {
return EquatableImage.calculate(this);
}
// Future<EquatableImage> toEquatable() {
// return EquatableImage.calculate(this);
// }
}
@@ -18,12 +18,10 @@ class BrowserIcon with FastEquatable {
required Color? dominantColor,
required IconSource source,
}) async {
final image = await tryDecodeImage(
bytes,
).then((image) => image!.toEquatable());
final image = await tryDecodeImage(bytes);
return BrowserIcon(
image: image,
image: image!,
dominantColor: dominantColor,
source: source,
);
@@ -39,10 +39,7 @@ class TabStates extends _$TabStates {
Future<void> _onIconChange(IconChangeEvent event) async {
final IconChangeEvent(:tabId, :bytes) = event;
final image = await bytes.mapNotNull(
(bytes) =>
tryDecodeImage(bytes).then((image) async => image?.toEquatable()),
);
final image = await bytes.mapNotNull((bytes) => tryDecodeImage(bytes));
final current = state[tabId] ?? TabState.$default(tabId);
state = {...state}..[tabId] = current.copyWith.icon(image);
@@ -51,10 +48,7 @@ class TabStates extends _$TabStates {
Future<void> _onThumbnailChange(ThumbnailEvent event) async {
final ThumbnailEvent(:tabId, :bytes) = event;
final image = await bytes.mapNotNull(
(bytes) =>
tryDecodeImage(bytes).then((image) async => image?.toEquatable()),
);
final image = await bytes.mapNotNull((bytes) => tryDecodeImage(bytes));
final current = state[tabId] ?? TabState.$default(tabId);
state = {...state}..[tabId] = current.copyWith.thumbnail(image);
@@ -173,7 +173,7 @@ final selectedTabStateProvider = AutoDisposeProvider<TabState?>.internal(
@Deprecated('Will be removed in 3.0. Use Ref instead')
// ignore: unused_element
typedef SelectedTabStateRef = AutoDisposeProviderRef<TabState?>;
String _$tabStatesHash() => r'c2169e467962d006015bf50d09e93b3f4bf596e6';
String _$tabStatesHash() => r'2f4af9df4d648f7fb940f02e14f4a6762bb21d8a';
/// See also [TabStates].
@ProviderFor(TabStates)
@@ -50,9 +50,7 @@ class WebExtensionsState extends _$WebExtensionsState {
Future<void> _onIconChange(ExtensionIconEvent event) async {
final ExtensionIconEvent(:extensionId, :bytes) = event;
final image = await tryDecodeImage(
bytes,
).then((image) async => image?.toEquatable());
final image = await tryDecodeImage(bytes);
if (image != null) {
if (_imageCache[extensionId] != image) {
@@ -7,7 +7,7 @@ part of 'web_extensions_state.dart';
// **************************************************************************
String _$webExtensionsStateHash() =>
r'7fd0cb313fb433f7896bfe0f89a4545f94f58793';
r'9382461e7e72c31946a5308642baaac307977a15';
/// Copied from Dart SDK
class _SystemHash {
@@ -66,7 +66,7 @@ class HistorySuggestions extends HookConsumerWidget {
return ListTile(
leading: RepaintBoundary(
child: RawImage(
image: icon.data,
image: icon.data?.value,
height: 24,
width: 24,
),
@@ -1,12 +1,13 @@
import 'dart:typed_data';
import 'dart:ui';
import 'package:lensai/domain/entities/equatable_image.dart';
import 'package:lensai/utils/lru_cache.dart';
import 'package:xxh3/xxh3.dart';
final _cache = LRUCache<int, Image>(100);
final _cache = LRUCache<int, EquatableImage>(100);
Future<Image?> tryDecodeImage(
Future<EquatableImage?> tryDecodeImage(
Uint8List bytes, {
int? targetWidth,
int? targetHeight,
@@ -28,9 +29,9 @@ Future<Image?> tryDecodeImage(
);
final frameInfo = await codec.getNextFrame();
final image = frameInfo.image;
final image = EquatableImage(frameInfo.image, hash: digest);
if (image.width > 0) {
if (image.value.width > 0) {
_cache.set(digest, image);
return image;
}