Good day everyone!
I have some wonderful news for anyone interested!
I present to you: Layer display
It is nothing special really. Select the layer, export the layer, load the file as ArrayBuffer, convert to uInt8Array and make a url for it.
Though I spent some time searching, in order to find this solution.
Aside from a humble brag (
brag), I would like to share for posterity.
Any improvements will be greatly appreciated.
The Export as PNG function
export const exportLayerAsPngAndLoad = async (layer: Layer): Promise<string> => {
const { id, name } = layer;
await core.executeAsModal(
async () => {
const destFolder = (await storage.localFileSystem.getDataFolder()).nativePath;
await selectLayerByID(id);
const exportCommand = {
_obj: 'exportSelectionAsFileTypePressed',
_target: { _ref: 'layer', _enum: 'ordinal', _value: 'targetEnum' },
fileType: 'png',
quality: 32,
metadata: 0,
destFolder,
sRGB: true,
openWindow: false,
_options: { dialogOptions: 'dontDisplay' },
};
await action.batchPlay([exportCommand], { synchronousExecution: true, modalBehavior: 'execute' });
},
{ commandName: 'Export Layer As PNG' }
);
try {
return loadImageFromDataFolder(name);
} catch (e) {
console.error(`Error loading image: ${e}`);
}
return null;
};
Load Image function
export const loadImageFromDataFolder = async (imageName: string): Promise<string> => {
const dataFolder = await storage.localFileSystem.getDataFolder();
const name = imageName.concat('.png');
const entriesArray = Array.from(await dataFolder.getEntries());
const image = entriesArray.find((entry) => entry.name === name);
if (!image) throw new Error(`Image ${imageName}.png Not Found`);
if (!image.isFile) throw new Error(`${imageName}.png is not a file`);
const file = image as storage.File;
const data = (await file.read({ format: storage.formats.binary })) as ArrayBuffer;
if (data.byteLength === 0) throw new Error(`${imageName}.png is empty`);
const uInt8Array = new Uint8Array(data);
const blob = new Blob([uInt8Array]);
const url = URL.createObjectURL(blob);
await image.delete();
return url;
};
Select Layer By ID
export const selectLayerByID = async (layerID: number) => {
const actionObject = [
{
_obj: 'select',
_target: [
{
_ref: 'layer',
_id: layerID,
},
],
makeVisible: false,
layerID: [layerID],
_isCommand: false,
},
];
await app.batchPlay(actionObject, { modalBehavior: 'execute' });
};
React Image Display
import React, { FC } from 'react';
import { ImageDisplayStyle, ImageDisplayContainer } from './styled';
import { Layer } from 'Photoshop'; // Credit to Hans Otto Wirtz for the Typescript library
interface Props {
exportLayer: Layer;
}
export const ImageDisplay: FC<Props> = (props: Props) => {
const { exportLayer } = props;
const [loading, setLoading] = useState(false);
const [imageUrl, setImageUrl] = useState(null);
useEffect(() => {
if(exportLayer) {
setLoading(true);
const url = await exportLayerAsPngAndLoad(exportLayer);
setLoading(false);
setImageUrl(url);
}
}, [exportLayer])
return (
<ImageDisplayStyle>
{(imageUrl && (
<ImageDisplayContainer>
<img className="background" src="/images/BackGround.png" alt="Background" />
{(!loading && <img className="image" src={imageUrl} alt="BaseLayer" />) || (
<img className="loading" src="LOADING.gif" alt="loading" />
)}
</ImageDisplayContainer>
)) || <ImageDisplayContainer>Select a Choice</ImageDisplayContainer>}
</ImageDisplayStyle>
);
};
export default ImageDisplay;