Skip to content

Commit 64a0510

Browse files
authored
Optimize RawImage.split() function
1 parent 9e74fc3 commit 64a0510

File tree

1 file changed

+25
-11
lines changed

1 file changed

+25
-11
lines changed

src/utils/image.js

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -638,19 +638,33 @@ export class RawImage {
638638
}
639639

640640
/**
641-
* Splits the image data into separate channels.
642-
* The number of elements in the array corresponds to the number of channels in the image.
643-
* @returns {Array<Uint8ClampedArray|Uint8Array>} An array containing separate channel data.
641+
* Split the image data into individual bands. This method returns an array of individual image bands from an image.
642+
* For example, splitting an "RGB" image creates three new images each containing a copy of one of the original bands (red, green, blue).
643+
*
644+
* Inspired by PIL's `Image.split()` [function](https://pillow.readthedocs.io/en/latest/reference/Image.html#PIL.Image.Image.split).
645+
* @returns {(Uint8Array|Uint8ClampedArray)[]} An array containing bands.
644646
*/
645-
toChannels() {
646-
// Split each channel into a separate entry in a `channels` array.
647-
const channels = [];
648-
for (let c = 0; c < this.channels; c++) {
649-
channels.push(
650-
this.data.filter((_, i) => i % this.channels === c)
651-
);
647+
split() {
648+
const { data, channels } = this;
649+
650+
/** @type {typeof Uint8Array | typeof Uint8ClampedArray} */
651+
const data_type = /** @type {any} */(data.constructor);
652+
const per_channel_length = data.length / channels;
653+
654+
// Pre-allocate buffers for each channel
655+
const split_data = Array.from(
656+
{ length: channels },
657+
() => new data_type(per_channel_length),
658+
);
659+
660+
// Write pixel data
661+
for (let i = 0; i < per_channel_length; ++i) {
662+
const data_offset = channels * i;
663+
for (let j = 0; j < channels; ++j) {
664+
split_data[j][i] = data[data_offset + j];
665+
}
652666
}
653-
return channels;
667+
return split_data;
654668
}
655669

656670
/**

0 commit comments

Comments
 (0)