python将字符串中编码的12位图像转换为8位png

python将字符串中编码的12位图像转换为8位png,python,image,bits,Python,Image,Bits,我有一个从usb远地点摄像头读取的字符串,它是一个12位灰度图像,其中12位分别占据16位单词中最低的12位。 我想通过忽略最低的4位,从这个字符串创建一个8位png 我可以将其转换为16位图像,其中最高4位始终为零,使用PIL with import Image #imageStr is the image string #imageSize is the image size img=Image.fromstring("I", imageSize, imageStr, "raw", "

我有一个从usb远地点摄像头读取的字符串,它是一个12位灰度图像,其中12位分别占据16位单词中最低的12位。 我想通过忽略最低的4位,从这个字符串创建一个8位png

我可以将其转换为16位图像,其中最高4位始终为零,使用PIL with

import Image

#imageStr is the image string
#imageSize is the image size 

img=Image.fromstring("I", imageSize, imageStr, "raw", "I;16", 0,1)
img.save("MyImage.png", "PNG")
不管怎样,我可以做一些类似的事情来创建一个8位图像,而不必完全解包字符串,进行算术运算并生成一个新字符串吗

编辑:Wumps关于转换图像的评论给了我一个想法,我是通过

img = img.point(lambda i: i * 16, "L") #shifts by 4 bits and converts to 8-bit image.
#shifts by 4 bits and converts to 8-bit image
img = img.point(lambda i: i * 16, "L") 

谢谢你,我知道怎么做的唯一方法是:

data = numpy.fromstring(imageStr, numpy.uint16)
data >>= 4 # shift out four bits
data = numpy.array(data, dtype=numpy.uint8)
img = Image.fromarray(data.reshape(imageSize))
在principe中,PIL可以通过以下方式转换图像:

img = img.convert("L")
但问题是它无法将精度降低到8位(AFAIK),因此所有内容都将被剪裁为255:)


编辑:删除了中间字符串转换,它现在直接从numpy转换为PIL

Wump关于转换图像的评论给了我一个想法,我是通过

img = img.point(lambda i: i * 16, "L") #shifts by 4 bits and converts to 8-bit image.
#shifts by 4 bits and converts to 8-bit image
img = img.point(lambda i: i * 16, "L") 

感谢Wump

如何将8位PNG转换为4位PNG并保留调色板?