cropFromRoi function
Implementation
Future<img.Image> cropFromRoi(img.Image src, RectF roi) async {
if (roi.xmin < 0 || roi.ymin < 0 || roi.xmax > 1 || roi.ymax > 1) {
throw ArgumentError('ROI coordinates must be normalized [0,1], got: (${roi.xmin}, ${roi.ymin}, ${roi.xmax}, ${roi.ymax})');
}
if (roi.xmin >= roi.xmax || roi.ymin >= roi.ymax) {
throw ArgumentError('Invalid ROI: min coordinates must be less than max');
}
final rgb = src.getBytes(order: img.ChannelOrder.rgb);
final rp = ReceivePort();
final params = {
'sendPort': rp.sendPort,
'op': 'crop',
'w': src.width,
'h': src.height,
'rgb': TransferableTypedData.fromList([rgb]),
'roi': {
'xmin': roi.xmin,
'ymin': roi.ymin,
'xmax': roi.xmax,
'ymax': roi.ymax,
},
};
await Isolate.spawn(_imageTransformIsolate, params);
final Map msg = await rp.first as Map;
rp.close();
if (msg['ok'] != true) {
final error = msg['error'];
throw StateError('Image crop failed: ${error ?? "unknown error"}');
}
final ByteBuffer outBB = (msg['rgb'] as TransferableTypedData).materialize();
final Uint8List outRgb = outBB.asUint8List();
final int ow = msg['w'] as int;
final int oh = msg['h'] as int;
return img.Image.fromBytes(width: ow, height: oh, bytes: outRgb.buffer, order: img.ChannelOrder.rgb);
}