Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/deep-lines-sort.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@imgproxy/imgproxy-js-core": minor
---

Add `color_profile` option support
30 changes: 30 additions & 0 deletions src/options/colorProfile.ts
Original file line number Diff line number Diff line change
@@ -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 };
1 change: 1 addition & 0 deletions src/options/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down
33 changes: 33 additions & 0 deletions src/types/colorProfile.ts
Original file line number Diff line number Diff line change
@@ -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 };
2 changes: 2 additions & 0 deletions src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -85,6 +86,7 @@ export type Options = AdjustOptionsPartial &
BlurOptionsPartial &
BrightnessOptionsPartial &
CacheBusterOptionsPartial &
ColorProfileOptionsPartial &
ColorizeOptionsPartial &
ContrastOptionsPartial &
CropOptionsPartial &
Expand Down
52 changes: 52 additions & 0 deletions tests/optionsBasic/colorProfile.test.ts
Original file line number Diff line number Diff line change
@@ -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"
);
});
});
});