代码之家  ›  专栏  ›  技术社区  ›  Dan P

使用Raspbian上的PyPNG有选择地更改png像素

  •  0
  • Dan P  · 技术社区  · 9 年前

    我正在尝试浏览我用复盆子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进行逐像素处理吗?

    非常感谢!

    1 回复  |  直到 7 年前
        1
  •  0
  •   Marc J    9 年前

    如果你对新图书馆开放,我建议 pillow ,Python Imaging Library(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