findSimilarImages function

Future<List<SimilarImagesGroup>> findSimilarImages(
  1. String directoryPath, {
  2. List<String> exts = const ['.jpg', '.jpeg', '.png'],
  3. int distanceThreshold = 20,
  4. void onProgress(
    1. SimilarImagesProgress progress
    )?,
  5. HashFn hashFn = HashFn.perceptual,
})

Check all similar imgs under the directory.

  • directoryPath is the path of the directory to search for images.
  • exts is extensions, defaults to '.jpg', '.jpeg', '.png'
  • distanceThreshold is the threshold for the distance between two images. Defaults to 20. Bigger value means less similar images.
  • onProgress is a callback that will be called with progress updates.

Note: On web platforms, this function requires different usage patterns. In browsers, you need to provide URLs to images or use the File API with user-selected files.

Implementation

Future<List<SimilarImagesGroup>> findSimilarImages(
  String directoryPath, {
  List<String> exts = const ['.jpg', '.jpeg', '.png'],
  int distanceThreshold = 20,
  void Function(SimilarImagesProgress progress)? onProgress,
  HashFn hashFn = HashFn.perceptual,
}) async {
  if (_isWeb) {
    throw UnsupportedError(
        'findSimilarImages is not supported on web; use findSimilarImagesWeb');
  }
  // Create ports for communication
  final receivePort = ReceivePort();

  // Define the data to send to the isolate
  final params = _SimilarImagesParams(
    directoryPath: directoryPath,
    exts: exts,
    distanceThreshold: distanceThreshold,
    hashFn: hashFn,
  );

  // Spawn the isolate
  final isolate = await Isolate.spawn(
    _findSimilarImagesIsolate,
    (receivePort.sendPort, params),
  );

  // Handle messages from the isolate
  final completer = Completer<List<List<(String, ImageHash)>>>();

  receivePort.listen((message) {
    if (message is SimilarImagesProgress) {
      // Progress update
      onProgress?.call(message);
    } else if (message is List<List<(String, ImageHash)>>) {
      // Final result
      completer.complete(message);
      receivePort.close();
      isolate.kill();
    }
  });

  return completer.future;
}