I need a script in Google Apps Script to merge two images into one (add a logo or watermark to an image). I've tried using the Slides API and the Document API, but encountered issues.
Here’s the script I wrote:
function addLogoToImage() {
var imageBlob = UrlFetchApp.fetch("https://........jpg").getBlob();
var logoBlob = UrlFetchApp.fetch("https://......jpg").getBlob();
const presentation = SlidesApp.create('temp');
const slide = presentation.getSlides()[0];
// Add the main image
slide.insertImage(imageBlob);
// Add the logo
slide.insertImage(logoBlob).setWidth(50).setHeight(50).setTop(10).setLeft(10);
Utilities.sleep(2000);
// Export the slide as an image
const presentationId = presentation.getId();
const exportUrl = `https://docs.google.com/presentation/d/${presentationId}/export/png`;
const token = ScriptApp.getOAuthToken();
const response = UrlFetchApp.fetch(exportUrl, {
headers: {
Authorization: `Bearer ${token}`,
},
});
const thumbnail = response.getBlob().setName('merged_image.png');
DriveApp.createFile(thumbnail);
// Clean up by deleting the presentation
Drive.Files.remove(presentationId);
}
However, the result is a blank white image of 3 KB in size.
I also tried the Document API with the following script:
function addLogoWithGoogleDrawings() {
// Image URLs
var imageUrl = "https://.........jpg";
var logoUrl = "https://........jpg";
// Add the images to a drawing
var doc = DocumentApp.create("temp");
var drawingId = doc.getId();
var body = doc.getBody();
body.appendImage(UrlFetchApp.fetch(imageUrl).getBlob());
body.appendImage(UrlFetchApp.fetch(logoUrl).getBlob());
// Wait for the content to load
Utilities.sleep(3000);
// Export as JPG
const thumbnail = doc.getAs("image/png").setName('merged_image.png');
DriveApp.createFile(thumbnail);
// Clean up by deleting the document
Drive.Files.remove(drawingId);
}
However, as per the documentation, the getAs() method only supports exporting to application/pdf or text/markdown.
Question: Does anyone have an idea how to merge images and export them as a single image file using Google Apps Script? Alternatively, is there a way to fix one of the scripts above?
Bonus...: In the future, I’ll need a similar solution for adding watermarks to videos (e.g., a logo displayed in a corner throughout the video). Any guidance on that would also be greatly appreciated!
Thank you!
This script uses the Google Slides API
(via SlidesApp) to automate the creation of a Google Slides presentation. It merges two images by first fetching the main image
and a logo or watermark
.
The script then creates a new Google Slides presentation, inserts the images, and adjusts their sizes and positions.
The slide is saved as a PNG image, which is stored in Google Drive, and the temporary Google Slides presentation is deleted.
Code:
function downloadMergedSlide() {
var pngFile = mergeAndConvertToPng();
var html = "<script>window.open('" + pngFile.getDownloadUrl() + "');google.script.host.close();</script>";
var userInterface = HtmlService.createHtmlOutput(html)
.setHeight(10)
.setWidth(100);
SlidesApp.getUi().showModalDialog(userInterface, 'Downloading PNG ...');
pngFile.setTrashed(true);
}
function mergeAndConvertToPng() {
const mainImageURL = "https://........jpg";
const logoImageURL = "https://........jpg";
const mainImageBlob = UrlFetchApp.fetch(mainImageURL).getBlob();
const logoImageBlob = UrlFetchApp.fetch(logoImageURL).getBlob();
const presentation = SlidesApp.create("Temp Merged Slide");
const slide = presentation.getSlides()[0];
const mainImage = slide.insertImage(mainImageBlob);
mainImage.setWidth(960).setHeight(540).setTop(0).setLeft(0);
const logoImage = slide.insertImage(logoImageBlob);
logoImage.setWidth(50).setHeight(50).setTop(10).setLeft(10);
presentation.saveAndClose();
const presentationId = presentation.getId();
const exportUrl = `https://docs.google.com/presentation/d/${presentationId}/export/png`;
const token = ScriptApp.getOAuthToken();
const response = UrlFetchApp.fetch(exportUrl, {
headers: {
Authorization: `Bearer ${token}`,
},
muteHttpExceptions: true,
});
if (response.getResponseCode() === 200) {
const pngBlob = response.getBlob();
const pngFile = DriveApp.createFile(pngBlob.setName("merged_image.png"));
DriveApp.getFileById(presentationId).setTrashed(true);
return pngFile;
}
return null;
}
Sample Output:
To adjust the size or position of the images, you can change the values of setWidth()
, setHeight()
, setTop()
, and setLeft()
for both images.
Reference: