当前位置: 首页 > 面试题库 >

使用PIL将图像转换为特定的调色板而无需抖动

连厉刚
2023-03-14
问题内容

我正在尝试使用Pillow库(Python图像库,PIL)将PNG格式的RGB图像转换为使用特定的索引调色板。但是我想使用“四舍五入到最接近的颜色”方法而不是抖动进行转换,因为图像是像素图,抖动会扭曲区域的轮廓,并给打算平坦的区域增加噪声。

我试过了Image.Image.paste(),它使用了四种指定的颜色,但是产生了抖动的图像:

from PIL import Image
oldimage = Image.open("oldimage.png")
palettedata = [0, 0, 0, 102, 102, 102, 176, 176, 176, 255, 255, 255]
newimage = Image.new('P', oldimage.size)
newimage.putpalette(palettedata * 64)
newimage.paste(oldimage, (0, 0) + oldimage.size)
newimage.show()

Image.Image.quantize()按照pictu回答类似问题的方式进行了尝试,但是它也会引起抖动:

from PIL import Image
palettedata = [0, 0, 0, 102, 102, 102, 176, 176, 176, 255, 255, 255]
palimage = Image.new('P', (16, 16))
palimage.putpalette(palettedata * 64)
oldimage = Image.open("School_scrollable1.png")
newimage = oldimage.quantize(palette=palimage)
newimage.show()

我试过了Image.Image.convert(),它转换了图像而没有抖动,但是它包含了指定颜色以外的颜色,大概是因为它使用了Web调色板或自适应调色板

from PIL import Image
oldimage = Image.open("oldimage.png")
palettedata = [0, 0, 0, 102, 102, 102, 176, 176, 176, 255, 255, 255]
expanded_palettedata = palettedata * 64
newimage = oldimage.convert('P', dither=Image.NONE, palette=palettedata)
newimage.show()

如何自动将图像转换为特定的调色板而不抖动?我想避免像John La
Rooy的回答和评论中所建议的那样处理Python中每个单独像素的解决方案,因为事实证明,我以前的涉及Python编写的内部循环的解决方案对于大型图像来说明显很慢。


问题答案:

用C实现的PIL部分在PIL._imaging模块中,您也可以在Image.core之后使用from PIL import Image。当前版本的Pillow为每个PIL.Image.Image实例赋予一个名为成员的成员im,该成员是实例的成员,该成员ImagingCore定义在PIL._imaging。您可以使用列出其方法help(oldimage.im),但是这些方法本身在Python中均未记录。

对象的convert方法ImagingCore中实现_imaging.c。它需要一到三个参数,并创建一个新的ImagingCore对象(称为Imaging_Type内部_imaging.c)。

  • mode(必需):模式字符串(例如"P"
  • dither (可选,默认为0):PIL传递0或1
  • paletteimage(可选):ImagingCore带有调色板的

我面临的问题是,quantize()dist- packages/PIL/Image.py力的dither参数1。所以我把副本quantize()方法出来,改变了这一切。这可能在将来的Pillow版本中不起作用,但如果不能,则他们很可能会实现“quantize()承诺的更高版本中的扩展量化器接口

#!/usr/bin/env python3
from PIL import Image

def quantizetopalette(silf, palette, dither=False):
    """Convert an RGB or L mode image to use a given P image's palette."""

    silf.load()

    # use palette from reference image
    palette.load()
    if palette.mode != "P":
        raise ValueError("bad mode for palette image")
    if silf.mode != "RGB" and silf.mode != "L":
        raise ValueError(
            "only RGB or L mode images can be quantized to a palette"
            )
    im = silf.im.convert("P", 1 if dither else 0, palette.im)
    # the 0 above means turn OFF dithering

    # Later versions of Pillow (4.x) rename _makeself to _new
    try:
        return silf._new(im)
    except AttributeError:
        return silf._makeself(im)

palettedata = [0, 0, 0, 102, 102, 102, 176, 176, 176, 255, 255, 255]
palimage = Image.new('P', (16, 16))
palimage.putpalette(palettedata * 64)
oldimage = Image.open("School_scrollable1.png")
newimage = quantizetopalette(oldimage, palimage, dither=False)
newimage.show()


 类似资料:
  • 问题内容: 我正在尝试将图像从转换为格式。我正在使用。这是到目前为止我一直尝试的。 但我认为图像未转换为CV格式。窗口向我显示了一个大的棕色图像。将图像从转换为格式时,我在哪里出错? 另外,为什么我需要输入访问功能? 问题答案: 用这个:

  • 问题内容: 我正在尝试通过和不通过将字节数组写入磁盘来验证字节数组,然后使用来打开它。我看了and方法,但是我需要图像的大小(只有将字节流转换为图像时才能得到)。 我的读取功能如下所示: 然后作为基本测试,我尝试将字节数组转换为图像: 如果有人知道我在做什么错,或者有一种更优雅的方法将这些字节转换为对我有真正帮助的图像。 PS:我以为我需要字节数组,因为我对字节进行了处理(使它们出现图像错误)。这

  • 问题内容: 我有一个PIL图像格式的图像。我需要将其转换为字节数组。 现在我需要作为字节数组。 问题答案: 感谢大家的帮助。 终于解决了!! 这样,我不必将裁剪后的图像保存在硬盘中,并且能够从PIL裁剪后的图像中检索字节数组。

  • 问题内容: 我正在使用PIL1.1.7在Python 2.7中制作图像处理器的原型,我希望所有图像都以JPG结尾。输入文件类型将包括透明和不透明的tiff,gif,png。我一直在尝试结合两个脚本,发现1.将其他文件类型转换为JPG和2.通过创建空白的白色图像并将原始图像粘贴在白色背景上来消除透明度。我的搜索被那些寻求产生或保持透明度的人们所困扰,而不是相反。 我目前正在与此: 这两个脚本都是独立

  • 问题内容: 好吧,我想将PIL图像对象来回转换为numpy数组,因此我可以实现比对象所允许的更快的逐像素转换。我想出了如何通过以下方式将像素信息放置在有用的3D numpy数组中: 但是,在完成所有出色的转换之后,我似乎无法弄清楚如何将其重新加载到PIL对象中。我知道该方法,但似乎无法使其正常工作。 问题答案: 你并不是在说行为不正确。我假设你在做 这是因为需要一个元组序列,并且你要给它一个num

  • 问题内容: 我有一幅颜色为BGR的图像。如何转换我的PIL图像,以有效地交换每个像素的B和R元素? 问题答案: 假设没有阿尔法谱带,难道就这么简单吗? 编辑: 嗯…似乎PIL在这方面有一些错误…似乎不适用于最新版本的PIL(1.1.7)。它可能(?)仍可与1.1.6一起使用,但是…