gpt4 book ai didi

python - 如何使用 Python 图像库将任何图像转换为 4 色调色板图像?

转载 作者:太空狗 更新时间:2023-10-29 17:56:35 26 4
gpt4 key购买 nike

我有一个支持 4 色图形的设备(很像过去的 CGA)。

我想使用 PIL读取图像并使用我的 4 色调色板(红色、绿色、黄色、黑色)转换它,但我不知道它是否可能。我发现一些邮件列表存档帖子似乎暗示其他人已经尝试这样做但失败了。

一个简单的 python 示例将不胜感激!

如果你添加一些东西,然后将图像转换为字节字符串,其中每个字节代表 4 个像素的数据(每两位代表从 0 到 3 的颜色)

最佳答案

首先:您的四种调色板(黑色、绿色、红色、黄色)没有蓝色成分。因此,您必须接受您的输出图像将很难接近输入图像,除非没有蓝色组件开始。

试试这段代码:

import Image

def estimate_color(c, bit, c_error):
c_new= c - c_error
if c_new > 127:
c_bit= bit
c_error= 255 - c_new
else:
c_bit= 0
c_error= -c_new
return c_bit, c_error

def image2cga(im):
"Produce a sequence of CGA pixels from image im"
im_width= im.size[0]
for index, (r, g, b) in enumerate(im.getdata()):
if index % im_width == 0: # start of a line
r_error= g_error= 0
r_bit, r_error= estimate_color(r, 1, r_error)
g_bit, g_error= estimate_color(g, 2, g_error)
yield r_bit|g_bit

def cvt2cga(imgfn):
"Convert an RGB image to (K, R, G, Y) CGA image"
inp_im= Image.open(imgfn) # assume it's RGB
out_im= Image.new("P", inp_im.size, None)
out_im.putpalette( (
0, 0, 0,
255, 0, 0,
0, 255, 0,
255, 255, 0,
) )
out_im.putdata(list(image2cga(inp_im)))
return out_im

if __name__ == "__main__":
import sys, os

for imgfn in sys.argv[1:]:
im= cvt2cga(imgfn)
dirname, filename= os.path.split(imgfn)
name, ext= os.path.splitext(filename)
newpathname= os.path.join(dirname, "cga-%s.png" % name)
im.save(newpathname)

这将创建一个 PNG 调色板图像,其中只有前四个调色板条目设置为您的颜色。此示例图片:

成为

获取 image2cga 的输出(产生一个 0-3 值的序列)并将每四个值打包到一个字节是微不足道的。

如果您需要有关代码功能的帮助,请询问,我会解释。

EDIT1:不要重新发明轮子

当然,事实证明我太热情了——正如 Thomas 发现的那样——Image.quantize 方法可以将调色板图像作为参数并进行量化,结果比我上面的临时方法好得多:

def cga_quantize(image):
pal_image= Image.new("P", (1,1))
pal_image.putpalette( (0,0,0, 0,255,0, 255,0,0, 255,255,0) + (0,0,0)*252)
return image.convert("RGB").quantize(palette=pal_image)

EDIT1, cont: 将像素打包成字节

对于“附加值”,下面是生成打包字符串的代码(每字节 4 个像素):

import itertools as it

# setup: create a map with tuples [(0,0,0,0)‥(3,3,3,3)] as keys
# and values [chr(0)‥chr(255)], because PIL does not yet support
# 4 colour palette images

TUPLE2CHAR= {}

# Assume (b7, b6) are pixel0, (b5, b4) are pixel1…
# Call it "big endian"

KEY_BUILDER= [
(0, 64, 128, 192), # pixel0 value used as index
(0, 16, 32, 48), # pixel1
(0, 4, 8, 12), # pixel2
(0, 1, 2, 3), # pixel3
]
# For "little endian", uncomment the following line
## KEY_BUILDER.reverse()

# python2.6 has itertools.product, but for compatibility purposes
# let's do it verbosely:
for ix0, px0 in enumerate(KEY_BUILDER[0]):
for ix1, px1 in enumerate(KEY_BUILDER[1]):
for ix2, px2 in enumerate(KEY_BUILDER[2]):
for ix3, px3 in enumerate(KEY_BUILDER[3]):
TUPLE2CHAR[ix0,ix1,ix2,ix3]= chr(px0+px1+px2+px3)

# Another helper function, copied almost verbatim from itertools docs
def grouper(n, iterable, padvalue=None):
"grouper(3, 'abcdefg', 'x') --> ('a','b','c'), ('d','e','f'), ('g','x','x')"
return it.izip(*[it.chain(iterable, it.repeat(padvalue, n-1))]*n)

# now the functions
def seq2str(seq):
"""Takes a sequence of [0..3] values and packs them into bytes
using two bits per value"""
return ''.join(
TUPLE2CHAR[four_pixel]
for four_pixel in grouper(4, seq, 0))

# and the image related function
# Note that the following function is correct,
# but is not useful for Windows 16 colour bitmaps,
# which start at the *bottom* row…
def image2str(img):
return seq2str(img.getdata())

关于python - 如何使用 Python 图像库将任何图像转换为 4 色调色板图像?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/236692/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com