Python 如何将Gdk pixbuf对象转换为numpy数组

Python 如何将Gdk pixbuf对象转换为numpy数组,python,arrays,image,Python,Arrays,Image,所以,我试着拍摄一张屏幕截图,并将其作为numpy数组进行处理。然而,我能找到的只是先把它转换成PIL图像,然后再转换成numpy数组。因此,我想知道是否有一种方法可以直接将其转换为numpy数组,而不必使用PIL库 from gi.repository import Gdk window = Gdk.get_default_root_window() x, y, width, height = window.get_geometry() pb = Gdk.pixbuf_get_from_wi

所以,我试着拍摄一张屏幕截图,并将其作为numpy数组进行处理。然而,我能找到的只是先把它转换成PIL图像,然后再转换成numpy数组。因此,我想知道是否有一种方法可以直接将其转换为numpy数组,而不必使用PIL库

from gi.repository import Gdk

window = Gdk.get_default_root_window()
x, y, width, height = window.get_geometry()
pb = Gdk.pixbuf_get_from_window(window, x, y, width, height)

谢谢你

如果你不介意使用Gtk2和PyGtk,那么下面就可以了

import gtk, numpy
image="yourimage.jpg"
t=gtk.gdk.pixbuf_new_from_file(image)
n=t.get_pixels_array()
print n.shape
最好的部分是
n
是对
t
中数据的引用,因此您可以使用numpy更改pixbuf

如果您希望使用Gtk3,这两个调用就可以了

from gi.repository import GdkPixbuf
import numpy
def array_from_pixbuf(p):
    " convert from GdkPixbuf to numpy array"
    w,h,c,r=(p.get_width(), p.get_height(), p.get_n_channels(), p.get_rowstride())
    assert p.get_colorspace() == GdkPixbuf.Colorspace.RGB
    assert p.get_bits_per_sample() == 8
    if  p.get_has_alpha():
        assert c == 4
    else:
        assert c == 3
    assert r >= w * c
    a=numpy.frombuffer(p.get_pixels(),dtype=numpy.uint8)
    if a.shape[0] == w*c*h:
        return a.reshape( (h, w, c) )
    else:
        b=numpy.zeros((h,w*c),'uint8')
        for j in range(h):
            b[j,:]=a[r*j:r*j+w*c]
        return b.reshape( (h, w, c) )

def pixbuf_from_array(z):
    " convert from numpy array to GdkPixbuf "
    z=z.astype('uint8')
    h,w,c=z.shape
    assert c == 3 or c == 4
    if hasattr(GdkPixbuf.Pixbuf,'new_from_bytes'):
        Z = GLib.Bytes.new(z.tobytes())
        return GdkPixbuf.Pixbuf.new_from_bytes(Z, GdkPixbuf.Colorspace.RGB, c==4, 8, w, h, w*c)
    return GdkPixbuf.Pixbuf.new_from_data(z.tobytes(),  GdkPixbuf.Colorspace.RGB, c==4, 8, w, h, w*c, None, None)

如果您不介意使用Gtk2和PyGtk,那么下面就可以了

import gtk, numpy
image="yourimage.jpg"
t=gtk.gdk.pixbuf_new_from_file(image)
n=t.get_pixels_array()
print n.shape
最好的部分是
n
是对
t
中数据的引用,因此您可以使用numpy更改pixbuf

如果您希望使用Gtk3,这两个调用就可以了

from gi.repository import GdkPixbuf
import numpy
def array_from_pixbuf(p):
    " convert from GdkPixbuf to numpy array"
    w,h,c,r=(p.get_width(), p.get_height(), p.get_n_channels(), p.get_rowstride())
    assert p.get_colorspace() == GdkPixbuf.Colorspace.RGB
    assert p.get_bits_per_sample() == 8
    if  p.get_has_alpha():
        assert c == 4
    else:
        assert c == 3
    assert r >= w * c
    a=numpy.frombuffer(p.get_pixels(),dtype=numpy.uint8)
    if a.shape[0] == w*c*h:
        return a.reshape( (h, w, c) )
    else:
        b=numpy.zeros((h,w*c),'uint8')
        for j in range(h):
            b[j,:]=a[r*j:r*j+w*c]
        return b.reshape( (h, w, c) )

def pixbuf_from_array(z):
    " convert from numpy array to GdkPixbuf "
    z=z.astype('uint8')
    h,w,c=z.shape
    assert c == 3 or c == 4
    if hasattr(GdkPixbuf.Pixbuf,'new_from_bytes'):
        Z = GLib.Bytes.new(z.tobytes())
        return GdkPixbuf.Pixbuf.new_from_bytes(Z, GdkPixbuf.Colorspace.RGB, c==4, 8, w, h, w*c)
    return GdkPixbuf.Pixbuf.new_from_data(z.tobytes(),  GdkPixbuf.Colorspace.RGB, c==4, 8, w, h, w*c, None, None)

_pixbuf函数中的
array_效果很好,但是
pixbuf_from_array
函数显示垃圾或导致分段错误。经过大量搜索,我找到了这个答案,描述了保存图像的内存在使用前被释放:。解决方法是使用Pixbuf.new_from_data并在z.tobytes()周围放置GLib.Bytes.new()。亲爱的Zoltan,我最近尝试了你的版本,实际上由于你的更改,代码崩溃了,而我上面的版本运行得很好。我不知道为什么,很有趣。对我来说,这两种变体的行为是完全相反的。来自\u pixbuf
array\u函数工作得很好,但是来自\u array
pixbuf\u函数显示垃圾或导致分段错误。经过大量搜索,我找到了这个答案,描述了保存图像的内存在使用前被释放:。解决方法是使用Pixbuf.new_from_data并在z.tobytes()周围放置GLib.Bytes.new()。亲爱的Zoltan,我最近尝试了你的版本,实际上由于你的更改,代码崩溃了,而我上面的版本运行得很好。我不知道为什么,很有趣。对我来说,这两种变体的行为是完全相反的。