convert method
Convert this image to a new format
or number of channels, numChannels
.
If the new number of channels is 4 and the current image does
not have an alpha channel, then the given alpha
value will be used
to set the new alpha channel. If alpha
is not provided, then the
maxChannelValue will be used to set the alpha. If withPalette
is
true, and to target format and numChannels has fewer than 256 colors,
then the new image will be converted to use a palette.
Implementation
Image convert(
{Format? format,
int? numChannels,
num? alpha,
bool withPalette = false,
bool noAnimation = false}) {
format ??= this.format;
numChannels ??= this.numChannels;
alpha ??= formatMaxValue[format];
// Commented out because it causes problems converting a uint8 w/ palette
// to a uint1 w/ palette
/*if (withPalette &&
(numChannels >= 4 ||
!(format == Format.uint1 ||
format == Format.uint2 ||
format == Format.uint4 ||
(format == Format.uint8 && numChannels == 1))) ||
(format.index < Format.uint8.index &&
this.format.index >= Format.uint8.index)) {
withPalette = false;
}*/
if (format == this.format &&
numChannels == this.numChannels &&
((!withPalette && palette == null) ||
(withPalette && palette != null))) {
// Same format and number of channels
return Image.from(this);
}
Image? firstFrame;
for (final frame in frames) {
final newImage = Image(
width: frame.width,
height: frame.height,
format: format,
numChannels: numChannels,
withPalette: withPalette,
exif: frame._exif?.clone(),
iccp: frame.iccProfile?.clone(),
backgroundColor: frame.backgroundColor?.clone(),
frameType: frame.frameType,
loopCount: frame.loopCount,
frameDuration: frame.frameDuration)
..textData = frame.textData != null
? Map<String, String>.from(frame.textData!)
: null;
if (firstFrame != null) {
firstFrame.addFrame(newImage);
} else {
firstFrame = newImage;
}
final pal = newImage.palette;
final f = newImage.palette?.format ?? format;
if (pal != null) {
final usedColors = <int, int>{};
var numColors = 0;
final op = frame.getPixel(0, 0);
Color? c;
for (final np in newImage) {
final nr = (op.rNormalized * 255).floor();
final ng = (op.gNormalized * 255).floor();
final nb = (op.bNormalized * 255).floor();
final h = rgbaToUint32(nr, ng, nb, 0);
if (usedColors.containsKey(h)) {
np.index = usedColors[h]!;
} else {
usedColors[h] = numColors;
np.index = numColors;
c = convertColor(op,
to: c, format: f, numChannels: numChannels, alpha: alpha);
pal.setRgb(numColors, c.r, c.g, c.b);
numColors++;
}
op.moveNext();
}
} else {
final op = frame.getPixel(0, 0);
for (final np in newImage) {
convertColor(op, to: np, alpha: alpha);
op.moveNext();
}
}
if (noAnimation) {
break;
}
}
return firstFrame!;
}