composeImage method
Future<Uint8List>
composeImage({
- required Uint8List inputImage,
- required Uint8List watermarkImage,
- String anchor = 'bottomRight',
- double margin = 16.0,
- double widthPercent = 0.18,
- double opacity = 0.6,
- String format = 'jpeg',
- double quality = 0.9,
- double offsetX = 0.0,
- double offsetY = 0.0,
- String marginUnit = 'px',
- String offsetUnit = 'px',
override
Composes inputImage
with watermarkImage
and returns encoded bytes.
Options (all optional with defaults):
- anchor: one of 'topLeft','topRight','bottomLeft','bottomRight','center' (default: 'bottomRight')
- margin: logical pixels in output space (default: 16.0)
- widthPercent: 0..1 relative to base width (default: 0.18)
- opacity: 0..1 applied to watermark (default: 0.6)
- format: 'jpeg' | 'png' (default: 'jpeg')
- quality: 0..1 for JPEG (default: 0.9)
- offsetX/offsetY: offsets from the anchor (default: 0)
- marginUnit: 'px' | 'percent' (default: 'px')
- offsetUnit: 'px' | 'percent' (default: 'px')
Implementation
@override
Future<Uint8List> composeImage({
required Uint8List inputImage,
required Uint8List watermarkImage,
String anchor = 'bottomRight',
double margin = 16.0,
double widthPercent = 0.18,
double opacity = 0.6,
String format = 'jpeg',
double quality = 0.9,
double offsetX = 0.0,
double offsetY = 0.0,
String marginUnit = 'px',
String offsetUnit = 'px',
}) async {
pigeon.Anchor _anchorFromString(String s) {
switch (s) {
case 'topLeft':
return pigeon.Anchor.topLeft;
case 'topRight':
return pigeon.Anchor.topRight;
case 'bottomLeft':
return pigeon.Anchor.bottomLeft;
case 'center':
return pigeon.Anchor.center;
case 'bottomRight':
default:
return pigeon.Anchor.bottomRight;
}
}
pigeon.OutputFormat _formatFromString(String s) {
switch (s) {
case 'png':
return pigeon.OutputFormat.png;
case 'jpeg':
default:
return pigeon.OutputFormat.jpeg;
}
}
pigeon.MeasureUnit _unitFromString(String s) {
switch (s) {
case 'percent':
return pigeon.MeasureUnit.percent;
case 'px':
default:
return pigeon.MeasureUnit.px;
}
}
final api = pigeon.WatermarkApi();
final req = pigeon.ComposeImageRequest(
baseImage: inputImage,
watermarkImage: watermarkImage,
anchor: _anchorFromString(anchor),
margin: margin,
widthPercent: widthPercent,
opacity: opacity,
format: _formatFromString(format),
quality: quality,
offsetX: offsetX,
offsetY: offsetY,
marginUnit: _unitFromString(marginUnit),
offsetUnit: _unitFromString(offsetUnit),
);
try {
final res = await api.composeImage(req);
return res.imageBytes;
} on PlatformException catch (_) {
// Fallback to legacy MethodChannel if Pigeon channel isn't set up.
final args = <String, dynamic>{
'inputImage': inputImage,
'watermarkImage': watermarkImage,
'anchor': anchor,
'margin': margin,
'widthPercent': widthPercent,
'opacity': opacity,
'format': format,
'quality': quality,
'offsetX': offsetX,
'offsetY': offsetY,
'marginUnit': marginUnit,
'offsetUnit': offsetUnit,
};
final bytes = await methodChannel.invokeMethod<Uint8List>('composeImage', args);
if (bytes == null) {
throw PlatformException(code: 'compose_failed', message: 'No bytes returned');
}
return bytes;
}
}