在 Raspbian 上使用 PyPNG 有选择地更改 png 像素
Changing png pixels selectively with PyPNG on Raspbian
我正在尝试遍历我用 Raspberry pi 的相机拍摄的 png 的每个像素,并有选择地更改高于或低于特定 r、g 或 b 值的像素。我知道这是一个非常低效的算法,我只是想掌握 python 脚本的窍门。我的代码基于问题中的@Constantin 代码:How can I read the RGB value of a given pixel in Python?
他的代码如下。
import png, array
point = (2, 10) # coordinates of pixel to be painted red
reader = png.Reader(filename='image.png')
w, h, pixels, metadata = reader.read_flat()
pixel_byte_width = 4 if metadata['alpha'] else 3
#The line below is, I think wrong. I'll point out the what I did in my code below
pixel_position = point[0] + point[1] * w
new_pixel_value = (255, 0, 0, 0) if metadata['alpha'] else (255, 0, 0)
pixels[
pixel_position * pixel_byte_width :
(pixel_position + 1) * pixel_byte_width] = array.array('B', new_pixel_value)
output = open('image-with-red-dot.png', 'wb')
writer = png.Writer(w, h, **metadata)
writer.write_array(output, pixels)
output.close()
我把它改成这样:
#!/usr/bin/python
import png, array
reader = png.Reader(filename='test.png')
w, h, pixels, metadata = reader.read_flat()
pixel_byte_width = 4 if metadata['alpha'] else 3
for x in range(w):
for y in range(h):
point_index = x+(y-1)*w#This is the bit that I said I'd fix above.
r = pixels[point_index * pixel_byte_width + 0]
g = pixels[point_index * pixel_byte_width + 1]
b = pixels[point_index * pixel_byte_width + 2]
pixel = pixels[point_index * pixel_byte_width :
(point_index+1) * pixel_byte_width]
#Above we have all the info about each byte, and below is our devious plan
new_pixel = (0, 0, 0, 0) if metadata['alpha'] else (0, 0, 0)
#if g > 175:
pixel = array.array('B', new_pixel)
output = open('test_edited.png', 'wb')
writer = png.Writer(w, h, **metadata)
writer.write_array(output, pixels)
output.close()
pi 想了一两分钟,然后我可以打开一个完全相同的新 png。我的脚本缺少什么,或者是否有比 python 更好的平台来在 Raspbian Jessie 上逐个像素地做事?
非常感谢!
如果您对新库持开放态度,我建议 pillow
,Python 成像库 (PIL) 的后继者。它更简单,不限于 png。 Documentation is here.
from PIL import Image, ImageDraw
img = Image.open('image.png')
img = img.convert("RGB") # Make sure we are in 8-bit RGB
draw = ImageDraw.Draw(img)
for y in range(img.height):
for x in range(img.width):
# getpixel returns a tuple with (R, G, B)
if img.getpixel((x, y))[1] > 175: # If too green
draw.point((x,y), '#000000') # Color syntax is CSS-like
img.save('test_edited.png', 'PNG')
# You can also use img.show() in a graphical environment
我正在尝试遍历我用 Raspberry pi 的相机拍摄的 png 的每个像素,并有选择地更改高于或低于特定 r、g 或 b 值的像素。我知道这是一个非常低效的算法,我只是想掌握 python 脚本的窍门。我的代码基于问题中的@Constantin 代码:How can I read the RGB value of a given pixel in Python? 他的代码如下。
import png, array
point = (2, 10) # coordinates of pixel to be painted red
reader = png.Reader(filename='image.png')
w, h, pixels, metadata = reader.read_flat()
pixel_byte_width = 4 if metadata['alpha'] else 3
#The line below is, I think wrong. I'll point out the what I did in my code below
pixel_position = point[0] + point[1] * w
new_pixel_value = (255, 0, 0, 0) if metadata['alpha'] else (255, 0, 0)
pixels[
pixel_position * pixel_byte_width :
(pixel_position + 1) * pixel_byte_width] = array.array('B', new_pixel_value)
output = open('image-with-red-dot.png', 'wb')
writer = png.Writer(w, h, **metadata)
writer.write_array(output, pixels)
output.close()
我把它改成这样:
#!/usr/bin/python
import png, array
reader = png.Reader(filename='test.png')
w, h, pixels, metadata = reader.read_flat()
pixel_byte_width = 4 if metadata['alpha'] else 3
for x in range(w):
for y in range(h):
point_index = x+(y-1)*w#This is the bit that I said I'd fix above.
r = pixels[point_index * pixel_byte_width + 0]
g = pixels[point_index * pixel_byte_width + 1]
b = pixels[point_index * pixel_byte_width + 2]
pixel = pixels[point_index * pixel_byte_width :
(point_index+1) * pixel_byte_width]
#Above we have all the info about each byte, and below is our devious plan
new_pixel = (0, 0, 0, 0) if metadata['alpha'] else (0, 0, 0)
#if g > 175:
pixel = array.array('B', new_pixel)
output = open('test_edited.png', 'wb')
writer = png.Writer(w, h, **metadata)
writer.write_array(output, pixels)
output.close()
pi 想了一两分钟,然后我可以打开一个完全相同的新 png。我的脚本缺少什么,或者是否有比 python 更好的平台来在 Raspbian Jessie 上逐个像素地做事?
非常感谢!
如果您对新库持开放态度,我建议 pillow
,Python 成像库 (PIL) 的后继者。它更简单,不限于 png。 Documentation is here.
from PIL import Image, ImageDraw
img = Image.open('image.png')
img = img.convert("RGB") # Make sure we are in 8-bit RGB
draw = ImageDraw.Draw(img)
for y in range(img.height):
for x in range(img.width):
# getpixel returns a tuple with (R, G, B)
if img.getpixel((x, y))[1] > 175: # If too green
draw.point((x,y), '#000000') # Color syntax is CSS-like
img.save('test_edited.png', 'PNG')
# You can also use img.show() in a graphical environment