compositeImage function
Composite the image src
onto the image dst
.
In other words, drawImage will take an rectangular area from src of
width srcW
and height srcH
at position (srcX
,srcY
) and place it
in a rectangular area of dst
of width dstW
and height dstH
at
position (dstX
,dstY
).
If the source and destination coordinates and width and heights differ,
appropriate stretching or shrinking of the image fragment will be performed.
The coordinates refer to the upper left corner. This function can be used to
copy regions within the same image (if dst
is the same as src
)
but if the regions overlap the results will be unpredictable.
if center
is true, the src
will be centered in dst
.
Implementation
Image compositeImage(Image dst, Image src,
{int? dstX,
int? dstY,
int? dstW,
int? dstH,
int? srcX,
int? srcY,
int? srcW,
int? srcH,
BlendMode blend = BlendMode.alpha,
bool linearBlend = false,
bool center = false,
Image? mask,
Channel maskChannel = Channel.luminance}) {
dstX ??= 0;
dstY ??= 0;
srcX ??= 0;
srcY ??= 0;
srcW ??= src.width;
srcH ??= src.height;
dstW ??= (dst.width < src.width) ? dstW = dst.width : src.width;
dstH ??= (dst.height < src.height) ? dst.height : src.height;
if (center) {
// if [src] is wider than [dst]
var wdt = dst.width - src.width;
if (wdt < 0) wdt = 0;
dstX = wdt ~/ 2;
// if [src] is higher than [dst]
var height = dst.height - src.height;
if (height < 0) height = 0;
dstY = height ~/ 2;
}
if (dst.hasPalette) {
dst.convert(numChannels: dst.numChannels);
}
final dy = srcH / dstH;
final dx = srcW / dstW;
final yCache = List<int>.generate(dstH, (y) => srcY! + (y * dy).toInt(),
growable: false);
final xCache = List<int>.generate(dstW, (x) => srcX! + (x * dx).toInt(),
growable: false);
if (blend == BlendMode.direct) {
_directComposite(
src, dst, dstX, dstY, dstW, dstH, xCache, yCache, mask, maskChannel);
} else {
_composite(src, dst, dstX, dstY, dstW, dstH, xCache, yCache, blend,
linearBlend, mask, maskChannel);
}
return dst;
}