I want screate plugin for simple image browser. Now its parially working. I can select folder, show thumbs but double click is not importing/placing image in document. I want use as my quick image library with search function. Any ideas hot to resolve this? My code right now looks like this
const fs = require("uxp").storage.localFileSystem;
const uxp = require("uxp");
const photoshop = require("photoshop").app;
let selectedFolder = null;
// When the "Select Folder" button is clicked
document.getElementById("select-btn").addEventListener("click", async () => {
try {
// Let the user select a folder
selectedFolder = await fs.getFolder();
if (!selectedFolder) {
displayMessage("No folder selected.");
return;
}
displayMessage("Folder selected: " + selectedFolder.nativePath);
console.log("Folder selected:", selectedFolder.nativePath);
// Clear existing results before loading new images
clearThumbnails();
// Load images from the selected folder
loadImages(selectedFolder);
} catch (error) {
displayMessage("Error selecting folder: " + error.message);
console.error("Error selecting folder:", error);
}
});
// Function to display messages to the user in the UI
function displayMessage(message) {
const resultsContainer = document.getElementById("results");
resultsContainer.innerHTML = `<p>${message}</p>`;
}
// Function to clear thumbnails in the UI
function clearThumbnails() {
const resultsContainer = document.getElementById("results");
resultsContainer.innerHTML = ""; // Clear any previous results
}
// Function to load images from the selected folder
async function loadImages(folder) {
const resultsContainer = document.getElementById("results");
try {
console.log("Loading images from folder:", folder.nativePath);
const images = await getImagesFromFolder(folder);
if (images.length === 0) {
displayMessage("No images found in the selected folder.");
return;
}
images.forEach(async (file) => {
const fileElement = document.createElement("div");
fileElement.classList.add("thumbnail");
try {
// Read file as binary data (ArrayBuffer) for image files
const fileData = await file.read({ format: uxp.storage.formats.binary });
console.log("File read successfully:", file.name);
// Check the type of fileData returned by read()
if (fileData instanceof ArrayBuffer) {
const blob = new Blob([fileData]);
const imageUrl = URL.createObjectURL(blob); // Create an object URL for the Blob
fileElement.innerHTML = `<img src="${imageUrl}" alt="${file.name}" style="width:50px; height:50px; cursor:pointer;">`;
// When double-clicking the thumbnail, open the image in Photoshop
fileElement.addEventListener("dblclick", async () => {
await importImageToPSD(file);
});
resultsContainer.appendChild(fileElement);
} else {
console.error("Error: file content is not an ArrayBuffer, it's a", typeof fileData);
displayMessage("Error reading file: Not an ArrayBuffer, got: " + typeof fileData);
}
} catch (error) {
console.error("Error reading file:", error);
displayMessage("Error reading file: " + error.message);
}
});
} catch (error) {
displayMessage("Error retrieving entries from folder: " + error.message);
console.error("Error retrieving entries from folder:", error);
}
}
// Recursive function to get all images (jpg/png) from a folder and its subfolders
async function getImagesFromFolder(folder) {
let imageFiles = [];
const entries = await folder.getEntries();
for (const entry of entries) {
if (entry.isFile && (entry.name.toLowerCase().endsWith(".jpg") || entry.name.toLowerCase().endsWith(".png"))) {
imageFiles.push(entry); // Add image files to the array
} else if (entry.isFolder) {
// Recursively check inside subfolders
const subfolderImages = await getImagesFromFolder(entry);
imageFiles = imageFiles.concat(subfolderImages); // Combine results from subfolders
}
}
return imageFiles;
}
// Function to import the selected image to the currently open PSD document
async function importImageToPSD(file) {
try {
const fileData = await file.read({ format: uxp.storage.formats.binary }); // Read the file content as binary
console.log("Importing image to PSD:", file.name);
// Check the type of fileData returned by read()
if (fileData instanceof ArrayBuffer) {
// Create a Blob from the ArrayBuffer
const blob = new Blob([fileData]);
// Save the Blob to a temporary file in the system
const tempFile = await saveTemporaryFile(blob, file.name);
// Now place the image in Photoshop
await placeImageInPhotoshop(tempFile);
} else {
console.error("Error: file content is not an ArrayBuffer, it's a", typeof fileData);
displayMessage("Failed to import image: Not an ArrayBuffer");
}
} catch (err) {
displayMessage("Failed to import image: " + err.message);
console.error("Error importing image:", err);
}
}
// Function to save the image data to a temporary file
async function saveTemporaryFile(blob, filename) {
const tempFolder = await fs.getTemporaryFolder(); // Get the system's temporary folder
const tempFile = await tempFolder.createFile(filename, { overwrite: true }); // Create the temp file with the specified filename
await tempFile.write(blob); // Write the image data to the temporary file
return tempFile; // Return the temporary file object
}
// Function to place the image in Photoshop document using BatchPlay
async function placeImageInPhotoshop(file) {
try {
const doc = photoshop.activeDocument; // Get the currently active document
// Create the asset object that we will use for placing the image
const asset = { file: file.nativePath }; // asset file path to the temporary file
// Ensure we pass the path directly as a string to the placeEvent command
const cmd = [{
"_obj": "placeEvent",
"null": {
"_path": asset.file, // The path to the temporary image file
"_kind": "local"
},
"offset": {
"_obj": "offset",
"horizontal": {
"_unit": "pixelsUnit",
"_value": 0
},
"vertical": {
"_unit": "pixelsUnit",
"_value": 0
}
},
"_isCommand": true
}];
// Run the BatchPlay command
await photoshop.batchPlay(cmd);
console.log("Image placed successfully.");
} catch (err) {
console.error("Error placing image:", err);
displayMessage("Failed to place image: " + err.message);
}
}