浏览器图像调整大小,优于最高 PIL 质量
Posted
技术标签:
【中文标题】浏览器图像调整大小,优于最高 PIL 质量【英文标题】:Browser image resize, better than highest PIL quality 【发布时间】:2019-03-19 15:32:49 【问题描述】:序言
我正在将来自 Django 后端的图像显示到 26 x 26px
大小(css)<img>
标记中。
我可以通过两种方式做到这一点:
-
将后端(枕头)的大小调整为
26x26
(裁剪以保持纵横比)
发送完整尺寸的图片,让 CSS 进行尺寸调整
问题
使用LANCZOS
算法调整大小并将结果保存为 100% 质量的 Jpg,显示的图像看起来比浏览器调整大小的图像差很多。
为什么会这样,有什么办法可以解决吗?
编辑:在 Retina 显示器上测试
编辑:Bicubic 看起来与 Lanczos 非常相似
【问题讨论】:
你能试试双三次插值并显示结果吗? 我相信 LANCZOS 算法是用于放大图像的。我建议使用PIL.Image.BICUBIC
。
已编辑。如果有的话,它看起来有点糟糕。
PIL 文档说他们的 lanczos 算法存在导致质量差的错误。由于某种原因,与 Matplotlib 的 interpolation="lanczos" 以及我自己的基于 Numpy 的实现相比,Pillow 6.2.0 的 LANCZOS 实现仍然会产生非常模糊的放大。
【参考方案1】:
本文[1] 表示,Retina 显示器(高 DPI 显示器)将尝试在同一区域显示 2 倍以上的像素。也以像素为单位测量的区域,即您在 CSS 中实际声明的像素。
所以这就是我的困惑的来源。解决方案是生成两倍于显示大小的缩略图。
【讨论】:
【参考方案2】:根据我的经验,PIL/Pillow(以下简称为“Pillow”)在处理小图像时的行为可能与处理大图像时非常不同 - 不仅在调整大小操作方面,而且在一般情况下 - 但您不妨测试一下所有Pillow 提供的方法,例如:
# q.v. https://gist.github.com/fish2000/d85befaf289c664b6a9f44d1b56e57da#file-asscat-py-L129-L134
from PIL import Image
# q.v. PIL.Image constants of the same (yet uppercased) names:
interpolation_methods = frozenset(
"box",
"bilinear", "bicubic",
"hamming", "lanczos",
"nearest" )
def interpol(name):
""" Return a PIL/Pillow image interpolation method constant by name """
return getattr(Image, name.upper())
size = (26, 26)
avatar = Image.open(…) # load your source avatar image
methods = (interpol(method) for method in interpolation_methods)
scaled = (avatar.resize(size, resample=method) for method in methods)
# you can save these out for more granular inspection:
previews = list(scaled)
for preview in previews:
preview.show()
...请记住,Image.NEAREST
可以为小尺寸产生令人惊讶的好结果——而且 Pillow 绝不是 Adobe® Photoshop™,因此不能真正负责复制您的结果可能已经不一样了。
但是,不管是否使用 CSS(或任何其他基于客户端的方法)进行扩展:如果可能,最好通过线路发送更少的字节 - 但这并不意味着它可以做不完。就个人而言,我是一个完美主义者,但如果时间或金钱紧迫,我不会对此感到迂腐。
【讨论】:
“总是最好通过线路发送更少的字节”,这是我为后端调整大小而烦恼的唯一原因。我讨厌小头像图像的扫描线加载。以上是关于浏览器图像调整大小,优于最高 PIL 质量的主要内容,如果未能解决你的问题,请参考以下文章