Closed ollyde closed 2 years ago
Hi, @ollydixon
It looks like you're trying to close the IsolatedWorker
immediately after calling run
before giving it a chance to warm up.
However, I might be wrong, so could you please provide a minimal reproducible code?
Thanks.
@iandis thank for you replying.
Sure, I'm doing image compression. Can't seem to figure out how to get the Web Worker to work with this one though. The docs don't tell me what to write inside them vs. what I have.
I reverted this back to Isolate, but it's the same code when I apply your library.
import 'dart:io'; import 'dart:isolate'; import 'dart:typed_data';
import 'package:bap/utils/files/helpers_files.dart';
import 'package:bap/utils/files/platform_file.dart';
import 'package:bap/utils/model_file_processing_options.dart';
import 'package:filesize/filesize.dart';
import 'package:flutter/foundation.dart';
import 'package:image/image.dart' as image_lib;
Future<CustomPlatformFile> compressImage(CustomPlatformFile platformFile) async {
if (kIsWeb) {
return _compressImageInBackground([null, platformFile]);
}
final p = ReceivePort();
await Isolate.spawn(
_compressImageInBackground,
[p.sendPort, platformFile],
errorsAreFatal: true,
);
return await p.first as CustomPlatformFile;
}
// Future<PlatformFile> _compressImageInBackground(PlatformFile platformFile, FileProcessingOptions options) async {
Future<CustomPlatformFile> _compressImageInBackground(List<Object?> arguments) async {
try {
final sendPort = arguments[0] as SendPort?;
final platformFile = arguments[1] as CustomPlatformFile;
final options = platformFile.fileProcessingOptons;
// Not image
if (!isImage(platformFile)) {
if (sendPort == null) {
return platformFile;
}
sendPort.send(platformFile);
return Isolate.exit();
}
// Heic, server side compress.
if (isHeic(platformFile)) {
if (kDebugMode) {
print("Cannot compress HEIC");
}
platformFile.fileProcessingOptons = FileProcessingOptions(
clientOnlyUploadTrackingUid: options?.clientOnlyUploadTrackingUid,
clientCompressed: false,
clientResizedWidth: null,
saveOriginalFile: true,
compressImage: true,
resizeImageWidth: options?.resizeImageWidth ?? 720,
);
if (sendPort == null) {
return platformFile;
}
sendPort.send(platformFile);
return Isolate.exit();
}
image_lib.Image? image;
if (platformFile.bytes == null && !kIsWeb) {
image = image_lib.decodeImage(await File(platformFile.path!).readAsBytes());
} else {
image = image_lib.decodeImage(platformFile.bytes!);
}
// Failed, so do it on the server.
if (image == null) {
if (kDebugMode) {
print("Failed image compressing");
}
platformFile.fileProcessingOptons = FileProcessingOptions(
clientOnlyUploadTrackingUid: options?.clientOnlyUploadTrackingUid,
clientCompressed: false,
clientResizedWidth: null,
saveOriginalFile: true,
compressImage: true,
resizeImageWidth: options?.resizeImageWidth ?? 720,
);
if (sendPort == null) {
return platformFile;
}
sendPort.send(platformFile);
return Isolate.exit();
}
int originalLength = image.length;
if (image.width > (options?.clientResizedWidth ?? 720)) {
image = image_lib.copyResize(
image,
width: (options?.clientResizedWidth ?? 720),
interpolation: image_lib.Interpolation.average,
);
if (kDebugMode) {
print("Resized image");
}
}
final compressedJgp = image_lib.encodeJpg(image, quality: 90);
if (kDebugMode) {
print("--- Compressing file ---");
print("Input size : " + filesize(originalLength));
print("Outpu size : " + filesize(image.length));
}
// Success.
final platformFileNew = CustomPlatformFile(
name: platformFile.name,
size: compressedJgp.length,
bytes: Uint8List.fromList(compressedJgp),
fileProcessingOptons: FileProcessingOptions(
clientOnlyUploadTrackingUid: options?.clientOnlyUploadTrackingUid,
clientCompressed: true,
clientResizedWidth: image.width,
saveOriginalFile: false,
compressImage: false,
resizeImageWidth: null,
),
);
if (sendPort == null) {
return platformFileNew;
}
sendPort.send(platformFileNew);
return Isolate.exit();
} catch (e) {
if (kDebugMode) {
print(e);
}
rethrow;
}
}
And the supporting class
import 'dart:typed_data';
import 'package:bap/utils/model_file_processing_options.dart';
import 'package:file_picker/file_picker.dart';
class CustomPlatformFile extends PlatformFile {
FileProcessingOptions? fileProcessingOptons;
CustomPlatformFile({
required String name,
required int size,
this.fileProcessingOptons,
String? path,
Uint8List? bytes,
}) : super(
name: name,
size: size,
bytes: bytes,
path: path,
);
CustomPlatformFile.fromPlatformFile({
required PlatformFile file,
this.fileProcessingOptons,
}) : super(
name: file.name,
size: file.size,
bytes: file.bytes,
path: file.path,
identifier: file.identifier,
readStream: file.readStream,
);
}
Hi @ollydixon, from what I see, I think you were trying to close IsolatedWorker
when your _compressImageInBackground
fails. My suggestion is, don't close IsolatedWorker
if you still need it running. However, I'll be patching this error in 0.1.1 as it should not throw error when calling close
. Thanks!
Thanks @iandis we're still figuring out how to get this working on Web hehe :-D
You need to create/import image compression API using javascript, then call it using JsIsolatedWorker @ollydixon
@iandis ahh I though this converted the Dart code to JS automatically hehe.
When running the isolate for the first time it fails. Then all isolates afterwards succeed.
Looks like a library bug.