如何使用 imageio 调整图像大小以获得正确的 ICO 文件?

Posted

技术标签:

【中文标题】如何使用 imageio 调整图像大小以获得正确的 ICO 文件?【英文标题】:How to resize images with imageio to get proper ICO files? 【发布时间】:2021-04-21 02:39:11 【问题描述】:

我想从图像中保存 ICO 文件。 imageio 工作正常,但对于水平图像,它给了我一个错误。

这是我的代码:

import imageio
image = imageio.imread('image.png')
imageio.imwrite("image.ico", image)

【问题讨论】:

它给你带来了什么错误? @PrabhatKumarSahu 它没有给我任何错误。正方形转换后的图像打开时没有任何错误。但在水平图像的情况下,我无法打开它。请建议任何简单的方法来调整它们的大小 【参考方案1】:

我假设,您在打开生成的 ICO 文件时遇到问题,因为您使用的软件在打开 ICO 文件时只需要特定大小的方形图像!?不幸的是,imageio.imwrite 在输入非方形图像时,似乎只将较大的尺寸设置为默认的 16、24、... 像素来保存 ICO 文件。假设,我们有这样一张图片:

而且,我们有一些像这样的测试代码:

import imageio

# Read image
img_io = imageio.imread('image.png')

# Write ICO image
imageio.imwrite('image.ico', img_io)

生成的image.ico 有六个尺寸为16 x 1324 x 19 等的图像。

如果你想解决这个问题,你应该事先适当地调整你的图像大小以获得一个方形图像。实际上,使用imageio 时调整图像大小可能非常困难。有关详细信息,请参阅this recent Q&A。如果您只是想在不保持纵横比的情况下获得方形图像,您可能需要使用skimage.transform.resize

import imageio
from skimage.transform import resize

# Read image
img_io = imageio.imread('image.png')

# Resize image
img_io = resize(img_io, (200, 200))

# Write ICO image
imageio.imwrite('image.ico', img_io)

现在,生成的image.ico 有六张图像,尺寸为16 x 1624 x 24,依此类推。

如果您想保持图片的纵横比,则需要为图片添加适当的边框。在那个问题上有this helpful Q&A。您还可以仅使用 NumPy 添加精美的透明边框:

import imageio
import numpy as np

# Read image
img_io = imageio.imread('image.png')

# Add transparent borders to image
h, w = img_io.shape[:2]
img = np.zeros((w, w, 4), np.uint8)
img[30:h+30, :, :3] = img_io
img[30:h+30, :, 3] = 255

# Write ICO image
imageio.imwrite('image.ico', img)

现在,生成的image.ico 甚至有七个尺寸为16 x 16、...、256 x 256 的图像,因为修改后的图像已经足够大了。

----------------------------------------
System information
----------------------------------------
Platform:      Windows-10-10.0.16299-SP0
Python:        3.8.5
imageio:       2.9.0
NumPy:         1.19.5
scikit-image:  0.18.1
----------------------------------------

【讨论】:

【参考方案2】:

您可以使用reshape(),这样您的代码就可以变成类似

import imageio
image = imageio.imread('image.png')
M, N, C = image.shape
image = image.reshape((N, M, C)) # new shape here, I inverted M and N
imageio.imwrite("image.ico", image)

但要注意,像素数不能随reshape改变,即总数,在本例中为M * N,一旦重新整形,新的像素数必须相同。 想改的话可以用slicing,有例子in the documentation

【讨论】:

以上是关于如何使用 imageio 调整图像大小以获得正确的 ICO 文件?的主要内容,如果未能解决你的问题,请参考以下文章

图像没有相对于父 div 正确调整自身大小

如何使用自动布局调整情节提要的图像大小?

我是不是需要在代码而不是 IB 中调整下载图像的大小以获得更好的性能?

通过调整图像 url 将图像裁剪为正确大小

使用“flex:shrink”无法正确调整图像大小

如何动态调整电子邮件客户端中的图像大小?