image-color-grading 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,452 @@
1
+ # image-color-grading
2
+
3
+ 基于 WebGL 的高性能图像调色库,支持 22+ 种专业级调色参数,可用于图像编辑、滤镜应用等场景。
4
+
5
+ ## 特性
6
+
7
+ - 🚀 **高性能** - 基于 WebGL 的 GPU 加速渲染
8
+ - 🎨 **丰富的调色参数** - 支持 22+ 种专业调色参数
9
+ - 📦 **零依赖** - 无任何第三方依赖
10
+ - 🔧 **易于使用** - 简洁的 API 设计
11
+ - 📱 **跨平台** - 支持所有现代浏览器
12
+ - 💪 **TypeScript** - 完整的类型定义
13
+
14
+ ## 安装
15
+
16
+ ```bash
17
+ npm install image-color-grading
18
+ ```
19
+
20
+ ```bash
21
+ yarn add image-color-grading
22
+ ```
23
+
24
+ ```bash
25
+ pnpm add image-color-grading
26
+ ```
27
+
28
+ ## 快速开始
29
+
30
+ ```typescript
31
+ import { ImageColorGrading } from 'image-color-grading';
32
+
33
+ // 创建处理器实例
34
+ const processor = new ImageColorGrading();
35
+
36
+ // 加载图像
37
+ await processor.loadImage('path/to/image.jpg');
38
+
39
+ // 设置调色参数
40
+ processor.setSettings({
41
+ brightness: 20,
42
+ contrast: 10,
43
+ saturation: 15,
44
+ vibrance: 25,
45
+ });
46
+
47
+ // 导出为 Data URL
48
+ const dataUrl = processor.toDataURL();
49
+
50
+ // 或导出为 Blob
51
+ const blob = await processor.toBlob({ format: 'image/jpeg', quality: 0.9 });
52
+ ```
53
+
54
+ ## API 文档
55
+
56
+ ### ImageColorGrading
57
+
58
+ 主要的图像调色处理器类。
59
+
60
+ #### 构造函数
61
+
62
+ ```typescript
63
+ const processor = new ImageColorGrading(canvas?: HTMLCanvasElement);
64
+ ```
65
+
66
+ - `canvas` - 可选,自定义 canvas 元素。不传则自动创建。
67
+
68
+ #### 方法
69
+
70
+ ##### loadImage(url: string): Promise\<void\>
71
+
72
+ 从 URL 加载图像。
73
+
74
+ ```typescript
75
+ await processor.loadImage('https://example.com/image.jpg');
76
+ ```
77
+
78
+ ##### loadFromImage(image: HTMLImageElement): void
79
+
80
+ 从 HTMLImageElement 加载图像。
81
+
82
+ ```typescript
83
+ const img = document.querySelector('img');
84
+ processor.loadFromImage(img);
85
+ ```
86
+
87
+ ##### loadFromFile(file: File): Promise\<void\>
88
+
89
+ 从 File 对象加载图像(适用于文件上传)。
90
+
91
+ ```typescript
92
+ const input = document.querySelector('input[type="file"]');
93
+ input.addEventListener('change', async (e) => {
94
+ const file = e.target.files[0];
95
+ await processor.loadFromFile(file);
96
+ });
97
+ ```
98
+
99
+ ##### loadFromImageData(imageData: ImageData): void
100
+
101
+ 从 ImageData 加载图像。
102
+
103
+ ```typescript
104
+ const imageData = ctx.getImageData(0, 0, width, height);
105
+ processor.loadFromImageData(imageData);
106
+ ```
107
+
108
+ ##### setSettings(settings: PartialColorGradingSettings): void
109
+
110
+ 设置调色参数(支持部分更新)。
111
+
112
+ ```typescript
113
+ processor.setSettings({
114
+ brightness: 20,
115
+ contrast: 10,
116
+ });
117
+ ```
118
+
119
+ ##### getSettings(): ColorGradingSettings
120
+
121
+ 获取当前的调色设置。
122
+
123
+ ```typescript
124
+ const settings = processor.getSettings();
125
+ console.log(settings.brightness); // 20
126
+ ```
127
+
128
+ ##### resetSettings(): void
129
+
130
+ 重置所有设置为默认值。
131
+
132
+ ```typescript
133
+ processor.resetSettings();
134
+ ```
135
+
136
+ ##### render(): void
137
+
138
+ 手动触发渲染(通常在 setSettings 后自动调用)。
139
+
140
+ ```typescript
141
+ processor.render();
142
+ ```
143
+
144
+ ##### toDataURL(options?: ExportOptions): string
145
+
146
+ 导出为 Data URL 字符串。
147
+
148
+ ```typescript
149
+ // 导出为 PNG
150
+ const pngUrl = processor.toDataURL();
151
+
152
+ // 导出为 JPEG,质量 90%
153
+ const jpegUrl = processor.toDataURL({
154
+ format: 'image/jpeg',
155
+ quality: 0.9
156
+ });
157
+ ```
158
+
159
+ ##### toBlob(options?: ExportOptions): Promise\<Blob\>
160
+
161
+ 导出为 Blob 对象。
162
+
163
+ ```typescript
164
+ const blob = await processor.toBlob({
165
+ format: 'image/png'
166
+ });
167
+
168
+ // 下载文件
169
+ const url = URL.createObjectURL(blob);
170
+ const a = document.createElement('a');
171
+ a.href = url;
172
+ a.download = 'edited-image.png';
173
+ a.click();
174
+ ```
175
+
176
+ ##### getImageData(): ImageData
177
+
178
+ 获取处理后的 ImageData。
179
+
180
+ ```typescript
181
+ const imageData = processor.getImageData();
182
+ ```
183
+
184
+ ##### getCanvas(): HTMLCanvasElement
185
+
186
+ 获取 canvas 元素。
187
+
188
+ ```typescript
189
+ const canvas = processor.getCanvas();
190
+ document.body.appendChild(canvas);
191
+ ```
192
+
193
+ ##### getSize(): { width: number; height: number }
194
+
195
+ 获取图像尺寸。
196
+
197
+ ```typescript
198
+ const { width, height } = processor.getSize();
199
+ ```
200
+
201
+ ##### isLoaded(): boolean
202
+
203
+ 检查是否已加载图像。
204
+
205
+ ```typescript
206
+ if (processor.isLoaded()) {
207
+ processor.setSettings({ brightness: 10 });
208
+ }
209
+ ```
210
+
211
+ ##### dispose(): void
212
+
213
+ 销毁资源,释放 WebGL 上下文。
214
+
215
+ ```typescript
216
+ processor.dispose();
217
+ ```
218
+
219
+ ### 调色参数
220
+
221
+ 所有参数的默认值为 `0`。
222
+
223
+ | 参数 | 中文名 | 范围 | 说明 |
224
+ |------|--------|------|------|
225
+ | `vibrance` | 自然饱和度 | -100 ~ 100 | 智能增强/降低饱和度,保护肤色 |
226
+ | `saturation` | 饱和度 | -100 ~ 100 | 整体色彩饱和度调整 |
227
+ | `temperature` | 色温 | -100 ~ 100 | 冷暖色调调整 |
228
+ | `tint` | 色调 | -100 ~ 100 | 绿/品红色调偏移 |
229
+ | `hue` | 色相 | -100 ~ 100 | 色相旋转 |
230
+ | `brightness` | 亮度 | -100 ~ 100 | 整体亮度调整 |
231
+ | `exposure` | 曝光度 | -100 ~ 100 | 模拟相机曝光调整 |
232
+ | `contrast` | 对比度 | -100 ~ 100 | 明暗对比调整 |
233
+ | `blacks` | 黑色 | -100 ~ 100 | 暗部色阶调整 |
234
+ | `whites` | 白色 | -100 ~ 100 | 亮部色阶调整 |
235
+ | `highlights` | 高光 | -100 ~ 100 | 高光区域亮度调整 |
236
+ | `shadows` | 暗调 | -100 ~ 100 | 阴影区域亮度调整 |
237
+ | `dehaze` | 除雾化 | 0 ~ 100 | 去除雾霾效果 |
238
+ | `bloom` | 泛光 | 0 ~ 100 | 高光溢出效果 |
239
+ | `glamour` | 氛围美化 | 0 ~ 100 | 柔光美化效果 |
240
+ | `clarity` | 清晰度 | -100 ~ 100 | 局部对比度增强 |
241
+ | `sharpen` | 锐化 | 0 ~ 100 | 边缘锐化 |
242
+ | `smooth` | 平滑 | 0 ~ 100 | 平滑降噪 |
243
+ | `blur` | 模糊 | 0 ~ 100 | 高斯模糊 |
244
+ | `vignette` | 暗角 | -100 ~ 100 | 边缘暗角效果 |
245
+ | `grain` | 颗粒 | 0 ~ 100 | 胶片颗粒效果 |
246
+
247
+ ### 类型定义
248
+
249
+ ```typescript
250
+ // 完整的调色设置
251
+ interface ColorGradingSettings {
252
+ vibrance: number;
253
+ saturation: number;
254
+ temperature: number;
255
+ tint: number;
256
+ hue: number;
257
+ brightness: number;
258
+ exposure: number;
259
+ contrast: number;
260
+ blacks: number;
261
+ whites: number;
262
+ highlights: number;
263
+ shadows: number;
264
+ dehaze: number;
265
+ bloom: number;
266
+ glamour: number;
267
+ clarity: number;
268
+ sharpen: number;
269
+ smooth: number;
270
+ blur: number;
271
+ vignette: number;
272
+ grain: number;
273
+ }
274
+
275
+ // 部分设置(用于 setSettings)
276
+ type PartialColorGradingSettings = Partial<ColorGradingSettings>;
277
+
278
+ // 导出选项
279
+ interface ExportOptions {
280
+ format?: 'image/png' | 'image/jpeg' | 'image/webp';
281
+ quality?: number; // 0-1, 仅对 jpeg/webp 有效
282
+ }
283
+ ```
284
+
285
+ ## 示例
286
+
287
+ ### 在 React 中使用
288
+
289
+ ```tsx
290
+ import { useEffect, useRef, useState } from 'react';
291
+ import { ImageColorGrading, ColorGradingSettings } from 'image-color-grading';
292
+
293
+ function ImageEditor() {
294
+ const containerRef = useRef<HTMLDivElement>(null);
295
+ const processorRef = useRef<ImageColorGrading | null>(null);
296
+ const [settings, setSettings] = useState<Partial<ColorGradingSettings>>({});
297
+
298
+ useEffect(() => {
299
+ const processor = new ImageColorGrading();
300
+ processorRef.current = processor;
301
+
302
+ // 将 canvas 添加到 DOM
303
+ if (containerRef.current) {
304
+ containerRef.current.appendChild(processor.getCanvas());
305
+ }
306
+
307
+ // 加载图像
308
+ processor.loadImage('/sample.jpg');
309
+
310
+ return () => {
311
+ processor.dispose();
312
+ };
313
+ }, []);
314
+
315
+ useEffect(() => {
316
+ processorRef.current?.setSettings(settings);
317
+ }, [settings]);
318
+
319
+ return (
320
+ <div>
321
+ <div ref={containerRef} />
322
+ <input
323
+ type="range"
324
+ min="-100"
325
+ max="100"
326
+ value={settings.brightness ?? 0}
327
+ onChange={(e) => setSettings({ ...settings, brightness: Number(e.target.value) })}
328
+ />
329
+ </div>
330
+ );
331
+ }
332
+ ```
333
+
334
+ ### 在 Vue 中使用
335
+
336
+ ```vue
337
+ <template>
338
+ <div>
339
+ <div ref="container"></div>
340
+ <input
341
+ type="range"
342
+ :min="-100"
343
+ :max="100"
344
+ v-model.number="brightness"
345
+ @input="updateSettings"
346
+ />
347
+ </div>
348
+ </template>
349
+
350
+ <script setup>
351
+ import { ref, onMounted, onUnmounted } from 'vue';
352
+ import { ImageColorGrading } from 'image-color-grading';
353
+
354
+ const container = ref(null);
355
+ const brightness = ref(0);
356
+ let processor = null;
357
+
358
+ onMounted(async () => {
359
+ processor = new ImageColorGrading();
360
+ container.value.appendChild(processor.getCanvas());
361
+ await processor.loadImage('/sample.jpg');
362
+ });
363
+
364
+ onUnmounted(() => {
365
+ processor?.dispose();
366
+ });
367
+
368
+ function updateSettings() {
369
+ processor?.setSettings({ brightness: brightness.value });
370
+ }
371
+ </script>
372
+ ```
373
+
374
+ ### 批量处理图像
375
+
376
+ ```typescript
377
+ import { ImageColorGrading } from 'image-color-grading';
378
+
379
+ async function batchProcess(imageUrls: string[], settings: Partial<ColorGradingSettings>) {
380
+ const processor = new ImageColorGrading();
381
+ const results: Blob[] = [];
382
+
383
+ for (const url of imageUrls) {
384
+ await processor.loadImage(url);
385
+ processor.setSettings(settings);
386
+ const blob = await processor.toBlob({ format: 'image/jpeg', quality: 0.85 });
387
+ results.push(blob);
388
+ }
389
+
390
+ processor.dispose();
391
+ return results;
392
+ }
393
+ ```
394
+
395
+ ### 创建预设滤镜
396
+
397
+ ```typescript
398
+ import { ImageColorGrading, PartialColorGradingSettings } from 'image-color-grading';
399
+
400
+ // 定义预设滤镜
401
+ const presets: Record<string, PartialColorGradingSettings> = {
402
+ vintage: {
403
+ saturation: -20,
404
+ contrast: 10,
405
+ temperature: 15,
406
+ grain: 30,
407
+ vignette: 25,
408
+ },
409
+ blackAndWhite: {
410
+ saturation: -100,
411
+ contrast: 20,
412
+ },
413
+ vivid: {
414
+ vibrance: 40,
415
+ saturation: 20,
416
+ contrast: 15,
417
+ clarity: 20,
418
+ },
419
+ cinematic: {
420
+ contrast: 25,
421
+ highlights: -20,
422
+ shadows: 15,
423
+ temperature: -10,
424
+ vignette: 30,
425
+ },
426
+ };
427
+
428
+ // 应用预设
429
+ function applyPreset(processor: ImageColorGrading, presetName: string) {
430
+ processor.resetSettings();
431
+ processor.setSettings(presets[presetName]);
432
+ }
433
+ ```
434
+
435
+ ## 浏览器兼容性
436
+
437
+ | 浏览器 | 最低版本 |
438
+ |--------|----------|
439
+ | Chrome | 56+ |
440
+ | Firefox | 51+ |
441
+ | Safari | 15+ |
442
+ | Edge | 79+ |
443
+
444
+ ## 注意事项
445
+
446
+ 1. **跨域图像** - 加载跨域图像时,服务器需要设置正确的 CORS 头
447
+ 2. **内存管理** - 处理完成后调用 `dispose()` 释放 WebGL 资源
448
+ 3. **图像尺寸** - 超大图像可能会影响性能,建议在客户端进行适当的缩放
449
+
450
+ ## License
451
+
452
+ MIT
@@ -0,0 +1,23 @@
1
+ /**
2
+ * @module image-color-grading
3
+ *
4
+ * 基于 WebGL 的高性能图像调色库
5
+ *
6
+ * @example
7
+ * ```ts
8
+ * import { ImageColorGrading, defaultSettings } from 'image-color-grading';
9
+ *
10
+ * const processor = new ImageColorGrading();
11
+ * await processor.loadImage('path/to/image.jpg');
12
+ * processor.setSettings({
13
+ * brightness: 20,
14
+ * contrast: 10,
15
+ * saturation: 15
16
+ * });
17
+ *
18
+ * const dataUrl = processor.toDataURL();
19
+ * ```
20
+ */
21
+ export { ImageColorGrading, defaultSettings } from './processor';
22
+ export type { ColorGradingSettings, PartialColorGradingSettings, ExportOptions, } from './types';
23
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACjE,YAAY,EACV,oBAAoB,EACpB,2BAA2B,EAC3B,aAAa,GACd,MAAM,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,22 @@
1
+ /**
2
+ * @module image-color-grading
3
+ *
4
+ * 基于 WebGL 的高性能图像调色库
5
+ *
6
+ * @example
7
+ * ```ts
8
+ * import { ImageColorGrading, defaultSettings } from 'image-color-grading';
9
+ *
10
+ * const processor = new ImageColorGrading();
11
+ * await processor.loadImage('path/to/image.jpg');
12
+ * processor.setSettings({
13
+ * brightness: 20,
14
+ * contrast: 10,
15
+ * saturation: 15
16
+ * });
17
+ *
18
+ * const dataUrl = processor.toDataURL();
19
+ * ```
20
+ */
21
+ export { ImageColorGrading, defaultSettings } from './processor';
22
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,109 @@
1
+ import type { ColorGradingSettings, PartialColorGradingSettings, ExportOptions } from './types';
2
+ /**
3
+ * 默认设置
4
+ */
5
+ export declare const defaultSettings: ColorGradingSettings;
6
+ /**
7
+ * 图像调色处理器
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * const processor = new ImageColorGrading();
12
+ * await processor.loadImage('path/to/image.jpg');
13
+ * processor.setSettings({ brightness: 20, contrast: 10 });
14
+ * processor.render();
15
+ * const dataUrl = processor.toDataURL();
16
+ * ```
17
+ */
18
+ export declare class ImageColorGrading {
19
+ private canvas;
20
+ private resources;
21
+ private settings;
22
+ private imageLoaded;
23
+ /**
24
+ * 创建图像调色处理器
25
+ * @param canvas - 可选的 canvas 元素,不传则自动创建
26
+ */
27
+ constructor(canvas?: HTMLCanvasElement);
28
+ /**
29
+ * 获取 canvas 元素
30
+ */
31
+ getCanvas(): HTMLCanvasElement;
32
+ /**
33
+ * 获取当前设置
34
+ */
35
+ getSettings(): ColorGradingSettings;
36
+ /**
37
+ * 设置调色参数
38
+ * @param newSettings - 部分或全部设置参数
39
+ */
40
+ setSettings(newSettings: PartialColorGradingSettings): void;
41
+ /**
42
+ * 重置所有设置为默认值
43
+ */
44
+ resetSettings(): void;
45
+ /**
46
+ * 从 URL 加载图像
47
+ * @param url - 图像 URL
48
+ * @returns Promise
49
+ */
50
+ loadImage(url: string): Promise<void>;
51
+ /**
52
+ * 从 HTMLImageElement 加载图像
53
+ * @param image - 图像元素
54
+ */
55
+ loadFromImage(image: HTMLImageElement): void;
56
+ /**
57
+ * 从 File 对象加载图像
58
+ * @param file - File 对象
59
+ * @returns Promise
60
+ */
61
+ loadFromFile(file: File): Promise<void>;
62
+ /**
63
+ * 从 ImageData 加载图像
64
+ * @param imageData - ImageData 对象
65
+ */
66
+ loadFromImageData(imageData: ImageData): void;
67
+ /**
68
+ * 渲染图像
69
+ */
70
+ render(): void;
71
+ /**
72
+ * 导出为 Data URL
73
+ * @param options - 导出选项
74
+ * @returns Data URL 字符串
75
+ */
76
+ toDataURL(options?: ExportOptions): string;
77
+ /**
78
+ * 导出为 Blob
79
+ * @param options - 导出选项
80
+ * @returns Promise<Blob>
81
+ */
82
+ toBlob(options?: ExportOptions): Promise<Blob>;
83
+ /**
84
+ * 获取 ImageData
85
+ * @returns ImageData
86
+ */
87
+ getImageData(): ImageData;
88
+ /**
89
+ * 获取图像尺寸
90
+ */
91
+ getSize(): {
92
+ width: number;
93
+ height: number;
94
+ };
95
+ /**
96
+ * 检查是否已加载图像
97
+ */
98
+ isLoaded(): boolean;
99
+ /**
100
+ * 销毁资源
101
+ */
102
+ dispose(): void;
103
+ private getWebGLContext;
104
+ private initFromImage;
105
+ private initResources;
106
+ private disposeResources;
107
+ private drawFrame;
108
+ }
109
+ //# sourceMappingURL=processor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"processor.d.ts","sourceRoot":"","sources":["../src/processor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,oBAAoB,EACpB,2BAA2B,EAI3B,aAAa,EACd,MAAM,SAAS,CAAC;AAYjB;;GAEG;AACH,eAAO,MAAM,eAAe,EAAE,oBAsB7B,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,SAAS,CAA+B;IAChD,OAAO,CAAC,QAAQ,CAAgD;IAChE,OAAO,CAAC,WAAW,CAAS;IAE5B;;;OAGG;gBACS,MAAM,CAAC,EAAE,iBAAiB;IAItC;;OAEG;IACH,SAAS,IAAI,iBAAiB;IAI9B;;OAEG;IACH,WAAW,IAAI,oBAAoB;IAInC;;;OAGG;IACH,WAAW,CAAC,WAAW,EAAE,2BAA2B,GAAG,IAAI;IAO3D;;OAEG;IACH,aAAa,IAAI,IAAI;IAOrB;;;;OAIG;IACH,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAerC;;;OAGG;IACH,aAAa,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI;IAI5C;;;;OAIG;IACH,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAevC;;;OAGG;IACH,iBAAiB,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI;IAoC7C;;OAEG;IACH,MAAM,IAAI,IAAI;IAQd;;;;OAIG;IACH,SAAS,CAAC,OAAO,CAAC,EAAE,aAAa,GAAG,MAAM;IAM1C;;;;OAIG;IACH,MAAM,CAAC,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAkB9C;;;OAGG;IACH,YAAY,IAAI,SAAS;IAiBzB;;OAEG;IACH,OAAO,IAAI;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE;IAO5C;;OAEG;IACH,QAAQ,IAAI,OAAO;IAInB;;OAEG;IACH,OAAO,IAAI,IAAI;IAOf,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,aAAa;IAmCrB,OAAO,CAAC,aAAa;IA4ErB,OAAO,CAAC,gBAAgB;IAmBxB,OAAO,CAAC,SAAS;CAuUlB"}