Convert a gdoc into image
Asked Answered
C

2

5

is there a way to create an image (e.g. a png) from a google document? I really mean an image, not just a pdf. GetAS only creates pdf, but returns an error if contentType is set to image/png or other equivalent formats. My (actually trivial) code is

function convertFile() {
var SOURCE_TEMPLATE = "1HvqYidpUpihzo_HDAQ3zE5ScMVsHG9NNlwPkN80GHK0";
var TARGET_FOLDER = "1Eue-3tJpE8sBML0qo6Z25G0D_uuXZjHZ";
var source = DriveApp.getFileById(SOURCE_TEMPLATE);
var targetFolder = DriveApp.getFolderById(TARGET_FOLDER);
var target = source.makeCopy(source,targetFolder);
var newFile = DriveApp.createFile(target.getAs('image/png'));
}

When I run this code, I get the following error (my translation):

The conversion from application/vnd.google-apps.document to image/png is not supported.

Ty

Chaussure answered 11/3, 2019 at 22:44 Comment(3)
You want to retrieve each page as PNG data. Is my understanding correct? By the way, in order to correctly your situation, can you provide your current script?Estriol
Yes, that is correct. My script is trivial: I just verified that 'newFile = DriveApp.createFile(target.getAs('application/pdf'));' creates a pdf, but 'newFile = DriveApp.createFile(target.getAs('image/png'));' returns an error.Chaussure
Thank you for replying. Can I ask you about your reply? 1. What is target? 2. Can you provide the detail information about returns an error.? 3. Can you add the script in your question by updating? I think that it will help users think of about your question. If you can cooperate to resolve your issue, I'm glad.Estriol
E
8

How about this answer?

Reason of error:

makeCopy() returns File object. getAs() cannot be used for this. By this, the error occurs.

Workaround:

Unfortunately, in the current stage, Google Document cannot be directly exported as PNG images. So it is required to think of workarounds. Google Document can be converted to PDF. This answer uses this. As a workaround, I would like to propose to use an external API which is ConvertAPI. I thought that using the external API, the script becomes simple. This a method (PDF to PNG API) of API can be converted from PDF data to PNG data.

When you try this, for example, you can also test this using "Free Package". When you try using "Free Package", please Sign Up at "Free Package" and retrieve your Secret key.

Sample script:

Before you run this script, please retrieve your Secret key and set it.

var secretkey = "###";  // Please set your secret key.

var SOURCE_TEMPLATE = "1HvqYidpUpihzo_HDAQ3zE5ScMVsHG9NNlwPkN80GHK0";
var TARGET_FOLDER = "1Eue-3tJpE8sBML0qo6Z25G0D_uuXZjHZ";
var url = "https://v2.convertapi.com/convert/pdf/to/png?Secret=" + secretkey;
var options = {
  method: "post",
  payload: {File: DriveApp.getFileById(SOURCE_TEMPLATE).getBlob()},
}
var res = UrlFetchApp.fetch(url, options);
res = JSON.parse(res.getContentText());
res.Files.forEach(function(e) {
  var blob = Utilities.newBlob(Utilities.base64Decode(e.FileData), "image/png", e.FileName);
  DriveApp.getFolderById(TARGET_FOLDER).createFile(blob);
});

References:

Updated on January 11, 2023:

In the current stage, Google Apps Script can use V8 runtime. By this, there are some Javascript libraries that can be used with Google Apps Script. Ref1, Ref2 In this question, in the current stage, by using pdf-lib, all pages in a PDF file can be converted to PNG images using Google Apps Script. The sample script is as follows.

Sample script:

This method uses Drive API. Please enable Drive API at Advanced Google services.

Please set SOURCE_TEMPLATE and TARGET_FOLDER, and run main().

/**
 * This is a method for converting all pages in a PDF file to PNG images.
 * PNG images are returned as BlobSource[].
 * IMPORTANT: This method uses Drive API. Please enable Drive API at Advanced Google services.
 * 
 * @param {Blob} blob Blob of PDF file.
 * @return {BlobSource[]} PNG blobs.
 */
async function convertPDFToPNG_(blob) {
  // Convert PDF to PNG images.
  const cdnjs = "https://cdn.jsdelivr.net/npm/pdf-lib/dist/pdf-lib.min.js";
  eval(UrlFetchApp.fetch(cdnjs).getContentText()); // Load pdf-lib
  const setTimeout = function (f, t) { // Overwrite setTimeout with Google Apps Script.
    Utilities.sleep(t);
    return f();
  }
  const data = new Uint8Array(blob.getBytes());
  const pdfData = await PDFLib.PDFDocument.load(data);
  const pageLength = pdfData.getPageCount();
  console.log(`Total pages: ${pageLength}`);
  const obj = { imageBlobs: [], fileIds: [] };
  for (let i = 0; i < pageLength; i++) {
    console.log(`Processing page: ${i + 1}`);
    const pdfDoc = await PDFLib.PDFDocument.create();
    const [page] = await pdfDoc.copyPages(pdfData, [i]);
    pdfDoc.addPage(page);
    const bytes = await pdfDoc.save();
    const blob = Utilities.newBlob([...new Int8Array(bytes)], MimeType.PDF, `sample${i + 1}.pdf`);
    const id = DriveApp.createFile(blob).getId();
    Utilities.sleep(3000); // This is used for preparing the thumbnail of the created file.
    const link = Drive.Files.get(id, { fields: "thumbnailLink" }).thumbnailLink;
    if (!link) {
      throw new Error("In this case, please increase the value of 3000 in Utilities.sleep(3000), and test it again.");
    }
    const imageBlob = UrlFetchApp.fetch(link.replace(/\=s\d*/, "=s1000")).getBlob().setName(`page${i + 1}.png`);
    obj.imageBlobs.push(imageBlob);
    obj.fileIds.push(id);
  }
  obj.fileIds.forEach(id => DriveApp.getFileById(id).setTrashed(true));
  return obj.imageBlobs;
}

// Please run this function.
async function myFunction() {
  const SOURCE_TEMPLATE = "1HvqYidpUpihzo_HDAQ3zE5ScMVsHG9NNlwPkN80GHK0";
  const TARGET_FOLDER = "1Eue-3tJpE8sBML0qo6Z25G0D_uuXZjHZ";

  // Use a method for converting all pages in a PDF file to PNG images.
  const blob = DriveApp.getFileById(SOURCE_TEMPLATE).getBlob();
  const imageBlobs = await convertPDFToPNG_(blob);

  // As a sample, create PNG images as PNG files.
  const folder = DriveApp.getFolderById(TARGET_FOLDER);
  imageBlobs.forEach(b => folder.createFile(b));
}
  • When this script is run, all pages of the inputted PDF file are converted to PNG images, and those images are created in the destination folder.

Note:

References:

Estriol answered 13/3, 2019 at 23:31 Comment(8)
I just want to add that ConvertAPI has another thumbnail generator API where first page can be extracted and converted to png image, it works a bit faster than PDF to PNG. The Rest API endpoint would be v2.convertapi.com/convert/pdf/to/…Malvinamalvino
thanks it works perfectly, does someone knows other API with same purpose?Haihaida
@Estriol Do you know if there is a way to get better quality image from it? I am getting really low quality image when transferred from pdf to imageHylan
@Hylan About your question @Estriol Do you know if there is a way to get better quality image from it? I am getting really low quality image when transferred from pdf to image, can you post it as a new question by including more information? Because I cannot understand your question. But, I would like to support you. And, when you post it as a new question, it will help users including me think of a solution. If you can cooperate to resolve your question, I'm glad. Can you cooperate to do it?Estriol
it will be just an update to this question, so should I post a new question? #78477209Hylan
@Hylan About should I post a new question?, yes. Please post it as a new question. At that time, please include more information. If you can cooperate to resolve your question, I'm glad. Can you cooperate to do it?Estriol
I have posted a new question here #78552963Hylan
@Hylan Thank you for replying. When I could correctly understand your question, I would like to think of a solution.Estriol
T
1

I know this is an older question, but I thought I'd answer, since I believe I've found a solution that doesn't involve paying for a third-party subscription.

This can be accomplished by accessing the thumbnail of the Doc and creating a new PNG file from that thumbnail. Try this:

function convertFile() {
  var SOURCE_TEMPLATE = "1HvqYidpUpihzo_HDAQ3zE5ScMVsHG9NNlwPkN80GHK0";
  var TARGET_FOLDER = "1Eue-3tJpE8sBML0qo6Z25G0D_uuXZjHZ";
  var source = DriveApp.getFileById(SOURCE_TEMPLATE).getThumbnail().getAs('image/png');
  var targetFolder = DriveApp.getFolderById(TARGET_FOLDER);
  TARGET_FOLDER.createFile(source);
}

However, I've found that getting the thumbnail of the Doc is not as high quality as getting the thumbnail of a PDF created from the Doc. You can try the code below to compare which version of the new PNG you prefer.

To do this, you will also need to enable Advanced Services on your project, specifically the Drive API service. To do this, follow these instructions to add a new Service to your Google Apps Script project:

  • Open the Apps Script project.
  • At the left, click Editor < >.
  • At the left, next to Services, click Add a service +.
  • Select Drive API and click Add.

Once you do that, you'll be able to use the Drive command in your script, which is different than DriveApp. Note also the update to source.makeCopy() to only include the TARGET_FOLDER:

function convertFile() {
  var SOURCE_TEMPLATE = "1HvqYidpUpihzo_HDAQ3zE5ScMVsHG9NNlwPkN80GHK0";
  var TARGET_FOLDER = "1Eue-3tJpE8sBML0qo6Z25G0D_uuXZjHZ";
  var source = DriveApp.getFileById(SOURCE_TEMPLATE);
  var targetFolder = DriveApp.getFolderById(TARGET_FOLDER);
  var target = source.makeCopy(targetFolder);
  var pdfBlob = target.getAs(MimeType.PDF);
  var newPDF = TARGET_FOLDER.createFile(pdfBlob).setName('Some Name.pdf');
  var newId = newPDF.getId();
  Drive.Files.update({
    title: newPDF.getName(), mimeType: MimeType.PDF
  }, newId, pdfBlob);
  var newFile = DriveApp.getFileById(newId).getThumbnail().getAs('image/png');
  TARGET_FOLDER.createFile(newFile);
  target.setTrashed(true);
  newPDF.setTrashed(true);
}

This code will create a copy of your Google Doc file, convert it to a PDF, then grab the thumbnail of the PDF as a PNG, and then delete the copy of the Doc file and the PDF that were created.

The Drive.Files.update() function is the critical part of this code, as it finalizes the creation of the PDF file in your Drive. Trying to run the code without that portion will just return the new PDF file as null since the new PDF hasn't completely finished being created at that point.

Hope this helps!

Tutankhamen answered 24/10, 2022 at 14:46 Comment(1)
Thank you, but you should chane two "TARGET_FOLDER.createFile" parts to "tagetFolder.createFile".Christinchristina

© 2022 - 2024 — McMap. All rights reserved.