【问题标题】:Google Sheet/Google Script - Plotting points over a pictureGoogle Sheet/Google Script - 在图片上绘制点
【发布时间】:2021-03-31 13:08:57
【问题描述】:

我在谷歌上搜索了很多,但找不到任何答案。

我有一张这样的表格:

|身份证 |姓名 | X 坐标。 | Y坐标。 |

我有一张 512x512 的自定义图片(基本上是一张地图),我需要根据 X/Y 坐标绘制点。

有没有办法在 Google Sheet 上做到这一点?我愿意接受任何可能的解决方案(甚至包括 html 在内的解决方案)

提前致谢!

编辑。这是我需要的:

我的表

| ID | Name | X Coord. | Y Coord. |
| 1  | AAA  |    0     |    0     |
| 2  | BBB  |   512    |   512    |
| 3  | CCC  |   256    |   256    |

我的照片

【问题讨论】:

  • 我无法从I have a custom picture (it's basically a map) 512x512 and I need to plot the points based on the X/Y Coords. 想象你的目标。我为此道歉。您能否提供您期望的示例输入和输出?
  • 我更新了问题! @田池
  • 感谢您回复并添加更多信息。从您更新的问题中,我提出了一个答案作为解决方法。你能确认一下吗?如果这不是您期望的方向,我深表歉意。

标签: google-apps-script google-sheets plot draw


【解决方案1】:

我相信你目前的情况和你的目标如下。

  • 您有一个 512 x 512 像素的图像。
    • 图片文件已放入您的 Google 云端硬盘。
  • 您希望通过从电子表格中的“C”和“D”列检索到的坐标在图像上绘制点。
  • 您希望将从“B”列检索到的文本放入。
  • 您希望使用 Google Apps 脚本实现此目的。

问题和解决方法:

不幸的是,在当前阶段,没有直接编辑图像并将文本和形状放入 Google Apps Script 的方法中的方法。所以在这种情况下,需要使用变通方法。

幸运的是,我在我的博客中发表了一篇关于“使用 Google Apps 脚本在图像上插入文本”的报告。 Ref 我认为在您的情况下,这可能可以用作解决方法。此变通方法的流程如下。

  1. 从图像文件中检索 blob。
  2. 检索图像大小。
    • 在这种情况下,使用了 ImgApp 的 Google Apps 脚本库。
  3. 创建新的 Google 幻灯片,页面大小与图像大小相同。
    • 在这种情况下,使用 DocsServiceApp 的 Google Apps 脚本库。
  4. 插入图片。
  5. 从电子表格中检索坐标。
  6. 使用 Google 幻灯片的坐标绘制点。
  7. 从 Google 幻灯片中检索图像块。

用法:

在这种情况下,它假定您已经拥有 Google Apps 脚本项目。如果您没有 Google Apps 脚本项目,请创建它。例如,您也可以通过 Google 电子表格上的脚本编辑器创建它。

1。安装 Google Apps 脚本库。

请安装以下 Google Apps 脚本库。安装库的官方文档可以在here查看。

  1. ImgApp
    • 您可以在here看到安装库的项目密钥。
  2. DocsServiceApp
    • 您可以在here看到安装库的项目密钥。

2。启用 API:

Please enable Google Slides API at Advanced Google services.

3。示例脚本:

请将以下脚本复制并粘贴到 Google Apps Script 的脚本编辑器中,并设置变量。

function myFunction() {
  const fileIdOfImage = "###"; // Please set the fileID of image.
  const spreadsheetId = "###"; // Please set the Spreadsheet ID of image.
  const sheetName = "Sheet1"; // Please set the sheet name.
  const outputFilename = "sample.png"; // Please set the output image filename.

  // 1. Retrieve blob from an image file.
  const blob = DriveApp.getFileById(fileIdOfImage).getBlob();

  // 2. Retrieve the image size.
  const { width, height } = ImgApp.getSize(blob);

  // 3. Create new Google Slides with the page size which is the same with the image size.
  const object = { title: "temp", width: { unit: "pixel", size: width }, height: { unit: "pixel", size: height } };
  const id = DocsServiceApp.createNewSlidesWithPageSize(object);

  // 4. Insert the image.
  const s = SlidesApp.openById(id);
  const slide = s.getSlides()[0];
  const image = slide.insertImage(blob);

  // 5. Retrieve the coordinates from Spreadsheet.
  const sheet = SpreadsheetApp.openById(spreadsheetId).getSheetByName(sheetName);
  const values = sheet.getRange("B2:D" + sheet.getLastRow()).getValues();

  // 6. Plot the points using the coordinates to Google Slides.
  const pointSize = 8;
  const fontSize = 10;
  const boxSize = 60;
  values.forEach(([v, x, y]) => {
    let px = (x / 1.33333) - (pointSize / 2);
    let py = (-1 * (y - height) / 1.33333) - (pointSize / 2);
    slide.insertShape(SlidesApp.ShapeType.ELLIPSE, px, py, pointSize, pointSize).getFill().setSolidFill("#ff0000");
    const textBox = slide.insertTextBox(v, px - (boxSize / 2) + (pointSize / 2), py - (boxSize / 2) + (pointSize / 2), boxSize, boxSize);
    textBox.setContentAlignment(SlidesApp.ContentAlignment[(px < 0 && py > 0) || (px > 0 && py > 0) ? "TOP" : "BOTTOM"]);
    const text = textBox.getText();
    text.getParagraphStyle().setParagraphAlignment(SlidesApp.ParagraphAlignment[(px > 0 && py < 0) || (px > 0 && py > 0) ? "START" : "END"]);
    text.getTextStyle().setFontSize(fontSize);
  });
  slide.group([image, ...slide.getShapes()]);
  s.saveAndClose();

  // 7. Retrieve the image blob from Google Slides.
  const obj = Slides.Presentations.Pages.getThumbnail(id, slide.getObjectId(), {"thumbnailProperties.thumbnailSize": "LARGE"});
  const outputBlob = UrlFetchApp.fetch(obj.contentUrl.replace("=s1600", "=s" + width)).getBlob().setName(outputFilename);
  DriveApp.createFile(outputBlob);
  DriveApp.getFileById(id).setTrashed(true);
}
  • 运行上述脚本时,从fileIdOfImage 的图像文件中检索图像块,并从spreadsheetIdsheetName 的电子表格中检索用于绘制点的坐标。然后,将它们合并并输出为outputFilename的图像文件。
  • 当你想改变字体大小和点大小时,请调整fontSizepointSizeboxSize的变量。

输入和输出图像示例。

输入数据示例。

电子表格:

图片:

此图像大小为 512 x 512 像素。

样本输出数据。

当上述输入数据与上述示例脚本一起使用时,会得到以下结果。该图的原点是左下角。这是来自您的示例图片。

注意:

  • 这是一个简单的示例脚本。所以请根据您的实际情况进行修改。

参考资料:

【讨论】:

  • @Yariet 感谢您的回复和测试。我很高兴你的问题得到了解决。也谢谢你。
猜你喜欢
  • 1970-01-01
  • 2019-08-27
  • 1970-01-01
  • 1970-01-01
  • 2014-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多