Image.fromBytes constructor
- required int width,
- required int height,
- required ByteBuffer bytes,
- int bytesOffset = 0,
- Format format = Format.uint8,
- int? numChannels,
- int? rowStride,
- bool withPalette = false,
- Format paletteFormat = Format.uint8,
- Palette? palette,
- ExifData? exif,
- IccProfile? iccp,
- ChannelOrder? order,
- Map<
String, String> ? textData, - int loopCount = 0,
- FrameType frameType = FrameType.sequence,
- Color? backgroundColor,
- int frameDuration = 0,
- int frameIndex = 0,
Create an image from raw data in bytes
.
format
defines the order of color channels in bytes
.
An HTML canvas element stores colors in Format.rgba format; a Flutter
Image object stores colors in Format.rgba format.
rowStride
is the row stride, in bytes, of the source data bytes
.
This may be different than the rowStride of the Image, as some data
sources align rows to different byte alignments and include padding.
order
can be used if the source bytes
has a different channel order
than RGBA. ChannelOrder.bgra will rearrange the color channels from
BGRA to what Image wants, RGBA.
If numChannels
and order
are not provided, a default of 3 for
numChannels
and ChannelOrder.rgba for order
will be assumed.
For example, given an Html Canvas, you could create an image: var bytes = canvas.getContext('2d').getImageData(0, 0, canvas.width, canvas.height).data; var image = Image.fromBytes(width: canvas.width, height: canvas.height, bytes: canvasBytes, numChannels: 4);
Implementation
Image.fromBytes(
{required int width,
required int height,
required ByteBuffer bytes,
int bytesOffset = 0,
Format format = Format.uint8,
int? numChannels,
int? rowStride,
bool withPalette = false,
Format paletteFormat = Format.uint8,
Palette? palette,
ExifData? exif,
IccProfile? iccp,
ChannelOrder? order,
this.textData,
this.loopCount = 0,
this.frameType = FrameType.sequence,
this.backgroundColor,
this.frameDuration = 0,
this.frameIndex = 0}) {
frames.add(this);
numChannels ??= order != null ? channelOrderLength[order] : 3;
if (numChannels! < 0 || numChannels > 4) {
throw ImageException('An Image can only have 1-4 channels.');
}
order ??= numChannels == 3
? ChannelOrder.rgb
: numChannels == 4
? ChannelOrder.rgba
: numChannels == 1
? ChannelOrder.red
: ChannelOrder.grayAlpha;
if (numChannels == 1) {
// There is only one channel order
order = ChannelOrder.red;
} else if (numChannels == 2) {
// There is only one channel order
order = ChannelOrder.grayAlpha;
} else if (numChannels == 3) {
if (order != ChannelOrder.rgb && order != ChannelOrder.bgr) {
// The user asked for a channel order that conflicts with the number
// of channels.
order = ChannelOrder.rgb;
}
} else if (numChannels == 4) {
if (order != ChannelOrder.bgra &&
order != ChannelOrder.rgba &&
order != ChannelOrder.abgr &&
order != ChannelOrder.argb) {
// The user asked for a channel order that conflicts with the number
// of channels.
order = ChannelOrder.rgba;
}
}
_initialize(width, height,
format: format,
numChannels: numChannels,
withPalette: withPalette,
paletteFormat: paletteFormat,
palette: palette,
exif: exif,
iccp: iccp);
if (data == null) {
return;
}
final toBytes = data!.toUint8List();
final fromBytes = Uint8List.view(bytes, bytesOffset);
rowStride ??= getRowStride(width, numChannels, format);
final dataStride = data!.rowStride;
final stride = min(rowStride, dataStride);
var dOff = 0;
var bOff = 0;
for (int y = 0; y < height; ++y, bOff += rowStride, dOff += dataStride) {
final bRow = fromBytes.getRange(bOff, bOff + stride);
toBytes.setRange(dOff, dOff + dataStride, bRow);
}
if (numChannels == 3 && order == ChannelOrder.bgr) {
for (final p in this) {
final r = p.r;
p
..r = p.b
..b = r;
}
} else if (numChannels == 4 && order == ChannelOrder.abgr) {
for (final p in this) {
final r = p.r;
final g = p.g;
final b = p.b;
final a = p.a;
p
..r = a
..g = b
..b = g
..a = r;
}
} else if (numChannels == 4 && order == ChannelOrder.argb) {
for (final p in this) {
final r = p.r;
final g = p.g;
final b = p.b;
final a = p.a;
p
..r = a
..g = r
..b = g
..a = b;
}
} else if (numChannels == 4 && order == ChannelOrder.bgra) {
for (final p in this) {
final r = p.r;
final g = p.g;
final b = p.b;
final a = p.a;
p
..r = b
..g = g
..b = r
..a = a;
}
}
}