马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
本帖最后由 被诅咒的章鱼 于 2025-8-23 10:34 编辑
这两天偶然研究到我之前写的一些东西,然后有一个需求是“获取一张图片的长和宽”。
两个月前我使用的方法是用pygame把这个图片load一下,使用的是gamedir+相对路径的方式,但是安卓端的图片不存放在gamedir里,所以这件事之后以我手动填写图片的长宽结束。
不过这两天又提起这件事,我找到了一些新的解法,刚好几年前有人问过,遂做一个解答。
这里介绍两种办法
第一种:renpy.image_size()
文档连接在这里
用法很简单,入参是图片的路径,返回值是图片的长和宽,没有太多好说的。
第二种:Image("path/image").load().get_size()
这个是今早重新翻源码的时候发现的办法,注意入参是在Image后面入参,而不是在load或者get_size里,返回值同样是图片的长和宽。
然后说一下这两种方法的区别,主要区别是:第一种方法运行的相当慢,因为它是从磁盘读取文件(文档里也明确说了),而Image函数大概是有图像缓存,因此运行速度要比第一种方法快好几个数量级。
然后我们在这里讲一下第二种方法的原理吧:
当Image函数的入参是一个basestring(字符串)的时候,他会返回一个Image对象
renpy/display/im.py文件,
[RenPy] 纯文本查看 复制代码 def image():
if:
# 省略if的内容
pass
elif isinstance(arg, basestring):
return Image(arg, **properties)
这个Image对象里有一个load函数
renpy/display/im.py文件,
[RenPy] 纯文本查看 复制代码 class Image(ImageBase):
def load(self, unscaled=False):
# Unscaled is no longer used.
cache.add_load_log(self.filename)
try:
try:
filelike = renpy.loader.load(self.filename, directory="images")
filename = self.filename
force_size = None
except renpy.webloader.DownloadNeeded as e:
renpy.webloader.enqueue(e.relpath, 'image', self.filename)
# temporary placeholder:
filelike = open(os.path.join('_placeholders', e.relpath), 'rb')
filename = 'use_png_format.png'
force_size = e.size
with filelike as f:
surf = renpy.display.pgrender.load_image(f, filename)
if force_size is not None:
# avoid size-related exceptions (e.g. Crop on a smaller placeholder)
surf = renpy.display.pgrender.transform_scale(surf, force_size)
if self.is_svg:
width, height = surf.get_size()
width = int(width * renpy.display.draw.draw_per_virt * self.dpi / 96)
height = int(height * renpy.display.draw.draw_per_virt * self.dpi / 96)
if filename != self.filename:
# This should only run for placeholder images.
surf = renpy.display.pgrender.transform_scale(surf, (width, height))
else:
filelike = renpy.loader.load(self.filename, directory="images")
with filelike as f:
surf = renpy.display.pgrender.load_image(filelike, filename, size=(width, height))
return surf
在不报错的情况下会返回一个叫surf的东西
那么这个surf是什么呢?实际上我们没有必要知道,因为从代码中可以看出它是load_image这个函数的返回值,如果我们一直往前看的话就会牵扯到更多的文件,在这里没有必要了,因为源码中其实明确告诉了我们surf有一个叫做get_size的方法,它会返回surf的长和宽,这就足够了
所以以上就是获取图片大小的两种办法,经过测试加载一张4k的截屏文件,renpy.image_size()用时大概0.15秒左右,而Image几乎是一瞬间就能返回值……
|