如何在Python中读取给定像素的RGB值?

问题:如何在Python中读取给定像素的RGB值?

如果使用打开图像open("image.jpg"),假设我具有像素的坐标,如何获得像素的RGB值?

那么,我该怎么做呢?从空白图形开始,“写入”具有一定RGB值的像素?

如果不需要下载任何其他库,我会希望。

If I open an image with open("image.jpg"), how can I get the RGB values of a pixel assuming I have the coordinates of the pixel?

Then, how can I do the reverse of this? Starting with a blank graphic, ‘write’ a pixel with a certain RGB value?

I would prefer if I didn’t have to download any additional libraries.


回答 0

最好使用Python图像库来执行此操作,恐怕这是单独下载的。

执行所需操作的最简单方法是通过Image对象上load()方法,该方法返回一个像素访问对象,您可以像数组一样对其进行操作:

from PIL import Image

im = Image.open('dead_parrot.jpg') # Can be many different formats.
pix = im.load()
print im.size  # Get the width and hight of the image for iterating over
print pix[x,y]  # Get the RGBA Value of the a pixel of an image
pix[x,y] = value  # Set the RGBA Value of the image (tuple)
im.save('alive_parrot.png')  # Save the modified pixels as .png

或者,查看ImageDraw,它提供了更丰富的API用于创建图像。

It’s probably best to use the Python Image Library to do this which I’m afraid is a separate download.

The easiest way to do what you want is via the load() method on the Image object which returns a pixel access object which you can manipulate like an array:

from PIL import Image

im = Image.open('dead_parrot.jpg') # Can be many different formats.
pix = im.load()
print im.size  # Get the width and hight of the image for iterating over
print pix[x,y]  # Get the RGBA Value of the a pixel of an image
pix[x,y] = value  # Set the RGBA Value of the image (tuple)
im.save('alive_parrot.png')  # Save the modified pixels as .png

Alternatively, look at ImageDraw which gives a much richer API for creating images.


回答 1

使用Pillow(可与Python 3.X以及Python 2.7+一起使用),您可以执行以下操作:

from PIL import Image
im = Image.open('image.jpg', 'r')
width, height = im.size
pixel_values = list(im.getdata())

现在,您拥有所有像素值。如果是RGB或,可以通过读取其他模式im.mode。然后,您可以(x, y)通过以下方式获得像素:

pixel_values[width*y+x]

另外,您可以使用Numpy并调整数组的形状:

>>> pixel_values = numpy.array(pixel_values).reshape((width, height, 3))
>>> x, y = 0, 1
>>> pixel_values[x][y]
[ 18  18  12]

完整,易于使用的解决方案是

def get_image(image_path):
    """Get a numpy array of an image so that one can access values[x][y]."""
    image = Image.open(image_path, 'r')
    width, height = image.size
    pixel_values = list(image.getdata())
    if image.mode == 'RGB':
        channels = 3
    elif image.mode == 'L':
        channels = 1
    else:
        print("Unknown mode: %s" % image.mode)
        return None
    pixel_values = numpy.array(pixel_values).reshape((width, height, channels))
    return pixel_values

Using Pillow (which works with Python 3.X as well as Python 2.7+), you can do the following:

from PIL import Image
im = Image.open('image.jpg', 'r')
width, height = im.size
pixel_values = list(im.getdata())

Now you have all pixel values. If it is RGB or another mode can be read by im.mode. Then you can get pixel (x, y) by:

pixel_values[width*y+x]

Alternatively, you can use Numpy and reshape the array:

>>> pixel_values = numpy.array(pixel_values).reshape((width, height, 3))
>>> x, y = 0, 1
>>> pixel_values[x][y]
[ 18  18  12]

A complete, simple to use solution is

# Third party modules
import numpy
from PIL import Image


def get_image(image_path):
    """Get a numpy array of an image so that one can access values[x][y]."""
    image = Image.open(image_path, "r")
    width, height = image.size
    pixel_values = list(image.getdata())
    if image.mode == "RGB":
        channels = 3
    elif image.mode == "L":
        channels = 1
    else:
        print("Unknown mode: %s" % image.mode)
        return None
    pixel_values = numpy.array(pixel_values).reshape((width, height, channels))
    return pixel_values


image = get_image("gradient.png")

print(image[0])
print(image.shape)

Smoke testing the code

You might be uncertain about the order of width / height / channel. For this reason I’ve created this gradient:

The image has a width of 100px and a height of 26px. It has a color gradient going from #ffaa00 (yellow) to #ffffff (white). The output is:

[[255 172   5]
 [255 172   5]
 [255 172   5]
 [255 171   5]
 [255 172   5]
 [255 172   5]
 [255 171   5]
 [255 171   5]
 [255 171   5]
 [255 172   5]
 [255 172   5]
 [255 171   5]
 [255 171   5]
 [255 172   5]
 [255 172   5]
 [255 172   5]
 [255 171   5]
 [255 172   5]
 [255 172   5]
 [255 171   5]
 [255 171   5]
 [255 172   4]
 [255 172   5]
 [255 171   5]
 [255 171   5]
 [255 172   5]]
(100, 26, 3)

Things to note:

  • The shape is (width, height, channels)
  • The image[0], hence the first row, has 26 triples of the same color

回答 2

PyPNG-轻量级PNG解码器/编码器

尽管问题暗示JPG,但我希望我的回答对某些人有用。

这是使用PyPNG模块读取和写入PNG像素的方法:

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
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()

PyPNG是一个单一的纯Python模块,长度不足4000行,包括测试和注释。

PIL是一个更全面的映像库,但它也要重得多。

PyPNG – lightweight PNG decoder/encoder

Although the question hints at JPG, I hope my answer will be useful to some people.

Here’s how to read and write PNG pixels using PyPNG module:

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
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()

PyPNG is a single pure Python module less than 4000 lines long, including tests and comments.

PIL is a more comprehensive imaging library, but it’s also significantly heavier.


回答 3

正如Dave Webb所说:

这是我的工作代码片段,用于打印图像中的像素颜色:

import os, sys
import Image

im = Image.open("image.jpg")
x = 3
y = 4

pix = im.load()
print pix[x,y]

As Dave Webb said:

Here is my working code snippet printing the pixel colours from an image:

import os, sys
import Image

im = Image.open("image.jpg")
x = 3
y = 4

pix = im.load()
print pix[x,y]

回答 4

photo = Image.open('IN.jpg') #your image
photo = photo.convert('RGB')

width = photo.size[0] #define W and H
height = photo.size[1]

for y in range(0, height): #each pixel has coordinates
    row = ""
    for x in range(0, width):

        RGB = photo.getpixel((x,y))
        R,G,B = RGB  #now you can use the RGB value
photo = Image.open('IN.jpg') #your image
photo = photo.convert('RGB')

width = photo.size[0] #define W and H
height = photo.size[1]

for y in range(0, height): #each pixel has coordinates
    row = ""
    for x in range(0, width):

        RGB = photo.getpixel((x,y))
        R,G,B = RGB  #now you can use the RGB value

回答 5

图像处理是一个复杂的话题,它是最好的,如果你使用库。我可以推荐gdmodule,它可以从Python内轻松访问许多不同的图像格式。

Image manipulation is a complex topic, and it’s best if you do use a library. I can recommend gdmodule which provides easy access to many different image formats from within Python.


回答 6

在wiki.wxpython.org上有一篇非常不错的文章,名为“使用图像”。本文提到了使用wxWidgets(wxImage),PIL或PythonMagick的可能性。我个人使用过PIL和wxWidgets,它们都使图像处理相当容易。

There’s a really good article on wiki.wxpython.org entitled Working With Images. The article mentions the possiblity of using wxWidgets (wxImage), PIL or PythonMagick. Personally, I’ve used PIL and wxWidgets and both make image manipulation fairly easy.


回答 7

您可以使用pygame的surfarray模块。该模块具有3d像素阵列返回方法,称为pixel3d(surface)。我在下面显示了用法:

from pygame import surfarray, image, display
import pygame
import numpy #important to import

pygame.init()
image = image.load("myimagefile.jpg") #surface to render
resolution = (image.get_width(),image.get_height())
screen = display.set_mode(resolution) #create space for display
screen.blit(image, (0,0)) #superpose image on screen
display.flip()
surfarray.use_arraytype("numpy") #important!
screenpix = surfarray.pixels3d(image) #pixels in 3d array:
#[x][y][rgb]
for y in range(resolution[1]):
    for x in range(resolution[0]):
        for color in range(3):
            screenpix[x][y][color] += 128
            #reverting colors
screen.blit(surfarray.make_surface(screenpix), (0,0)) #superpose on screen
display.flip() #update display
while 1:
    print finished

希望对您有所帮助。最后一句话:屏幕在screenpix的生命周期内被锁定。

You can use pygame‘s surfarray module. This module has a 3d pixel array returning method called pixels3d(surface). I’ve shown usage below:

from pygame import surfarray, image, display
import pygame
import numpy #important to import

pygame.init()
image = image.load("myimagefile.jpg") #surface to render
resolution = (image.get_width(),image.get_height())
screen = display.set_mode(resolution) #create space for display
screen.blit(image, (0,0)) #superpose image on screen
display.flip()
surfarray.use_arraytype("numpy") #important!
screenpix = surfarray.pixels3d(image) #pixels in 3d array:
#[x][y][rgb]
for y in range(resolution[1]):
    for x in range(resolution[0]):
        for color in range(3):
            screenpix[x][y][color] += 128
            #reverting colors
screen.blit(surfarray.make_surface(screenpix), (0,0)) #superpose on screen
display.flip() #update display
while 1:
    print finished

I hope been helpful. Last word: screen is locked for lifetime of screenpix.


回答 8

使用命令“ sudo apt-get install python-imaging”安装PIL并运行以下程序。它将打印图像的RGB值。如果图像较大,则使用“>”将输出重定向到文件,然后打开文件以查看RGB值

import PIL
import Image
FILENAME='fn.gif' #image can be in gif jpeg or png format 
im=Image.open(FILENAME).convert('RGB')
pix=im.load()
w=im.size[0]
h=im.size[1]
for i in range(w):
  for j in range(h):
    print pix[i,j]

install PIL using the command “sudo apt-get install python-imaging” and run the following program. It will print RGB values of the image. If the image is large redirect the output to a file using ‘>’ later open the file to see RGB values

import PIL
import Image
FILENAME='fn.gif' #image can be in gif jpeg or png format 
im=Image.open(FILENAME).convert('RGB')
pix=im.load()
w=im.size[0]
h=im.size[1]
for i in range(w):
  for j in range(h):
    print pix[i,j]

回答 9

您可以使用Tkinter模块,它是Tk GUI工具包的标准Python界面,不需要额外下载。参见https://docs.python.org/2/library/tkinter.html

(对于Python 3,Tkinter重命名为tkinter)

这是设置RGB值的方法:

#from http://tkinter.unpythonic.net/wiki/PhotoImage
from Tkinter import *

root = Tk()

def pixel(image, pos, color):
    """Place pixel at pos=(x,y) on image, with color=(r,g,b)."""
    r,g,b = color
    x,y = pos
    image.put("#%02x%02x%02x" % (r,g,b), (y, x))

photo = PhotoImage(width=32, height=32)

pixel(photo, (16,16), (255,0,0))  # One lone pixel in the middle...

label = Label(root, image=photo)
label.grid()
root.mainloop()

并获得RGB:

#from http://www.kosbie.net/cmu/spring-14/15-112/handouts/steganographyEncoder.py
def getRGB(image, x, y):
    value = image.get(x, y)
    return tuple(map(int, value.split(" ")))

You could use the Tkinter module, which is the standard Python interface to the Tk GUI toolkit and you don’t need extra download. See https://docs.python.org/2/library/tkinter.html.

(For Python 3, Tkinter is renamed to tkinter)

Here is how to set RGB values:

#from http://tkinter.unpythonic.net/wiki/PhotoImage
from Tkinter import *

root = Tk()

def pixel(image, pos, color):
    """Place pixel at pos=(x,y) on image, with color=(r,g,b)."""
    r,g,b = color
    x,y = pos
    image.put("#%02x%02x%02x" % (r,g,b), (y, x))

photo = PhotoImage(width=32, height=32)

pixel(photo, (16,16), (255,0,0))  # One lone pixel in the middle...

label = Label(root, image=photo)
label.grid()
root.mainloop()

And get RGB:

#from http://www.kosbie.net/cmu/spring-14/15-112/handouts/steganographyEncoder.py
def getRGB(image, x, y):
    value = image.get(x, y)
    return tuple(map(int, value.split(" ")))

回答 10

from PIL import Image
def rgb_of_pixel(img_path, x, y):
    im = Image.open(img_path).convert('RGB')
    r, g, b = im.getpixel((x, y))
    a = (r, g, b)
    return a
from PIL import Image
def rgb_of_pixel(img_path, x, y):
    im = Image.open(img_path).convert('RGB')
    r, g, b = im.getpixel((x, y))
    a = (r, g, b)
    return a

回答 11

import matplotlib.pyplot as plt
import matplotlib.image as mpimg

img=mpimg.imread('Cricket_ACT_official_logo.png')
imgplot = plt.imshow(img)
import matplotlib.pyplot as plt
import matplotlib.image as mpimg

img=mpimg.imread('Cricket_ACT_official_logo.png')
imgplot = plt.imshow(img)

回答 12

如果您希望以RGB颜色代码的形式包含三位数,则以下代码应能做到这一点。

i = Image.open(path)
pixels = i.load() # this is not a list, nor is it list()'able
width, height = i.size

all_pixels = []
for x in range(width):
    for y in range(height):
        cpixel = pixels[x, y]
        all_pixels.append(cpixel)

这可能对您有用。

If you are looking to have three digits in the form of an RGB colour code, the following code should do just that.

i = Image.open(path)
pixels = i.load() # this is not a list, nor is it list()'able
width, height = i.size

all_pixels = []
for x in range(width):
    for y in range(height):
        cpixel = pixels[x, y]
        all_pixels.append(cpixel)

This may work for you.