image-in-browser
Version:
Package for encoding / decoding images, transforming images, applying filters, drawing primitives on images on the client side (no need for server Node.js)
205 lines • 6.83 kB
JavaScript
import { Format, FormatType } from '../color/format.js';
import { getImageDataBytes, } from './image-data.js';
import { PixelUint8 } from './pixel-uint8.js';
import { PixelRangeIterator } from './pixel-range-iterator.js';
import { ColorRgb8 } from '../color/color-rgb8.js';
import { ColorRgba8 } from '../color/color-rgba8.js';
import { MathUtils } from '../common/math-utils.js';
export class MemoryImageDataUint8 {
get width() {
return this._width;
}
set width(v) {
this._width = v;
}
get height() {
return this._height;
}
set height(v) {
this._height = v;
}
get data() {
return this._data;
}
get numChannels() {
return this._numChannels;
}
get format() {
return Format.uint8;
}
get formatType() {
return FormatType.uint;
}
get buffer() {
return this._data.buffer;
}
get rowStride() {
return this._width * this._numChannels;
}
get iterator() {
return PixelUint8.imageData(this);
}
get byteLength() {
return this._data.byteLength;
}
get length() {
return this._data.byteLength;
}
get maxChannelValue() {
var _a, _b;
return (_b = (_a = this._palette) === null || _a === void 0 ? void 0 : _a.maxChannelValue) !== null && _b !== void 0 ? _b : 255;
}
get maxIndexValue() {
return 255;
}
get hasPalette() {
return this.palette !== undefined;
}
get palette() {
return this._palette;
}
set palette(p) {
this._palette = p;
}
get isHdrFormat() {
return false;
}
get isLdrFormat() {
return !this.isHdrFormat;
}
get bitsPerChannel() {
return 8;
}
constructor(width, height, numChannels, data) {
this._width = width;
this._height = height;
this._numChannels = numChannels;
this._palette = undefined;
this._data =
data !== null && data !== void 0 ? data : new Uint8Array(this._width * this._height * this._numChannels);
}
static palette(width, height, palette) {
const data = new Uint8Array(width * height);
const d = new MemoryImageDataUint8(width, height, 1, data);
d._palette = palette;
return d;
}
static from(other, skipPixels = false) {
var _a;
const data = skipPixels
? new Uint8Array(other.data.length)
: other.data.slice();
const d = new MemoryImageDataUint8(other.width, other.height, other._numChannels, data);
d._palette = (_a = other.palette) === null || _a === void 0 ? void 0 : _a.clone();
return d;
}
getRange(x, y, width, height) {
return new PixelRangeIterator(PixelUint8.imageData(this), x, y, width, height);
}
getColor(r, g, b, a) {
return a === undefined
? new ColorRgb8(MathUtils.clampInt255(r), MathUtils.clampInt255(g), MathUtils.clampInt255(b))
: new ColorRgba8(MathUtils.clampInt255(r), MathUtils.clampInt255(g), MathUtils.clampInt255(b), MathUtils.clampInt255(a));
}
getPixel(x, y, pixel) {
let p = pixel;
if (p === undefined || !(p instanceof PixelUint8) || p.image !== this) {
p = PixelUint8.imageData(this);
}
p.setPosition(x, y);
return p;
}
setPixel(x, y, p) {
this.setPixelRgba(x, y, p.r, p.g, p.b, p.a);
}
setPixelR(x, y, r) {
const index = y * this.rowStride + x * this.numChannels;
this.data[index] = Math.trunc(r);
}
setPixelRgb(x, y, r, g, b) {
const index = y * this.rowStride + x * this._numChannels;
this._data[index] = Math.trunc(r);
if (this._numChannels > 1) {
this._data[index + 1] = Math.trunc(g);
if (this._numChannels > 2) {
this._data[index + 2] = Math.trunc(b);
}
}
}
setPixelRgba(x, y, r, g, b, a) {
const index = y * this.rowStride + x * this._numChannels;
this._data[index] = Math.trunc(r);
if (this._numChannels > 1) {
this._data[index + 1] = Math.trunc(g);
if (this._numChannels > 2) {
this._data[index + 2] = Math.trunc(b);
if (this._numChannels > 3) {
this._data[index + 3] = Math.trunc(a);
}
}
}
}
setPixelRgbSafe(x, y, r, g, b) {
if (x < 0 || x >= this.width || y < 0 || y >= this.height) {
return;
}
this.setPixelRgb(x, y, r, g, b);
}
setPixelRgbaSafe(x, y, r, g, b, a) {
if (x < 0 || x >= this.width || y < 0 || y >= this.height) {
return;
}
this.setPixelRgba(x, y, r, g, b, a);
}
clear(c) {
const c8 = c === null || c === void 0 ? void 0 : c.convert({
format: Format.uint8,
});
if (this._numChannels === 1) {
const ri = c8 === undefined ? 0 : MathUtils.clampInt255(c8.r);
this._data.fill(ri);
}
else if (this._numChannels === 2) {
const ri = c8 === undefined ? 0 : MathUtils.clampInt255(c8.r);
const gi = c8 === undefined ? 0 : MathUtils.clampInt255(c8.g);
const rg = (gi << 8) | ri;
const u16 = new Uint16Array(this._data.buffer);
u16.fill(rg);
}
else if (this._numChannels === 4) {
const ri = c8 === undefined ? 0 : MathUtils.clampInt255(c8.r);
const gi = c8 === undefined ? 0 : MathUtils.clampInt255(c8.g);
const bi = c8 === undefined ? 0 : MathUtils.clampInt255(c8.b);
const ai = c8 === undefined ? 0 : MathUtils.clampInt255(c8.a);
const rgba = (ai << 24) | (bi << 16) | (gi << 8) | ri;
const u32 = new Uint32Array(this._data.buffer);
u32.fill(rgba);
}
else {
const ri = c8 === undefined ? 0 : MathUtils.clampInt255(c8.r);
const gi = c8 === undefined ? 0 : MathUtils.clampInt255(c8.g);
const bi = c8 === undefined ? 0 : MathUtils.clampInt255(c8.b);
for (const p of this) {
p.r = ri;
p.g = gi;
p.b = bi;
}
}
}
clone(skipPixels = false) {
return MemoryImageDataUint8.from(this, skipPixels);
}
toUint8Array() {
return new Uint8Array(this.buffer);
}
getBytes(opt) {
return getImageDataBytes(this, opt);
}
toString() {
return `${this.constructor.name} (w: ${this._width}, h: ${this._height}, ch: ${this._numChannels})`;
}
[Symbol.iterator]() {
return PixelUint8.imageData(this);
}
}
//# sourceMappingURL=image-data-uint8.js.map