Edit in GitHubLog an issue

Imaging API Beta

The Imaging API Beta allows JavaScript to work directly with image data in Photoshop documents.

These APIs are currently beta which means that they are not complete and may change in the future. We present them here as a testing ground for this new capability. Please send comments, questions or bugs via the Beta Feedback panel (under the Windows menu) or directly at the Beta forum.

The functionality has the following known issues:

  • The API is only available in Photoshop (Beta) builds
  • Support is limited to RGB, gray scale, and Lab data
  • When using applyAlpha to matte the retrieved region's pixels on white, those pixels will still have had the empty pixels at the edges trimmed before the matte is applied. Be sure to check the returned sourceBounds.

The Imaging API are exposed on the imaging_beta sub-module under "photoshop". You can access these APIs by using the follow code:

Copied to your clipboard
const imaging = require("photoshop").imaging_beta;

Terminology and data types

Image data is expressed as a collection of pixels. A pixel represents all color information for a single point in the image. A pixel consists of one or more components of color values and alpha information.

An RGB pixel with alpha information has four components: "red", "green", "blue", and "alpha". An opaque RGB pixel has only three components. Including an alpha channel as a fourth yields RGBA. An opaque gray scale pixel has one component. A gray scale pixel with alpha has two components.

In order to properly interpret pixel data, Photoshop needs to know which color profile the data is expressed in. An example of a color profile is "Adobe RGB (1998)". All image data here will include the associated profile, and Photoshop will perform color conversions when needed. You can get the list of available color profiles by invoking [[Photoshop.getColorProfiles]] on the app object:

Copied to your clipboard
1const rgbProfiles = await require("photoshop").app.getColorProfiles("RGB");
2
3const grayProfiles = await require("photoshop").app.getColorProfiles("Gray");

When working with 32 bit images, Photoshop will return color profile names that include the description 'Linear Profile'. An example is "(Linear RGB Profile)". This text should not be included when specifying a profile. If a document profile is listed as Adobe RGB (1998) (Linear RGB Profile), then you would use the string Adobe RGB (1998) when specifying a profile with a method such as createImageDataFromBuffer.

Photoshop supports two ways to store pixel information in memory:

  • chunky: Components of a single pixels are stored consecutively in memory. If you have two opaque RGB pixels (pixel 1 and pixel 2), then they will be stored as: [R1, G1, B1, R2, G2, B2].
  • planar: Similar components are stored consecutively in memory. Components for a single pixel may not appear consecutively in memory. If you have two opaque RGB pixels, then they will be stored as: [R1, R2, G1, G2, B1, B2].

JavaScript APIs use the chunky format by default.

Image data is represented by a PhotoshopImageData instance. This instance has the following methods and properties:

PhotoshopImageData

NameType描述
widthNumberThe width of the image data in pixels.
heightNumberThe height of the image data in pixels.
colorSpaceStringThe color space (or mode) for the image data. This can be "RGB", "Grayscale", "Lab".
colorProfileStringThe color profile for the image data. For example, "sRGB IEC61966-2.1".
hasAlphaBooleanTrue if the image data includes an alpha channel. Only available with RGB.
componentsNumberNumber of components per pixel. This is 3 for RGB, 4 for RGBA and so forth.
componentSizeNumberNumber of bits per component. This can be 8, 16, or 32.
pixelFormatStringMemory layout (order) of components in a pixel. Could be "RGB", "RGBA", "Gray", or "LAB".
chunkyBooleanTrue if the image data internally is using the chunky format.
typeStringType of contained data. At the moment only "image/uncompressed" is supported.
getDataMethodSee documentation below.
disposeMethodSee documentation below.

When specifying bounds in the Imaging API, the resulting region will include the left and top locations up to the right and bottom locations. As an example: {left: 0, top: 0, right: 10, bottom: 10} will target ten pixels from location 0 to 9 in both directions (not including pixels from location 10). You can specify height and width instead of right and bottom - doing so can make the code easier to read: {left: 0, top: 0, width: 10, height: 10}.

The value range for pixel components depend on the componentSize.

Component SizeValue rangeComments
80..255
160..32768
320..1+High dynamic range images may have component values that are below 0 or above 1.0

Instances of PhotoshopImageData cannot be created explicitly by JavaScript, but are returned from Imaging API methods.


Performance considerations

Photoshop images can be (very) large. It is therefore important to manage the image data carefully in JavaScript. If you use a large amount of JavaScript memory, then you may see warnings in the UDT debugger console such as the following:

Copied to your clipboard
1Plugin memory usage increased to: 600MB.
2Plugin exceeds memory limit. Currently used memory 600.

The potential large data space has a number of implications.

First off, all Imaging API methods that return pixels are asynchronous. This is needed because modifying and even querying pixel data may incur disk I/O.

When requesting pixels, use the smallest possible target size. Specifying a small target size allows Photoshop to optimize the retrieval (and possibly document compositing) of the source region.

When you are done working with image data, then you should call dispose on the PhotoshopImageData instance. This allow Photoshop to release memory immediately rather than waiting for garbage collection.

Converting image data between different color spaces or color profiles is somewhat time consuming. Whenever possible, work with a color space and color profile that match the document that you are operating on.


APIs

PhotoshopImageData

getData

Return pixel information from an PhotoshopImageData instance as a typed array. The return type depends on the componentSize of the image.

Component SizeReturn type
8Uint8Array
16Uint16Array
32Float32Array

The method takes an options argument. This argument can be used to specify attributes of the returned data. Possible options include:

  • chunky | Boolean - Optional. If true then the data is returned as chunky data. If false, then data is returned in the planar format. The default value is true.

Return value: Promise<Uint8Array | Uint16Array | FloatArray>

The method is asynchronous, and thus returns a promise with the described data type.

Example:

Copied to your clipboard
const pixelData = await imageObj.imageData.getData()

dispose

Calling this synchronous method will release the contained image data. Doing so will reduce memory usage faster then waiting for the JavaScript garbage collector to run.

Copied to your clipboard
pixelData.dispose();

getPixels

This API allows JavaScript to obtain pixel data from a Photoshop document. You can request pixels from an individual layer, or from the full document composite.

Copied to your clipboard
const imageObj = await imaging.getPixels(options);
  • options | Object - Required Options describing the operation.
    • documentID | Number - Optional. The id of the source document. If missing, or negative, then the source is the active document.
    • layerID | Number - Optional. The id of the source layer. If the value is not provided then the API returns pixels from the composite document image.
    • sourceBounds | Object - Optional. The region whose pixels should be returned. If the value is not provided, then pixels from the entire layer or document are is returned. The provided bounds will be trimmed to only that region that contains pixel data. In this event, the returned sourceBounds will reflect this smaller region. The provided object must describe a rectangle using one the following number-value property sets:
      • left, top, right, and bottom
      • left, top, width, and height
    • targetSize | Object - Optional. The dimensions of the returned image. If this value is not provided then the returned size will match the requested size. That is, no scaling will be performed on the returned pixels. The provided object must have one or more of the following attributes:
      • width and height. If only one dimension is included, then the returned image data is scaled proportionally to match the requested dimension.
    • colorSpace | String - Optional. Requested color space of the returned pixels. If omitted, then the color space of the source document is used to convert colors.
    • colorProfile | String - Optional. The name of a color profile to apply to the returned pixels. If omitted, then the resulting color profile depends on the requested color space:
      • If the requested color space matches the source document, then the returned data will use the color profile of the source document.
      • If the requested color space is different from the source document, then the working color profile for that color space is used to convert colors.
    • componentSize | Number - Optional. The requested componentSize of the returned image data. If this property is omitted then the componentSize of the source pixel data is used. The value can be: -1 (for using the source document's depth), 8 , 16, or 32.
    • applyAlpha | Boolean - Optional. If true, then RGBA pixels will be converted to RGB by matting on white.
    • a possible alpha channel is applied to the pixels before returning. The returned imageData property will not contain an alpha channel.

Return value: Promise<Object>

The returned object has the following properties:

  • imageData | PhotoshopImageData. A PhotoshopImageData instance describing the returned pixel data.
  • sourceBounds | Object. The actual bounds used when obtaining pixels (see note regarding pyramid levels below).
  • level | Number. The pyramid level that was used when obtaining pixels.

Note: the components property of the image data depends on whether or not the pixel source includes an alpha channel, e.g., 4 for RGBA.

If the targetSize is smaller than the requested region, then the resulting image data will be scaled down. When scaling, Photoshop may use a smaller (cached) version of the image canvas. This is known as a pyramid level. The number of pyramid levels that are available in a document is determined by the preference: "Performance Cache Levels". Using a cache level may result in dramatic performance improvements. The returned level indicates which level that was used. Level 0 indicates the full resolution canvas. Level 1 indicates a cache that is half of the size of the full resolution, and so forth. The returned sourceBounds are relative to the bounds of the source cache level (not relative to the full resolution bounds).

The valid bounds for the sourceBounds depend on the pixel source. The origin of the composite image is (0, 0),and the size is given by the properties width and height on the DOM object for the source document. The origin of a pixel layer can be different from (0, 0). You can get the valid pixel bounds for a layer by calling boundsNoEffects on the DOM object corresponding to the source layer.

Example - create a thumbnail of an region of the target document that is 100 pixels tall.

Copied to your clipboard
1const thumbnail = await imaging.getPixels({
2 sourceBounds: { left: 0, top: 0, right: 300, bottom: 300 },
3 targetSize: { height: 100 }
4});

putPixels

This API allows JavaScript to change pixel data in a layer. You can replace all pixels in a layer or a region of the layer.

Copied to your clipboard
await imaging.putPixels(options);
  • options | Object - Required Options describing the operation.
    • documentID | Number - Optional. The id of the source document. If missing, or negative, then the source is the active document.
    • layerID | Number - Required. The id of the target layer. The target layer must be a pixel layer.
    • imageData | PhotoshopImageData - Required. Value describing the pixel data.
    • replace | Boolean - Optional. Describes how pixels are added to the layer. If true, then exising pixels in the layer are discarded before adding new pixels. If false, then the new pixels are added to the existing pixel content in the layer. The default value is true.
    • targetBounds | Object - Optional. The region where the pixels should be inserted. If the value is not provided, then pixels are inserted at the origin (0, 0) of the document. The provided object must include the following values: left, top. (Dimension keys width and height are not used.)
    • commandName | String - Optional. If provided then this name is used when creating an entry in the history panel.

Example:

Copied to your clipboard
1await imaging.putPixels({
2 layerID: 123
3 imageData: imageData
4});

getLayerMask

This API allows JavaScript to retrieve the pixel data representing a layer's mask.

Copied to your clipboard
const imageObj = await imaging.getLayerMask(options);
  • options | Object - Required Options describing the operation.
    • documentID | Number - Optional. The id of the source document. If the number is missing or negative, then the source will be the active document.
    • layerID | Number - Required. The id of the source layer.
    • kind | String - Optional. The kind of mask to return. There are two options: "user" or "vector". The default value is "user" which is the kind (pixel) applied by "Add Layer Mask" button.
    • sourceBounds | Object - Optional. The region whose pixels should be returned. If the value is not provided, then pixels from the entire mask are returned. The provided object must describe a rectangle using the following number properties:
      • left, top, right, and bottom
    • targetSize | Object - Optional. The dimensions of the returned image. If this value is not provided then the returned size will match the requested size (i.e. no scaling is performed on the returned pixels). The provided object must have one or more of the following attributes:
      • width and height. If only one dimension is provided then the returned image data is scaled proportionally to match the requested dimension.

Return value: Promise<Object>

The returned object has the following properties:

  • imageData | PhotoshopImageData. A PhotoshopImageData instance representing the pixels in the requested user mask. A user mask is represented as a single channel (gray scale image).
  • sourceBounds | Object. The actual bounds used when obtaining the mask pixels.

Example - get the user mask for a layer

Copied to your clipboard
1const imageObj = await imaging.getLayerMask({
2 documentID: 123,
3 layerID: 5,
4 kind: "user"
5 sourceBounds: { left: 0, top: 0, right: 300, bottom: 300 },
6 targetSize: { height: 100 }
7});

putLayerMask

This API allows JavaScript to edit the pixels of a layer's mask. At this time, only pixel masks are editable. In the UI, they are what is referred to as a "Layer Mask".

Copied to your clipboard
await imaging.putLayerMask(options);
  • options | Object - Required Options describing the operation.
    • documentID | Number - Optional. The id of the source document. If the number is missing or negative, then the source will be the active document.
    • layerID | Number - Required. The id of the target layer.
    • kind | String - Optional. The kind of mask to change. Only "user" is accepted at this time. The default value is "user".
    • imageData | PhotoshopImageData - Required. Value describing the mask data. This must be image data with a single component using the grayscale color model.
    • replace | Boolean - Optional. Describes how mask pixels are added. If true, then the exising mask in the layer is discarded before creating a new mask. If false, then the new image data is placed into to the existing mask in the layer. The default value is true.
    • targetBounds | Object - Optional. The region where the pixels should be inserted. If the value is not provided, then pixels are inserted at the origin (0, 0). The provided object must include the following values: left, top. (Dimension keys width and height are not used here.)
    • commandName | String - Optional. If provided, then this name is used when creating an entry in the history panel.

Example:

Copied to your clipboard
1await imaging.putLayerMask({
2 layerID: 123
3 imageData: grayImageData
4});

getSelection

This API allows JavaScript to obtain a pixel representation of the active selection. Think of it like entering Quick Mask mode.

Copied to your clipboard
const imageObj = await imaging.getSelection(options);
  • options | Object - Required Options describing the operation.
    • documentID | Number - Optional. The id of the source document. If missing, or negative, then the source is the active document.
    • sourceBounds | Object - Optional. The region whose pixels should be returned. If the value is not provided, then pixels from the entire selection are returned. The provided object must describe a rectangle using the following number properties:
      • left, top, right, and bottom
    • targetSize | Object - Optional. The dimensions of the returned image. If this value is not provided, then the returned size will match the requested size (i.e. no scaling is performed on the returned pixels). The provided object must have one or more of the following attributes:
      • width and height. If only one dimension is provided, then the returned image data is scaled proportionally to match the requested dimension.

Return value: Promise<Object>

The returned object has the following properties:

  • imageData | PhotoshopImageData. A PhotoshopImageData instance representing the selection.
  • sourceBounds | Object. The actual bounds used when obtaining the selection pixels.

Example - get the document selection

Copied to your clipboard
1const imageObj = await imaging.getSelection({
2 documentID: 123,
3 sourceBounds: { left: 0, top: 0, right: 300, bottom: 300 }
4});

putSelection

This API allows JavaScript to change the selection itself using a provided pixel data representation. Think of it like exiting Quick Mask mode.

Copied to your clipboard
await imaging.putSelection(options);
  • options | Object - Required Options describing the operation.
    • documentID | Number - Optional. The id of the source document. If missing, or negative, then the source is the active document.
    • replace | Boolean - Optional. Describes how selection is modified. If true, then the exising document selection is discarded before creating a new selection. If false, then the new image data is added to the existing document selection. The default value is true.
    • targetBounds | Object - Optional. The region where the selection should be inserted. If the value is not provided, then selection pixels are inserted at the origin (0, 0). The provided object must include the following values: left, top. (Dimension keys width and height are not used here.)
    • commandName | String - Optional. If provided, then this name is used when creating an entry in the history panel.

Example:

Copied to your clipboard
await imaging.putSelection({ imageData: grayImageData });

createImageDataFromBuffer

This API allows JavaScript to create arbitrary image data from a memory buffer.

Copied to your clipboard
const imageData = await imaging.createImageDataFromBuffer(arrayBuffer, options);
  • imageData | Typed array - Required | Desc ribes the image data. Accepted types are: Uint8Array, Uint16Array, and FloatArray. The used type will indicate the componentSize of the provided data. See table above.
  • options | Object - Required Options describing the operation.
    • width | Number - Required. The width of the image.
    • height | Number - Required. The height of the image.
    • components | Number - Required. Number of components per pixel.
    • chunky | Boolean - Optional. Describes pixel layout. See discussion above. The default value is true.
    • colorProfile | String - Required. Describes the color profile associated with the image data. See note regarding color profiles and 32 bit pixel data at the beginning of this document.
    • colorSpace | String - Required. Describes the color space associated with the image data. Can be "RGB" or "Grayscale"

Return value: Promise<PhotoshopImageData>

The number of elements in imageData must be equal to: width * height * components.

Example:

Copied to your clipboard
1const width = 30;
2const height = 40;
3const components = 4; // RGBA
4const componentCount = width * height;
5const dataSize = componentCount * components;
6const arrayBuffer = new Uint8Array(dataSize);
7
8// Add some (chunky) data to the buffer
9for (let i = 0 ; i < componentCount; i += components) {
10 arrayBuffer[index] = 255; // red
11 arrayBuffer[index+1] = 0; // green
12 arrayBuffer[index+2] = 0; // blue
13 arrayBuffer[index+3] = 127; // alpha
14}
15
16const options = {
17 width: width,
18 height: height,
19 components: components,
20 colorProfile: "sRGB IEC61966-2.1",
21 colorSpace: "RGB"
22};
23const imageData = await imaging.createImageDataFromBuffer(arrayBuffer, options)

Image data that is used for layer masks or document selections uses a single grayscale component. When creating such data, use components: 1, colorSpace: "Grayscale" and colorProfile: "Generic Gray Profile" as shown in the following example:

Copied to your clipboard
1const width = 30;
2const height = 40;
3const componentCount = width * height;
4const arrayBuffer = new Uint8Array(componentCount);
5
6for (let i = 0 ; i < componentCount; ++i) {
7 arrayBuffer[i] = 127; // all set to the median value
8}
9
10const options = {
11 width: width,
12 height: height,
13 components: 1, // masks are grayscale
14 chunky: false,
15 colorProfile: "Generic Gray Profile",
16 colorSpace: "Grayscale"
17};
18const maskData = await imaging.createImageDataFromBuffer(arrayBuffer, options)

encodeImageData

This API is exposed to allow image data to be used with UXP image elements. With the current version of UXP you must use jpeg/base64 encoding when assigning to an image element.

Copied to your clipboard
const dataImage = await imaging.encodeImageData(options);
  • options | Object - Required Options describing the operation.
    • imageData | PhotoshopImageData - Required. Value describing the pixel data.
    • base64 | Boolean - Optional. If provided, then the returned value will be a string that is base64 encoded.

Return value: Promise<Number[] | string>

Example:

Copied to your clipboard
1const imageElement = document.createElement('img');
2
3const jpegData = await imaging.encodeImageData({"imageData": imgObj.imageData, "base64": true});
4
5const dataUrl = "data:image/jpeg;base64," + jpegData;
6imageElement.src = dataUrl;
7document.body.appendChild(imageElement);

Sample files

Here you will find a sample plugin (how to load) and UXP JavaScript file (.psjs) that exercise most of the above.

Was this helpful?
  • Privacy
  • Terms of Use
  • Do not sell or share my personal information
  • AdChoices
Copyright © 2023 Adobe. All rights reserved.