From 0ca65014567c533c9dbed239c31f24f9d252452c Mon Sep 17 00:00:00 2001 From: Abdullah Alfaraj <7842232+AbdullahAlfaraj@users.noreply.github.com> Date: Thu, 7 Dec 2023 11:46:25 +0300 Subject: [PATCH] Added version check for Adobe Photoshop in real-time img2img feature --- index.js | 61 ---------------------- typescripts/comfyui/comfyui.tsx | 35 +++++++++---- typescripts/util/ts/general.ts | 91 ++++++++++++++++++++++++++++++++- 3 files changed, 115 insertions(+), 72 deletions(-) diff --git a/index.js b/index.js index 7da71e3..03cee81 100644 --- a/index.js +++ b/index.js @@ -1821,64 +1821,3 @@ async function openFileFromUrlExe(url, format = 'gif') { await openFileFromUrl(url, format) }) } - -const imaging = require('photoshop').imaging - -async function getImageFromLayer(sourceBounds, layer_id, components) { - const image_obj = await imaging.getPixels({ - ...(sourceBounds && { - sourceBounds: { left: 0, top: 0, right: 3000, bottom: 3000 }, - }), - ...(layer_id && { layerID: layer_id }), - components: components, - applyAlpha: true, - colorSpace: 'RGB', - }) - - return image_obj -} - -async function imageObjectToBase64(imgObj) { - const pixelData = await imgObj.imageData.getData() - // const base64 = Buffer.from(pixelData).toString('base64') - // const base64 = _arrayBufferToBase64(pixelData) - const jpegData = await imaging.encodeImageData({ - imageData: imgObj.imageData, - base64: true, - // pixelFormat: 'RGBA', - // applyAlpha: true, - }) - return jpegData - // return base64 -} - -async function imageObjectToBase64Url(imgObj) { - const jpegData = await imageObjectToBase64(imgObj) - const dataUrl = 'data:image/jpeg;base64,' + jpegData - // const dataUrl = 'data:image/png;base64,' + jpegData - - return dataUrl -} - -async function getImageFromCanvas(layer_id) { - let data_url - await executeAsModal(async () => { - const selection_info = await psapi.getSelectionInfoExe() - // let imgObj = await getImageFromLayer({},app.activeDocument.activeLayers[0].id,3) - let imgObj = await getImageFromLayer(selection_info, layer_id, 3) - - data_url = await imageObjectToBase64Url(imgObj) - // console.log('data_url:', data_url) - // html_manip.setInitImageSrc(data_url) - console.log('getImageFromCanvas: triggered') - }) - return data_url -} -let g_canvas_data_url -function getImageFromCanvasByInterval(interval = 5000) { - const interval_id = setInterval(async () => { - console.log('setInterval trigger') - g_canvas_data_url = await getImageFromCanvas() - }, interval) - return interval_id -} diff --git a/typescripts/comfyui/comfyui.tsx b/typescripts/comfyui/comfyui.tsx index f4803ca..e951510 100644 --- a/typescripts/comfyui/comfyui.tsx +++ b/typescripts/comfyui/comfyui.tsx @@ -19,7 +19,7 @@ import { Grid } from '../util/grid' import { io } from '../util/oldSystem' import { app, core } from 'photoshop' import { reaction, toJS } from 'mobx' -import { storage } from 'uxp' +import { host, storage } from 'uxp' import util, { ComfyInputType, @@ -29,7 +29,14 @@ import util, { store, } from './util' -import { base64UrlToBase64, copyJson, urlToCanvas } from '../util/ts/general' +import { + base64UrlToBase64, + copyJson, + deleteKeys, + getImageFromCanvas_new, + isValidVersion, + urlToCanvas, +} from '../util/ts/general' import comfyapi from './comfyapi' import { getSelectionInfoExe } from '../../psapi' import { moveImageToLayer } from '../util/ts/io' @@ -1516,11 +1523,11 @@ class ComfyWorkflowComponent extends React.Component<{}, { value?: number }> { store.data.lastCall = now const image_data_url = - //@ts-ignore - await getImageFromCanvas() + await getImageFromCanvas_new() + const image_base64 = base64UrlToBase64( - image_data_url + image_data_url! ) const image_name = @@ -1571,13 +1578,12 @@ class ComfyWorkflowComponent extends React.Component<{}, { value?: number }> { node_id ].data?.layer_id const layer_data_url = - //@ts-ignore - await getImageFromCanvas( - layer_id + await getImageFromCanvas_new( + layer_id! ) const layer_image_base64 = base64UrlToBase64( - layer_data_url + layer_data_url! ) const image_name = @@ -1597,10 +1603,21 @@ class ComfyWorkflowComponent extends React.Component<{}, { value?: number }> { } } catch (e) { console.error(e) + if (!isValidVersion(25)) { + // const errorMessage = `Real-time img2img Require Adobe Photoshop version 25 or higher. Your current version is ${host.version}. Please update Adobe Photoshop to use this feature. You can still use realtime txt2img.` + // app.showAlert(errorMessage) + throw e + } } } } catch (e) { console.error(e) + if (!isValidVersion(25)) { + const errorMessage = `Real-time img2img Require Adobe Photoshop version 25 or higher. Your current version is ${host.version}. Please update Adobe Photoshop to use this feature. You can still use realtime txt2img.` + app.showAlert(errorMessage) + throw errorMessage + } + throw e } } while (store.data.infinite_loop) { diff --git a/typescripts/util/ts/general.ts b/typescripts/util/ts/general.ts index 258554f..f90a612 100644 --- a/typescripts/util/ts/general.ts +++ b/typescripts/util/ts/general.ts @@ -1,5 +1,6 @@ -import { core } from 'photoshop' -import { io } from '../oldSystem' +import { app, core, imaging } from 'photoshop' +import { io, psapi } from '../oldSystem' +import { host } from 'uxp' export function autoResize(textarea: any, text_content: string, delay = 300) { try { @@ -68,3 +69,89 @@ export function newOutputImageName(format = 'png') { console.log('generated image name:', image_name) return image_name } + +export function isValidVersion(minMajorVersion: number) { + const current_major_version = host.version.split('.')[0] + if (parseInt(current_major_version) >= minMajorVersion) { + return true + } else { + return false + } +} + +async function getImageFromLayer( + sourceBounds: any, + layer_id: number | undefined, + components: any +) { + const image_obj = await imaging.getPixels({ + ...(sourceBounds && { + sourceBounds: { + left: sourceBounds.left, + top: sourceBounds.top, + right: sourceBounds.right, + bottom: sourceBounds.bottom, + }, + }), + ...(layer_id && { layerID: layer_id }), + components: components, + applyAlpha: true, + colorSpace: 'RGB', + }) + + return image_obj +} + +async function imageObjectToBase64(imgObj: any) { + const pixelData = await imgObj.imageData.getData() + // const base64 = Buffer.from(pixelData).toString('base64') + // const base64 = _arrayBufferToBase64(pixelData) + const jpegData = await imaging.encodeImageData({ + imageData: imgObj.imageData, + base64: true, + // pixelFormat: 'RGBA', + // applyAlpha: true, + }) + return jpegData + // return base64 +} + +async function imageObjectToBase64Url(imgObj: any) { + const jpegData = await imageObjectToBase64(imgObj) + const dataUrl = 'data:image/jpeg;base64,' + jpegData + // const dataUrl = 'data:image/png;base64,' + jpegData + + return dataUrl +} + +export async function getImageFromCanvas_new(layer_id?: number) { + let data_url + if (!isValidVersion(25)) { + const errorMessage = `Real-time img2img Require Adobe Photoshop version 25 or higher. Your current version is ${host.version}. Please update Adobe Photoshop to use this feature. You can still use realtime txt2img.` + // app.showAlert(errorMessage) + throw errorMessage + } + await core.executeAsModal( + async () => { + const selection_info = await psapi.getSelectionInfoExe() + // let imgObj = await getImageFromLayer({},app.activeDocument.activeLayers[0].id,3) + let imgObj = await getImageFromLayer(selection_info, layer_id, 3) + + data_url = await imageObjectToBase64Url(imgObj) + // console.log('data_url:', data_url) + // html_manip.setInitImageSrc(data_url) + console.log('getImageFromCanvas: triggered') + }, + { commandName: 'Get Image from Canvas' } + ) + return data_url +} + +export function deleteKeys(obj: Record, keys: string[]) { + keys.forEach((key) => { + if (obj.hasOwnProperty(key)) { + delete obj[key] + } + }) + return obj +}