createImageFromChannels static method
Implementation
static Image createImageFromChannels(int? colorMode, int? bitDepth, int width,
int height, List<PsdChannel> channelList) {
final output = Image(width, height);
final pixels = output.getBytes();
final channels = <int, PsdChannel>{};
for (var ch in channelList) {
channels[ch.id] = ch;
}
final numChannels = channelList.length;
final ns = (bitDepth == 8)
? 1
: (bitDepth == 16)
? 2
: -1;
if (ns == -1) {
throw ImageException('PSD: unsupported bit depth: $bitDepth');
}
final channel0 = channels[0];
final channel1 = channels[1];
final channel2 = channels[2];
final channel_1 = channels[-1];
for (var y = 0, di = 0, si = 0; y < height; ++y) {
for (var x = 0; x < width; ++x, si += ns) {
switch (colorMode) {
case COLORMODE_RGB:
final xi = di;
pixels[di++] = _ch(channel0!.data, si, ns);
pixels[di++] = _ch(channel1!.data, si, ns);
pixels[di++] = _ch(channel2!.data, si, ns);
pixels[di++] =
numChannels >= 4 ? _ch(channel_1!.data, si, ns) : 255;
final r = pixels[xi];
final g = pixels[xi + 1];
final b = pixels[xi + 2];
final a = pixels[xi + 3];
if (a != 0) {
// Photoshop/Gimp blend the image against white (argh!),
// which is not what we want for compositing. Invert the blend
// operation to try and undo the damage.
pixels[xi] = (((r + a) - 255) * 255) ~/ a;
pixels[xi + 1] = (((g + a) - 255) * 255) ~/ a;
pixels[xi + 2] = (((b + a) - 255) * 255) ~/ a;
}
break;
case COLORMODE_LAB:
final L = _ch(channel0!.data, si, ns) * 100 >> 8;
final a = _ch(channel1!.data, si, ns) - 128;
final b = _ch(channel2!.data, si, ns) - 128;
final alpha = numChannels >= 4 ? _ch(channel_1!.data, si, ns) : 255;
final rgb = labToRgb(L, a, b);
pixels[di++] = rgb[0];
pixels[di++] = rgb[1];
pixels[di++] = rgb[2];
pixels[di++] = alpha;
break;
case COLORMODE_GRAYSCALE:
final gray = _ch(channel0!.data, si, ns);
final alpha = numChannels >= 2 ? _ch(channel_1!.data, si, ns) : 255;
pixels[di++] = gray;
pixels[di++] = gray;
pixels[di++] = gray;
pixels[di++] = alpha;
break;
case COLORMODE_CMYK:
final c = _ch(channel0!.data, si, ns);
final m = _ch(channel1!.data, si, ns);
final y = _ch(channel2!.data, si, ns);
final k = _ch(channels[numChannels == 4 ? -1 : 3]!.data, si, ns);
final alpha = numChannels >= 5 ? _ch(channel_1!.data, si, ns) : 255;
final rgb = cmykToRgb(255 - c, 255 - m, 255 - y, 255 - k);
pixels[di++] = rgb[0];
pixels[di++] = rgb[1];
pixels[di++] = rgb[2];
pixels[di++] = alpha;
break;
default:
throw ImageException('Unhandled color mode: $colorMode');
}
}
}
return output;
}