2015-06-19 98 views
5

我可以从现有的图像文件使用如下的程序生成的像素值的列表:如何从Python中的像素值列表中创建PNG图像文件?

from PIL import Image 
image = Image.open("test.png") 
pixels = list(image.getdata()) 
width, height = image.size 
pixels = [pixels[i * width:(i + 1) * width] for i in xrange(height)] 

我怎么能转换的像素值回图像文件的这个名单?

回答

7

快速修复

首先,你需要让你的像素元组在一个单一的非嵌套列表:

pixels_out = [] 
for row in pixels: 
    for tup in row: 
     pixels_out.append(tup) 

接着,建立新的图像对象,使用输入图像的特性,以及把数据放入其中:

image_out = Image.new(image.mode,image.size) 
image_out.putdata(pixels_out) 

最后,保存:

image_out.save('test_out.png') 

根本问题

你的列表解析生成一个列表的列表,通过切片(i*width:(i+1)*width)产生的后者。你的理解可以更容易:pixels = [pixel for pixel in pixels]。显然,这会输出相同的列表pixels,但您可以使用该想法对像素执行操作,例如pixels = [operation(pixel) for pixel in pixels]

真的,你推翻了它。您不必管理图像尺寸。获取列表中的像素,然后将它们放入与putdata相同大小的图像中,可以保持这种顺序,因为它们通过PIL以相同方式线性化。

总之,这是你原来的片段应该是:

from PIL import Image 
image = Image.open("test.png") 
image_out = Image.new(image.mode,image.size) 

pixels = list(image.getdata()) 
image_out.putdata(pixels) 
image_out.save('test_out.png') 
0

你行你开罗。挺容易。

#!/usr/bin/python 

# Extracting pixels from an image ------ 
from PIL import Image 
image = Image.open("test.png") 
pixels = list(image.getdata()) 
width, height = image.size 
pixels = [pixels[i * width:(i + 1) * width] for i in xrange(height)] 


# Putting pixels back to an image ------ 

import cairo 

Width=len(pixels[0]) 
Height=len(pixels) 

surface = cairo.ImageSurface (cairo.FORMAT_ARGB32, Width, Height) 
context = cairo.Context (surface) 

y=0 
for row in pixels: 
    x=0 
    for rgb in row: 
     r=rgb[0] /255.0 
     g=rgb[1] /255.0 
     b=rgb[2] /255.0 
     context.set_source_rgb(r, g, b) 
     context.rectangle(x, y, 1, 1) 
     context.fill() 
     x+=1 
    y+=1 

surface.write_to_png ("out.png") # Output to PNG 
+1

这是一个整洁的想法,但如果您已经在使用PIL,则会矫枉过正。 – rjonnal

+1

OP没有指定他正在使用的内容。他问:“我如何从Python中的像素值列表创建PNG图像文件?”我给了一个答案。也许,他想以后重用这些数据?不允许或者什么? –

+1

开罗当然*允许*。我不确定它与数据重用有什么关系。 OP确实说明他/她正在使用PIL。 – rjonnal