hdr-canvas 0.0.9 → 0.0.11
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +79 -5
- package/dist/@types/hdr-canvas.d.ts +57 -0
- package/dist/hdr-canvas.cjs +25 -20
- package/dist/hdr-canvas.cjs.map +1 -1
- package/dist/hdr-canvas.d.ts +4 -35
- package/dist/hdr-canvas.js +25 -20
- package/dist/hdr-canvas.js.map +1 -1
- package/dist/hdr-canvas.min.js +1 -1
- package/dist/hdr-canvas.min.js.map +1 -1
- package/dist/index.d.ts +57 -0
- package/package.json +23 -11
- package/src/Uint16Image.ts +17 -34
- package/src/hdr-canvas.ts +8 -7
- package/src/hdr-check.ts +13 -15
- package/src/index.ts +1 -5
- package/src/{@types → types}/HDRCanvas.d.ts +4 -5
package/dist/index.d.ts
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
import { ColorTypes } from 'colorjs.io';
|
2
|
+
|
3
|
+
// See https://github.com/microsoft/TypeScript/blob/main/src/lib/dom.generated.d.ts
|
4
|
+
/// <reference lib="dom" />
|
5
|
+
|
6
|
+
type HDRHTMLCanvasOptionsType = "mode";
|
7
|
+
type HDRHTMLCanvasOptions = { [key in HDRHTMLCanvasOptionsType]?: string };
|
8
|
+
|
9
|
+
interface HDRHTMLCanvasElement extends HTMLCanvasElement {
|
10
|
+
configureHighDynamicRange(options: HDRHTMLCanvasOptions): void;
|
11
|
+
_getContext(contextId: string, options?: object): RenderingContext | null;
|
12
|
+
}
|
13
|
+
|
14
|
+
interface HDRImageData {
|
15
|
+
readonly colorSpace: PredefinedColorSpace;
|
16
|
+
readonly data: Uint8ClampedArray | Uint16Array;
|
17
|
+
readonly height: number;
|
18
|
+
readonly width: number;
|
19
|
+
}
|
20
|
+
|
21
|
+
// See https://github.com/w3c/ColorWeb-CG/blob/main/hdr_html_canvas_element.md
|
22
|
+
// "rec2100-display-linear" is left out beacause of mapping issues
|
23
|
+
type HDRPredefinedColorSpace = "display-p3" | "srgb" | "rec2100-hlg" | "rec2100-pq";
|
24
|
+
|
25
|
+
type Uint16ImagePixelCallback = (red: number, green: number, blue: number, alpha: number) => Uint16Array;
|
26
|
+
declare class Uint16Image {
|
27
|
+
height: number;
|
28
|
+
width: number;
|
29
|
+
data: Uint16Array;
|
30
|
+
static DEFAULT_COLORSPACE: HDRPredefinedColorSpace;
|
31
|
+
static SDR_MULTIPLIER: number;
|
32
|
+
static COLORSPACES: Record<HDRPredefinedColorSpace, ColorTypes>;
|
33
|
+
colorSpace: HDRPredefinedColorSpace;
|
34
|
+
constructor(width: number, height: number, colorspace?: string);
|
35
|
+
fill(color: number[]): Uint16Image | undefined;
|
36
|
+
getPixel(w: number, h: number): Uint16Array;
|
37
|
+
setPixel(w: number, h: number, px: number[]): void;
|
38
|
+
static scaleUint8ToUint16(val: number): number;
|
39
|
+
getImageData(): ImageData | null;
|
40
|
+
static convertPixelToRec2100_hlg(pixel: Uint8ClampedArray): Uint16Array;
|
41
|
+
static convertArrayToRec2100_hlg(data: Uint8ClampedArray): Uint16Array;
|
42
|
+
pixelCallback(fn: Uint16ImagePixelCallback): void;
|
43
|
+
static loadSDRImageData(url: URL): Promise<HDRImageData | undefined>;
|
44
|
+
static fromImageData(imageData: HDRImageData): Uint16Image;
|
45
|
+
static fromURL(url: URL): Promise<Uint16Image | undefined>;
|
46
|
+
setImageData(imageData: HDRImageData): void;
|
47
|
+
clone(): Uint16Image;
|
48
|
+
}
|
49
|
+
|
50
|
+
declare function checkHDR(): boolean;
|
51
|
+
declare function checkHDRCanvas(): boolean;
|
52
|
+
|
53
|
+
declare function initHDRCanvas(canvas: HDRHTMLCanvasElement): RenderingContext | null;
|
54
|
+
declare function defaultGetContextHDR(): void;
|
55
|
+
declare function resetGetContext(): void;
|
56
|
+
|
57
|
+
export { Uint16Image, checkHDR, checkHDRCanvas, defaultGetContextHDR, initHDRCanvas, resetGetContext };
|
package/package.json
CHANGED
@@ -1,8 +1,17 @@
|
|
1
1
|
{
|
2
2
|
"name": "hdr-canvas",
|
3
|
-
"version": "0.0.
|
3
|
+
"version": "0.0.11",
|
4
4
|
"description": "HDR capable HTML canvas",
|
5
|
-
"main": "dist/hdr-canvas.
|
5
|
+
"main": "dist/hdr-canvas.cjs",
|
6
|
+
"module": "dist/hdr-canvas.js",
|
7
|
+
"type": "module",
|
8
|
+
"exports": {
|
9
|
+
".": {
|
10
|
+
"import": "./build/three.module.js",
|
11
|
+
"require": "./build/three.cjs"
|
12
|
+
},
|
13
|
+
"./three": "./three/*"
|
14
|
+
},
|
6
15
|
"files": [
|
7
16
|
"dist/hdr-canvas.d.ts",
|
8
17
|
"dist/hdr-canvas.js",
|
@@ -11,9 +20,12 @@
|
|
11
20
|
"dist/hdr-canvas.min.js.map",
|
12
21
|
"dist/hdr-canvas.cjs",
|
13
22
|
"dist/hdr-canvas.cjs.map",
|
23
|
+
"dist/index.d.ts",
|
24
|
+
"dist/@types",
|
14
25
|
"three",
|
15
26
|
"src"
|
16
27
|
],
|
28
|
+
"types": "dist/index.d.ts",
|
17
29
|
"scripts": {
|
18
30
|
"test": "echo \"Error: no test specified\" && exit 1",
|
19
31
|
"lint": "eslint . -c eslint.config.mjs --report-unused-disable-directives",
|
@@ -39,20 +51,20 @@
|
|
39
51
|
},
|
40
52
|
"homepage": "https://github.com/cmahnke/hdr-canvas#readme",
|
41
53
|
"devDependencies": {
|
42
|
-
"@eslint/js": "^9.
|
43
|
-
"@rollup/plugin-node-resolve": "^15.
|
54
|
+
"@eslint/js": "^9.15.0",
|
55
|
+
"@rollup/plugin-node-resolve": "^15.3.0",
|
44
56
|
"@rollup/plugin-terser": "^0.4.4",
|
45
|
-
"@rollup/plugin-typescript": "^
|
57
|
+
"@rollup/plugin-typescript": "^12.1.1",
|
46
58
|
"@types/eslint__js": "^8.42.3",
|
47
|
-
"eslint": "^9.
|
59
|
+
"eslint": "^9.15.0",
|
48
60
|
"prettier": "^3.3.3",
|
49
61
|
"rimraf": "^6.0.1",
|
50
|
-
"rollup": "^4.
|
62
|
+
"rollup": "^4.27.3",
|
51
63
|
"rollup-plugin-dts": "^6.1.1",
|
52
|
-
"three": "^0.
|
53
|
-
"tslib": "^2.
|
54
|
-
"typescript": "^5.
|
55
|
-
"typescript-eslint": "^8.
|
64
|
+
"three": "^0.170.0",
|
65
|
+
"tslib": "^2.8.1",
|
66
|
+
"typescript": "^5.6.3",
|
67
|
+
"typescript-eslint": "^8.15.0"
|
56
68
|
},
|
57
69
|
"dependencies": {
|
58
70
|
"colorjs.io": "^0.5.2"
|
package/src/Uint16Image.ts
CHANGED
@@ -1,12 +1,9 @@
|
|
1
1
|
import Color from "colorjs.io";
|
2
2
|
import type { Coords, ColorTypes } from "colorjs.io";
|
3
3
|
|
4
|
-
type
|
5
|
-
|
6
|
-
|
7
|
-
blue: number,
|
8
|
-
alpha: number,
|
9
|
-
) => Uint16Array;
|
4
|
+
import type { HDRPredefinedColorSpace, HDRImageData } from "./types/HDRCanvas.d.ts";
|
5
|
+
|
6
|
+
type Uint16ImagePixelCallback = (red: number, green: number, blue: number, alpha: number) => Uint16Array;
|
10
7
|
|
11
8
|
/*
|
12
9
|
interface ColorSpaceMapping {
|
@@ -24,7 +21,7 @@ export class Uint16Image {
|
|
24
21
|
"rec2100-hlg": "rec2100hlg",
|
25
22
|
"display-p3": "p3",
|
26
23
|
srgb: "sRGB",
|
27
|
-
"rec2100-pq": "rec2100pq"
|
24
|
+
"rec2100-pq": "rec2100pq"
|
28
25
|
};
|
29
26
|
colorSpace: HDRPredefinedColorSpace;
|
30
27
|
|
@@ -76,25 +73,20 @@ export class Uint16Image {
|
|
76
73
|
if (this.data === undefined || this.data === null) {
|
77
74
|
return null;
|
78
75
|
}
|
79
|
-
return new ImageData(
|
80
|
-
this.
|
81
|
-
|
82
|
-
this.height,
|
83
|
-
{ colorSpace: this.colorSpace as PredefinedColorSpace },
|
84
|
-
);
|
76
|
+
return new ImageData(this.data as unknown as Uint8ClampedArray, this.width, this.height, {
|
77
|
+
colorSpace: this.colorSpace as PredefinedColorSpace
|
78
|
+
});
|
85
79
|
}
|
86
80
|
|
87
81
|
static convertPixelToRec2100_hlg(pixel: Uint8ClampedArray): Uint16Array {
|
88
|
-
const colorJScolorSpace = <string>
|
89
|
-
Uint16Image.COLORSPACES["rec2100-hlg" as HDRPredefinedColorSpace]
|
90
|
-
);
|
82
|
+
const colorJScolorSpace = <string>Uint16Image.COLORSPACES["rec2100-hlg" as HDRPredefinedColorSpace];
|
91
83
|
|
92
84
|
const srgbColor = new Color(
|
93
85
|
"srgb",
|
94
86
|
Array.from(pixel.slice(0, 3)).map((band: number) => {
|
95
87
|
return band / 255;
|
96
88
|
}) as Coords,
|
97
|
-
pixel[3] / 255
|
89
|
+
pixel[3] / 255
|
98
90
|
);
|
99
91
|
const rec2100hlgColor = srgbColor.to(colorJScolorSpace);
|
100
92
|
const hlg: Array<number> = rec2100hlgColor.coords.map((band: number) => {
|
@@ -118,10 +110,7 @@ export class Uint16Image {
|
|
118
110
|
|
119
111
|
pixelCallback(fn: Uint16ImagePixelCallback) {
|
120
112
|
for (let i = 0; i < this.data.length; i += 4) {
|
121
|
-
this.data.set(
|
122
|
-
fn(this.data[i], this.data[i + 1], this.data[i + 2], this.data[i + 3]),
|
123
|
-
i,
|
124
|
-
);
|
113
|
+
this.data.set(fn(this.data[i], this.data[i + 1], this.data[i + 2], this.data[i + 3]), i);
|
125
114
|
}
|
126
115
|
}
|
127
116
|
|
@@ -146,9 +135,7 @@ export class Uint16Image {
|
|
146
135
|
static fromImageData(imageData: HDRImageData): Uint16Image {
|
147
136
|
const i = new Uint16Image(imageData.width, imageData.height);
|
148
137
|
if (imageData.colorSpace == "srgb") {
|
149
|
-
i.data = Uint16Image.convertArrayToRec2100_hlg(
|
150
|
-
<Uint8ClampedArray>imageData.data,
|
151
|
-
);
|
138
|
+
i.data = Uint16Image.convertArrayToRec2100_hlg(<Uint8ClampedArray>imageData.data);
|
152
139
|
} else if (imageData.colorSpace == Uint16Image.DEFAULT_COLORSPACE) {
|
153
140
|
i.data = <Uint16Array>imageData.data;
|
154
141
|
} else {
|
@@ -158,22 +145,18 @@ export class Uint16Image {
|
|
158
145
|
}
|
159
146
|
|
160
147
|
static async fromURL(url: URL): Promise<Uint16Image | undefined> {
|
161
|
-
return Uint16Image.loadSDRImageData(url).then(
|
162
|
-
(data
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
},
|
167
|
-
);
|
148
|
+
return Uint16Image.loadSDRImageData(url).then((data: HDRImageData | undefined) => {
|
149
|
+
if (data !== undefined) {
|
150
|
+
return Uint16Image.fromImageData(data);
|
151
|
+
}
|
152
|
+
});
|
168
153
|
}
|
169
154
|
|
170
155
|
setImageData(imageData: HDRImageData): void {
|
171
156
|
this.width = imageData.width;
|
172
157
|
this.height = imageData.height;
|
173
158
|
if (imageData.colorSpace == "srgb") {
|
174
|
-
this.data = Uint16Image.convertArrayToRec2100_hlg(
|
175
|
-
<Uint8ClampedArray>imageData.data,
|
176
|
-
);
|
159
|
+
this.data = Uint16Image.convertArrayToRec2100_hlg(<Uint8ClampedArray>imageData.data);
|
177
160
|
} else if (imageData.colorSpace == Uint16Image.DEFAULT_COLORSPACE) {
|
178
161
|
this.data = <Uint16Array>imageData.data;
|
179
162
|
} else {
|
package/src/hdr-canvas.ts
CHANGED
@@ -1,9 +1,11 @@
|
|
1
|
-
import {Uint16Image} from
|
1
|
+
import { Uint16Image } from "./Uint16Image";
|
2
2
|
|
3
|
-
|
3
|
+
import type { HDRHTMLCanvasElement } from "./types/HDRCanvas.d.ts";
|
4
4
|
|
5
|
-
|
6
|
-
|
5
|
+
const hdr_options = { colorSpace: Uint16Image.DEFAULT_COLORSPACE, pixelFormat: "float16" };
|
6
|
+
|
7
|
+
export function initHDRCanvas(canvas: HDRHTMLCanvasElement): RenderingContext | null {
|
8
|
+
canvas.configureHighDynamicRange({ mode: "extended" });
|
7
9
|
const ctx = canvas.getContext("2d", hdr_options);
|
8
10
|
return ctx;
|
9
11
|
}
|
@@ -11,15 +13,14 @@ export function initHDRCanvas(canvas : HDRHTMLCanvasElement) : RenderingContext
|
|
11
13
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
12
14
|
export function defaultGetContextHDR() {
|
13
15
|
(HTMLCanvasElement.prototype as HDRHTMLCanvasElement)._getContext = HTMLCanvasElement.prototype.getContext;
|
14
|
-
(HTMLCanvasElement.prototype as any).getContext = function(type: string, options: object) {
|
15
|
-
|
16
|
+
(HTMLCanvasElement.prototype as any).getContext = function (type: string, options: object) {
|
16
17
|
if (options !== undefined) {
|
17
18
|
options = Object.assign({}, options, hdr_options);
|
18
19
|
} else {
|
19
20
|
options = hdr_options;
|
20
21
|
}
|
21
22
|
return (this as HDRHTMLCanvasElement)._getContext(type, options);
|
22
|
-
}
|
23
|
+
};
|
23
24
|
}
|
24
25
|
|
25
26
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
package/src/hdr-check.ts
CHANGED
@@ -4,12 +4,8 @@ export function checkHDR(): boolean {
|
|
4
4
|
const hdrSupported: boolean = bitsPerChannel > 8;
|
5
5
|
|
6
6
|
//TODO: Test if this works as expected
|
7
|
-
const dynamicRangeHighMQ: boolean = window.matchMedia(
|
8
|
-
|
9
|
-
).matches;
|
10
|
-
const colorGamutMQ: boolean =
|
11
|
-
window.matchMedia("(color-gamut: rec2020)").matches ||
|
12
|
-
window.matchMedia("(color-gamut: p3)").matches;
|
7
|
+
const dynamicRangeHighMQ: boolean = window.matchMedia("(dynamic-range: high)").matches;
|
8
|
+
const colorGamutMQ: boolean = window.matchMedia("(color-gamut: rec2020)").matches || window.matchMedia("(color-gamut: p3)").matches;
|
13
9
|
if (colorGamutMQ && dynamicRangeHighMQ) {
|
14
10
|
if (bitsPerChannel !== Math.round(bitsPerChannel)) {
|
15
11
|
// iOS bug
|
@@ -37,22 +33,24 @@ export function checkHDRCanvas(): boolean {
|
|
37
33
|
if (!canvas.getContext) {
|
38
34
|
return false;
|
39
35
|
}
|
40
|
-
const ctx: CanvasRenderingContext2D | null = <CanvasRenderingContext2D>(
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
})
|
45
|
-
);
|
36
|
+
const ctx: CanvasRenderingContext2D | null = <CanvasRenderingContext2D>canvas.getContext("2d", {
|
37
|
+
colorSpace: colorSpace,
|
38
|
+
pixelFormat: "float16"
|
39
|
+
});
|
46
40
|
//canvas.drawingBufferColorSpace = colorSpace;
|
47
41
|
//canvas.unpackColorSpace = colorSpace;
|
48
42
|
if (ctx === null) {
|
49
43
|
return false;
|
50
44
|
}
|
51
45
|
return true;
|
46
|
+
/* eslint-disable no-console, @typescript-eslint/no-unused-vars */
|
52
47
|
} catch (e) {
|
53
|
-
|
54
|
-
console.error(
|
55
|
-
|
48
|
+
//console.error("Bad canvas ColorSpace test", e);
|
49
|
+
console.error(
|
50
|
+
"Bad canvas ColorSpace test - make sure that the Chromium browser flag 'enable-experimental-web-platform-features' has been enabled"
|
51
|
+
);
|
52
|
+
|
56
53
|
return false;
|
57
54
|
}
|
55
|
+
/* eslint-enable */
|
58
56
|
}
|
package/src/index.ts
CHANGED
@@ -1,7 +1,3 @@
|
|
1
1
|
export { Uint16Image } from "./Uint16Image";
|
2
2
|
export { checkHDR, checkHDRCanvas } from "./hdr-check";
|
3
|
-
export {
|
4
|
-
initHDRCanvas,
|
5
|
-
defaultGetContextHDR,
|
6
|
-
resetGetContext,
|
7
|
-
} from "./hdr-canvas";
|
3
|
+
export { initHDRCanvas, defaultGetContextHDR, resetGetContext } from "./hdr-canvas";
|
@@ -1,4 +1,5 @@
|
|
1
1
|
// See https://github.com/microsoft/TypeScript/blob/main/src/lib/dom.generated.d.ts
|
2
|
+
/// <reference lib="dom" />
|
2
3
|
|
3
4
|
type HDRHTMLCanvasOptionsType = "mode";
|
4
5
|
type HDRHTMLCanvasOptions = { [key in HDRHTMLCanvasOptionsType]?: string };
|
@@ -17,10 +18,8 @@ interface HDRImageData {
|
|
17
18
|
|
18
19
|
// See https://github.com/w3c/ColorWeb-CG/blob/main/hdr_html_canvas_element.md
|
19
20
|
// "rec2100-display-linear" is left out beacause of mapping issues
|
20
|
-
type HDRPredefinedColorSpace =
|
21
|
-
| "display-p3"
|
22
|
-
| "srgb"
|
23
|
-
| "rec2100-hlg"
|
24
|
-
| "rec2100-pq";
|
21
|
+
type HDRPredefinedColorSpace = "display-p3" | "srgb" | "rec2100-hlg" | "rec2100-pq";
|
25
22
|
|
26
23
|
//enum HDRPredefinedColorSpace {"display-p3", "srgb", "rec2100-hlg", "rec2100-pq", "rec2100-display-linear"};
|
24
|
+
|
25
|
+
export { HDRHTMLCanvasElement, HDRPredefinedColorSpace, HDRImageData };
|