如何减小gt::ggplot_image()输出图片URI大小适配Google Slides
减小
gt::ggplot_image()输出图片URI体积的实用方法 gt::ggplot_image() 默认生成300dpi的PNG格式base64 data URI,base64编码本身就会比原始图片二进制体积大1/3左右,默认参数下超出Google Slides接口2KB的限制是很常见的情况,按下面两步处理基本都能解决:
方法1:R端直接调生成参数,从源头控体积
不需要额外依赖,直接给ggplot_image()传入自定义的绘图设备参数,把输出规格压到实际使用的最小值就行:
- 尺寸按幻灯片里占位符的实际大小设,别留冗余,单位是英寸
- dpi降到72就够,这是屏幕显示的标准分辨率,比默认300dpi的印刷级分辨率体积小70%以上,投出来完全不会糊
- 把默认的PNG格式换成JPEG,质量设为60-70,肉眼基本看不出差异,体积还能再砍一半
示例代码:
library(ggplot2) # 原绘图代码,修正了示例里的语法错误 my_plot <- ggplot(iris) + geom_histogram(aes(x = Sepal.Width)) # 生成压缩后的URI my_plot_image <- gt::ggplot_image( plot_object = my_plot, width = 3, height = 2, dpi = 72, device = function(filename, width, height, res) { jpeg( filename, width = width, height = height, res = res, quality = 65, units = "in" ) } ) # 检查体积,绝大多数情况这一步就已经压到2KB以内了 object.size(my_plot_image)
如果测下来还是略超,小幅缩小尺寸、把JPEG质量降到55-60即可。
方法2:Python端二次压缩兜底
如果R端调完还是差一点,直接用你已经接好的reticulate调用Pillow做二次压缩就行,不用落地本地文件,直接处理URI字符串:
import base64 import io from PIL import Image def compress_slide_img(origin_uri, max_size=1900, init_quality=65): # 拆分data URI头部和base64内容 header, b64_content = origin_uri.split(",", 1) img_bytes = base64.b64decode(b64_content) quality = init_quality while True: img = Image.open(io.BytesIO(img_bytes)) buf = io.BytesIO() # 转RGB存JPEG,开启优化参数 img.convert("RGB").save(buf, format="JPEG", quality=quality, optimize=True) new_b64 = base64.b64encode(buf.getvalue()).decode() new_uri = f"data:image/jpeg;base64,{new_b64}" # 体积达标或者质量降到最低阈值就返回 if len(new_uri.encode("utf-8")) <= max_size or quality < 20: return new_uri quality -= 10
R端直接调用即可:
# 传入R生成的URI做压缩 compressed_uri <- py$compress_slide_img(my_plot_image) # 再走原来的插入逻辑就不会报错了 request_slide_image_insert("placeholder_in_template", compressed_uri)
内容的提问来源于stack exchange,提问作者Natalie O'Shea
相关产品推荐
相关产品推荐

