简体   繁体   English

更新 PIL 中的像素颜色后图像未保存

[英]Image not saving after updating pixel color in PIL

I've generated barcode images in PNG format using HuBarcode, and have modified them to add a border of rgb(150, 150, 150) in hopes of accessing the pixels of that color to change them.我已经使用 HuBarcode 生成了 PNG 格式的条形码图像,并修改了它们以添加rgb(150, 150, 150)边框,希望能够访问该颜色的像素来更改它们。 I can access the pixel and get confirmation via print that the color is being changed, but when I open the image file, nothing has changed.我可以访问像素并通过print确认颜色正在更改,但是当我打开图像文件时,没有任何变化。 The pixels are still rgb(150, 150, 150) .像素仍然是rgb(150, 150, 150) Here's a code snippet I'm using.这是我正在使用的代码片段。 I can add more of my code if it will be helpful:如果有帮助,我可以添加更多代码:

def add_colored_border(self, barcode):
  img = Image.open(barcode)
  img = img.convert('RGB')
  px = img.load()
  for x in range(img.size[0]):
    for y in range(img.size[1]):
      pixel = px[x, y]
      if pixel == (150, 150, 150):  
        pixel = (0, 0, 255)
  img.save('testing.png')

You need to copy the modified pixel value back into the pixel access object.您需要将修改后的像素值复制回像素访问对象。 Eg,例如,

if px[x, y] == (150, 150, 150):
    px[x, y] = (0, 0, 255)

There's an example in the old PIL docs for Image.load() .在旧的 PIL 文档中有一个Image.load()的例子。

If you're modifying a lot of pixels, you may wish to use getdata() and putdata() .如果您要修改大量像素,您可能希望使用getdata()putdata() Those links are to the docs of the new fork of PIL known as Pillow, but those functions are also available in the old PIL.这些链接指向 PIL 的新分支(称为 Pillow)的文档,但这些功能在旧 PIL 中也可用。


pixel = px[x, y]
if pixel == (150, 150, 150):  
    pixel = (0, 0, 255)

doesn't do what you want because pixel = (0, 0, 255) creates a new tuple and binds that to the name pixel , it doesn't modify the tuple in the PixelAccess object at px[x, y] .不会做你想做的事,因为pixel = (0, 0, 255)创建一个新元组并将其绑定到名称pixel ,它不会修改 PixelAccess 对象中px[x, y]的元组。

Tuples are immutable, so they can't be modified - if you want to change them you need to replace them with a new tuple.元组是不可变的,所以它们不能被修改——如果你想改变它们,你需要用一个新的元组替换它们。 Python does let you modify lists in a way similar to what you were trying, since lists are mutable. Python确实允许您以类似于您尝试的方式修改列表,因为列表可变的。 To make this work, we need to use a list of lists, we can't use a simple list of integers or strings since Python integers and strings are immutable.为了完成这项工作,我们需要使用一个列表列表,我们不能使用一个简单的整数或字符串列表,因为 Python 整数和字符串是不可变的。

a = [[i] for i in range(5)]
print a
b = a[2]
print b
b[0] = 7
print b
print a

output输出

[[0], [1], [2], [3], [4]]
[2]
[7]
[[0], [1], [7], [3], [4]]  

This works because I'm modifying the contents of b .这是有效的,因为我正在修改b的内容。 But if I do但如果我这样做

c = a[3]
c = [11]
print a    

output输出

[[0], [1], [7], [3], [4]]

Now a is unchanged.现在a不变。 The assignment to c binds a new list to c , it doesn't touch the a[3] object that c was previously bound to.c的赋值将一个新列表绑定到c ,它不会触及c之前绑定到的a[3]对象。

For more on this important topic please see the excellent illustrated article Facts and myths about Python names and values by SO member Ned Batchelder.有关此重要主题的更多信息,请参阅 SO 成员 Ned Batchelder 出色的插图文章Facts and myths about Python names and values

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM