python - Tkinter 以错误的比例保存画布
问题描述
我一直在 tkinter 中编写一个绘图程序,我的一个函数保存了最终的画布输出(我的图像在坐标 0,0 的画布上渲染)。我将画布作为 postscript 文件保存到内存中,并使用 PIL 将 postscript 作为 PNG 保存到磁盘(PIL 在保存 postscript 文件时使用 ghostscript)。但是,画布始终保存为其原始大小的 60.15%。我想将图像保存为原始大小的 100%,但我不知道如何在我的代码中执行此操作。
下面是我的代码:
"""my image is 256 x 256"""
ps = self.canvas_image.canvas.postscript(colormode='color', x = 0, y = 0,
height = 256, width = 256)
im = Image.open(BytesIO(ps.encode('utf-8')))
im.save(filepath, "PNG")
这是我的图像(顶部是原始图像,底部是保存的图像):
解决方案
原来 postscript 是一种矢量化的图像格式,图像在光栅化之前需要进行缩放。您的矢量比例可能与我的不同(我的是 0.60):如果此代码中的 DPI 比例因子不适合您,您可以在封装的 postscript 文件中查看比例因子
开放的EPS代码取自这篇文章: 如何在将python乌龟画布转换为位图时保持画布大小
我用这个代码片段来解决我的问题:
ps = self.canvas_image.canvas.postscript(colormode='color', x = 0, y = 0, height = 256, width = 256)
""" canvas postscripts seem to be saved at 0.60 scale, so we need to increase the default dpi (72) by 60 percent """
im = open_eps(ps, dpi=119.5)
#im = Image.open('test.ps')
im.save(filepath, dpi=(119.5, 119.5))
def open_eps(ps, dpi=300.0):
img = Image.open(BytesIO(ps.encode('utf-8')))
original = [float(d) for d in img.size]
scale = dpi/72.0
if dpi is not 0:
img.load(scale = math.ceil(scale))
if scale != 1:
img.thumbnail([round(scale * d) for d in original], Image.ANTIALIAS)
return img
推荐阅读
- f# - 我可以让返回类型随参数而变化,有点像 F# 中的 sprintf 吗?
- ios - 如何在客户班播放声音并识别声音播放结束
- javascript - 使用 javascript 或 jQuery 加载时激活复选框
- snowflake-cloud-data-platform - 我正在尝试运行使用具有相同查询 ID 的 python 连接器时创建的多个查询语句
- c# - 当被比较的两个字符串相同时,为什么会出现 md5 哈希不匹配?
- python - 如何使用可用的 python 库发出多个带有超时的异步请求并合并它们的返回值?
- javascript - 将静态属性输入到对象变量中
- terraform - 将 Terraform “data consul_keys ...”存储为文件?
- python - 计算python Pandas中行之间的数据时间差
- apache-spark - Spark BigQuery 连接器:BaseEncoding$DecodingException:无法识别的字符:0xa