Create a JavaScript column and put this code:
function calculateDimensions(images, sizeAdjustment, keepRatio, isVertical) {
let totalWidth = 0;
let totalHeight = 0;
const dimensions = [];
images.forEach(img => {
let width = img.width;
let height = img.height;
if (sizeAdjustment === "reduce") {
const scale = Math.min(width / img.width, height / img.height);
width = img.width * scale;
height = img.height * scale;
}
dimensions.push({ width, height });
if (isVertical) {
totalWidth = Math.max(totalWidth, width);
totalHeight += height;
} else {
totalWidth += width;
totalHeight = Math.max(totalHeight, height);
}
});
return {
totalWidth,
totalHeight,
dimensions
};
}
function mergeImages(imageUrls) {
return new Promise((resolve, reject) => {
if (!imageUrls || imageUrls.length < 2) {
reject('Please provide an array with at least two image URLs to merge');
return;
}
// Create new Image objects to ensure images are fully loaded
const loadImages = (urls) => {
return Promise.all(urls.map(url => {
return new Promise((resolve, reject) => {
const img = new Image();
img.crossOrigin = "Anonymous";
img.onload = () => resolve(img);
img.onerror = (event) => reject(new Error(`Failed to load image: ${url}`));
img.src = url;
});
}));
};
loadImages(imageUrls)
.then(images => {
// Create a temporary canvas
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const isVertical = true;
const borderWidth = 0;
const borderColor = "#ffffff";
const sizeAdjustment = "reduce";
const keepRatio = true;
// Calculate dimensions
let dims = calculateDimensions(images, sizeAdjustment, keepRatio, isVertical);
// Set canvas size
if (isVertical) {
canvas.width = dims.totalWidth;
canvas.height = dims.totalHeight + (borderWidth * (images.length - 1));
} else {
canvas.width = dims.totalWidth + (borderWidth * (images.length - 1));
canvas.height = dims.totalHeight;
}
// Draw images on the canvas
let offset = 0;
images.forEach((img, index) => {
const dim = dims.dimensions[index];
if (isVertical) {
ctx.drawImage(img, 0, offset, dim.width, dim.height);
offset += dim.height + borderWidth;
} else {
ctx.drawImage(img, offset, 0, dim.width, dim.height);
offset += dim.width + borderWidth;
}
if (borderWidth > 0 && index < images.length - 1) {
if (isVertical) {
ctx.fillStyle = borderColor;
ctx.fillRect(0, offset - borderWidth, canvas.width, borderWidth);
} else {
ctx.fillStyle = borderColor;
ctx.fillRect(offset - borderWidth, 0, borderWidth, canvas.height);
}
}
});
// Convert to base64 with compression
const base64Image = canvas.toDataURL('image/jpeg', 0.7); // Adjust compression quality here
// Upload to ImgBB
uploadToImgBB(base64Image)
.then(uploadedUrl => resolve(uploadedUrl))
.catch(error => reject('Error uploading image: ' + error.message));
})
.catch(error => {
reject('Error merging images: ' + error.message);
});
});
}
async function uploadToImgBB(base64Image) {
const apiUrl = 'https://api.imgbb.com/1/upload';
const apiKey = p3; // Ensure p3 contains your ImgBB API key
const imageData = base64Image.split(',')[1]; // Remove the base64 prefix
const formData = new FormData();
formData.append('key', apiKey);
formData.append('image', imageData);
formData.append('expiration', '600'); // Set expiration to 600 seconds as per your example
const response = await fetch(apiUrl, {
method: 'POST',
body: formData
});
if (!response.ok) {
throw new Error(`Failed to upload image: ${response.statusText}`);
}
const result = await response.json();
if (result.success) {
return result.data.url;
} else {
throw new Error(result.error.message);
}
}
// Usage example:
const imageUrls = JSON.parse(p1); // Ensure p1 contains a JSON string of image URLs
return await mergeImages(imageUrls)
.then(uploadedUrl => {
console.log('Uploaded image URL:', uploadedUrl);
return uploadedUrl;
})
.catch(error => {
console.error(error);
});
In p1, put images’ url in the following format: [“url1”,“url2”,“url3”].
In p3, put your imgbb api key. Create a random account because that API key will be visible to everyone. Not a big deal in this case.
Url the returned URL from the Javascript column in your image component:
Source
Base source code from: Merge two images online, heavily modified by chat.mistral.ai.