【问题标题】:How can I get pixels from cairo.ImageSurface?如何从 cairo.ImageSurface 获取像素?
【发布时间】:2015-06-04 02:41:24
【问题描述】:

我编写了一个 Python 程序,当我单击一个按钮时,它会在其中绘制一个带有白色圆圈的黑色矩形。我使用Gtk.DrawingAreacairo.ImageSurface。代码如下。

class App:

    def __init__(self, width, height):

        self.surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)

        # Builder
        self.builder = Gtk.Builder()
        self.builder.add_from_file('ventana.glade')
        go = self.builder.get_object

        # Widgets
        self.window      = go('window')
        self.drawingarea = go('drawingarea')
        self.button      = go('button')

        signals = {
            'gtk_main_quit'    : Gtk.main_quit,
            'draw'             : self.draw
        }

        self.builder.connect_signals(signals)
        self.window.show_all()


    def draw(self, widget):
        context = self.drawingarea.get_window().cairo_create()
        context.set_source_surface(self.surface)

        context.set_source_rgba(0.0, 0.0, 0.0, 1.0)
        context.rectangle(0, 0, self.surface.get_width(), self.surface.get_height())
        context.fill()

        context.translate(10, 10)
        context.arc(0, 0, 10, 0, 2 * pi)
        context.set_source_rgba(1.0, 1.0, 1.0, 1.0)
        context.fill()

我得到以下窗口。

它工作正常,但我需要获取该图片像素的 RGB 值,所以我尝试使用map(ord, self.surface.get_data()),但我得到了一个零列表。

如何获取像素 RGB 列表?

还有一个问题:当我最小化窗口或切换到另一个窗口时,绘图会消失。有没有可能避免这种情况?

【问题讨论】:

    标签: python pygtk gtk3 cairo pycairo


    【解决方案1】:

    我不知道如何获取你的颜色,但关于绘图,将你的窗口与'configure-event'(窗口状态改变的事件)连接,然后调用drawingarea.queue_draw()

    【讨论】:

      【解决方案2】:

      你不需要使用地图,MemoryView 对象有一个tobytes() 函数。这将转换为一个 ByteArray,它可以很容易地转换为一个整数列表:

      # Set up pycairo
      my_surface = cairo.ImageSurface(cairo.FORMAT_RGB24, 10, 10)
      ctx = cairo.Context(my_surface)
      ctx.set_source_rgb(0.8, 0.8, 0.8)
      ctx.paint()
      
      # Draw a small red rectangle
      ctx.rectangle(1, 1, 5, 5)
      ctx.set_source_rgb(1, 0, 0)
      ctx.fill()
      
      # Convert pixels to MemoryView object, then bytestring or list of ints
      pixel_data_mv = my_surface.get_data()  # MemoryView object
      pixels_as_bytes = pixel_data_mv.tobytes()  # ByteArray
      pixels_as_list = list(pixels_as_bytes)
      
      # Iterate through memoryview object
      print(f"pixel_data_mv[{len(pixel_data_mv)}]:")
      for one_data_bit in pixel_data_mv:
          print(f"{str(one_data_bit)}", end=', ')
      print("")
      
      # Print as ByteArray and list of ints
      print(f"pixels_as_bytes[{len(pixels_as_bytes)}]:\n{pixels_as_bytes}")
      print(f"pixels_as_list[{len(pixels_as_list)}]:\n{pixels_as_list}")
      

      这将显示 ByteArray 和整数列表:

      pixels_as_bytes[400]:
      b'\xcc\xcc\xcc\xff\xcc\xcc\xcc\xff\xcc\xcc\xcc\xff\xcc ...
      pixels_as_list[400]:
      [204, 204, 204, 255, 204, 204, 204, 255, 204, 204, 204, 255
      

      注意像素被“分解”成四个字节,R/G/B/A。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-10-20
        • 2021-01-31
        • 2014-03-19
        • 1970-01-01
        • 1970-01-01
        • 2013-07-11
        • 1970-01-01
        相关资源
        最近更新 更多