From 5492e7192a85fbc70421d3cc93db601f982fe475 Mon Sep 17 00:00:00 2001 From: Ivan Buryak Date: Wed, 3 Sep 2025 09:32:05 +0500 Subject: [PATCH 1/2] Add color_profile option --- src/options/colorProfile.ts | 30 ++++++++++++++ src/options/index.ts | 1 + src/types/colorProfile.ts | 33 ++++++++++++++++ src/types/index.ts | 2 + tests/optionsBasic/colorProfile.test.ts | 52 +++++++++++++++++++++++++ 5 files changed, 118 insertions(+) create mode 100644 src/options/colorProfile.ts create mode 100644 src/types/colorProfile.ts create mode 100644 tests/optionsBasic/colorProfile.test.ts diff --git a/src/options/colorProfile.ts b/src/options/colorProfile.ts new file mode 100644 index 00000000..5d98e1e1 --- /dev/null +++ b/src/options/colorProfile.ts @@ -0,0 +1,30 @@ +import type { + ColorProfile, + ColorProfileOptionsPartial, +} from "../types/colorProfile"; +import { guardIsUndef } from "../utils"; + +const getOpt = ( + options: ColorProfileOptionsPartial +): ColorProfile | undefined => { + if ("color_profile" in options) { + return options.color_profile; + } else if ("cp" in options) { + return options.cp; + } else if ("icc" in options) { + return options.icc; + } + + return undefined; +}; + +const test = (options: ColorProfileOptionsPartial): boolean => + getOpt(options) !== undefined; + +const build = (options: ColorProfileOptionsPartial): string => { + const colorProfileOpts = getOpt(options); + guardIsUndef(colorProfileOpts, "color_profile"); + return `cp:${colorProfileOpts}`; +}; + +export { test, build }; diff --git a/src/options/index.ts b/src/options/index.ts index d19be2b0..08a16a31 100644 --- a/src/options/index.ts +++ b/src/options/index.ts @@ -7,6 +7,7 @@ export * as blur from "./blur"; export * as blurDetections from "./blurDetections"; export * as brightness from "./brightness"; export * as cacheBuster from "../optionsShared/cacheBuster"; +export * as colorProfile from "./colorProfile"; export * as colorize from "./colorize"; export * as contrast from "./contrast"; export * as crop from "../optionsShared/crop"; diff --git a/src/types/colorProfile.ts b/src/types/colorProfile.ts new file mode 100644 index 00000000..c409a2c0 --- /dev/null +++ b/src/types/colorProfile.ts @@ -0,0 +1,33 @@ +/** + * *Color Profile option* + * + * When set, imgproxy will convert the image's colorspace to the specified color profile + * and embed the selected color profile in the output image. + * + * @note This is a Pro feature. + * @note Ignored if the output format doesn't support color profiles. + * @note Embedded profiles are not stripped by the standard color profile removal options. + * + * Available profiles: + * - `srgb`: Built-in compact sRGB profile + * - `cmyk`: Built-in "Chemical proof" CMYK profile + * - Custom color profile filename (located in IMGPROXY_COLOR_PROFILES_DIR) + * + * @see {@link https://docs.imgproxy.net/generating_the_url?id=color-profile | color profile option imgproxy docs} + */ +type ColorProfile = string; + +/** + * *Color Profile option* + * + * To describe the Color Profile option, you can use the keywords `color_profile`, `cp`, or `icc`. + * + * @see https://docs.imgproxy.net/generating_the_url?id=color-profile + */ +interface ColorProfileOptionsPartial { + color_profile?: ColorProfile; + cp?: ColorProfile; + icc?: ColorProfile; +} + +export { ColorProfile, ColorProfileOptionsPartial }; diff --git a/src/types/index.ts b/src/types/index.ts index 16b263fb..a4452369 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -7,6 +7,7 @@ import type { BlurDetectionsOptionsPartial } from "./blurDetections"; import type { BlurOptionsPartial } from "./blur"; import type { BrightnessOptionsPartial } from "./brightness"; import type { CacheBusterOptionsPartial } from "../typesShared/cacheBuster"; +import type { ColorProfileOptionsPartial } from "./colorProfile"; import type { ColorizeOptionsPartial } from "./colorize"; import type { ContrastOptionsPartial } from "./contrast"; import type { CropOptionsPartial } from "../typesShared/crop"; @@ -85,6 +86,7 @@ export type Options = AdjustOptionsPartial & BlurOptionsPartial & BrightnessOptionsPartial & CacheBusterOptionsPartial & + ColorProfileOptionsPartial & ColorizeOptionsPartial & ContrastOptionsPartial & CropOptionsPartial & diff --git a/tests/optionsBasic/colorProfile.test.ts b/tests/optionsBasic/colorProfile.test.ts new file mode 100644 index 00000000..319e13cc --- /dev/null +++ b/tests/optionsBasic/colorProfile.test.ts @@ -0,0 +1,52 @@ +import { describe, expect, it } from "vitest"; +import { test, build } from "../../src/options/colorProfile"; + +describe("colorProfile", () => { + describe("test", () => { + it("should return true if color_profile option is defined", () => { + expect(test({ color_profile: "srgb" })).toEqual(true); + }); + + it("should return true if cp option is defined", () => { + expect(test({ cp: "cmyk" })).toEqual(true); + }); + + it("should return true if icc option is defined", () => { + expect(test({ icc: "custom_profile" })).toEqual(true); + }); + + it("should return false if color_profile option is undefined", () => { + expect(test({})).toEqual(false); + }); + }); + + describe("build", () => { + it("should throw an error if color_profile option is undefined", () => { + expect(() => build({})).toThrow("color_profile option is undefined"); + }); + + it("should return 'cp:srgb' if color_profile option is 'srgb'", () => { + expect(build({ color_profile: "srgb" })).toEqual("cp:srgb"); + }); + + it("should return 'cp:cmyk' if cp option is 'cmyk'", () => { + expect(build({ cp: "cmyk" })).toEqual("cp:cmyk"); + }); + + it("should return 'cp:custom_profile' if icc option is 'custom_profile'", () => { + expect(build({ icc: "custom_profile" })).toEqual("cp:custom_profile"); + }); + + it("should handle custom profile filename", () => { + expect(build({ color_profile: "my-custom-profile" })).toEqual( + "cp:my-custom-profile" + ); + }); + + it("should handle percent-encoded filename", () => { + expect(build({ cp: "profile%20with%20spaces" })).toEqual( + "cp:profile%20with%20spaces" + ); + }); + }); +}); From 4d06f474519d4d60d51ab198a6c0a1ed5ff8535e Mon Sep 17 00:00:00 2001 From: Ivan Buryak Date: Wed, 3 Sep 2025 09:32:49 +0500 Subject: [PATCH 2/2] Add changesets --- .changeset/deep-lines-sort.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/deep-lines-sort.md diff --git a/.changeset/deep-lines-sort.md b/.changeset/deep-lines-sort.md new file mode 100644 index 00000000..8495ec4a --- /dev/null +++ b/.changeset/deep-lines-sort.md @@ -0,0 +1,5 @@ +--- +"@imgproxy/imgproxy-js-core": minor +--- + +Add `color_profile` option support