更改 GdkPixbuf (GTK3) 中像素的颜色

2024-03-13

我在用着Gtk.StatusIcon,并且想要改变某些像素的颜色;我有一段工作代码,它加载一个带有我想要设置的颜色的 1x1 像素 PNG 文件,然后将其复制到图标 Pixbuf。
虽然这种方法有效,但它有一个明显的缺点,即必须为每种颜色创建 1x1 像素,因此我不能使用任意颜色,只能使用我为其创建图像的预定义颜色。

如何将像素设置为任意 RGBA 颜色?

我现在使用的代码(出于演示目的而简化):

#!/usr/bin/env python

from gi.repository import Gtk, GLib, GdkPixbuf

def set_icon_cb(widget, data=None):
    set_icon(widget)

def set_icon(icon):
    fill_amount = 20
    img = GdkPixbuf.Pixbuf.new_from_file('./data/icons/battery.png')
    fill = GdkPixbuf.Pixbuf.new_from_file('./data/icons/green.png')

    for row_num, row in enumerate(zip(*(iter(img.get_pixels()),) *img.get_rowstride())):
        # Blank row
        if 255 not in row: continue

        for col_num, pixel in enumerate(zip(*(iter(row),) * 4)):
            r, g, b, a = pixel

            if col_num > 2 and col_num <= fill_amount and a == 0:
                fill.copy_area(0, 0, 1, 1, img, col_num, row_num)

    icon.set_from_pixbuf(img)


icon = Gtk.StatusIcon()
icon.connect('activate', set_icon_cb)
set_icon(icon)

Gtk.main()

我尝试创建一个新的 Pixbuf 对象GdkPixbuf.PixbufLoader,但这似乎需要一个 PNG 图像,而不是一个字节对象,所以这不是很有帮助:

fill = GdkPixbuf.PixbufLoader()
fill.write(b'\x88\x88\x88\xff')
fill.close()
fill = fill.get_pixbuf()

# Gives error:
# GLib.Error: gdk-pixbuf-error-quark: Unrecognized image file format (3)

我的下一次尝试是使用GdkPixbuf.Pixbuf.new_from_data,看起来很有前途:

fill = GdkPixbuf.Pixbuf.new_from_data(b'\xff\x00\xff', GdkPixbuf.Colorspace.RGB,
    False, 8, 1, 1, 3)

然而,这也行不通。它不仅将像素设置为错误的颜色,还在多次调用时将其设置为不同的颜色set_icon(); print(fill.get_pixels())给我b'\x00\x00\x00'...我用错了吗?我绑定了各种不同的参数,但都给出了相同的结果......

我还找到了一个 C 示例,它修改了结果gdk_pixbuf_get_pixels(),因为这会返回指向图像数据的指针。但这不是你可以在 Python 中完成的事情(据我所知)。

我想要完成的事情的一些背景:
我有一个小托盘应用程序来显示我的笔记本电脑的电池状态;它会填满电池图标,以指示剩余的电池电量。低于一定百分比,颜色从绿色变为红色(这适用于上面的示例),但我希望在这方面有更大的灵活性;例如。允许其他人设置自己的绿色阴影,或使用紫色,或其他。


事实证明它相当简单,但从阅读文档来看却一点也不明显:

# red, green, blue, alpha
color = 0xeeff2dff

# Create blank 1x1 image
fill = GdkPixbuf.Pixbuf.new(GdkPixbuf.Colorspace.RGB, True, 8, 1, 1)

# Fill entire image with color
fill.fill(color)

我原来的解决方案,留在这里用于存档目的;这更复杂并且不透明,但它可能更适合更高级的操作

经过更多的研究后我最终使用了GdkPixbuf.PixbufLoader.new_with_type, from:

list(map(lambda x: x.get_name(), GdkPixbuf.Pixbuf.get_formats()))

我选择最简单的图像格式,它似乎是“便携式anymap格式”或pnm.

我使用 GIMP 创建了一个简单的 1x1 图像,它给了我以下数据:

>>> open('test.pnm', 'rb').read()
b'P6\n# CREATOR: GIMP PNM Filter Version 1.1\n1 1\n255\n\xff\x00\xff'

最后 3 个字节(\xff\x00\xff)是我选择的颜色。

我最终使用的完整示例:

color = b'\xee\xff\x2d'

px = GdkPixbuf.PixbufLoader.new_with_type('pnm')
px.write(b'P6\n\n1 1\n255\n' + color)
px.write(color)
px.close()
fill = px.get_pixbuf()

然后我可以使用fill就像原来的例子一样fill.copy_area()

这是一种解决方法,但可以接受......

PS.
从文档来看,GdkPixbuf.Pixbuf.new_from_data看起来是做到这一点的最佳选择,但它似乎坏了......无论我做什么我都无法工作......

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

更改 GdkPixbuf (GTK3) 中像素的颜色 的相关文章

随机推荐

  • Android mkdirs() 不工作

    我正在开发我的第一个 Android 应用程序 在尝试创建目录来保存录制的视频文件时遇到了问题 我的主要活动有一个方法buttonOnClickRecord调用使用 android 相机的意图 我还在这个方法调用期间创建了一个文件 并且我正
  • 如何找出方法或函数的调用者是谁? [复制]

    这个问题在这里已经有答案了 我想编写一个调试函数或方法来帮助打印有用的信息 当它被调用时 我需要 调用对象的内存地址 如果由对象调用 调用者的方法签名 或方法的名称 或函数的名称 拥有该方法或函数的类名 是否可以在不传递一大堆参数的情况下获
  • 为什么我无法使用 Puppeteer 访问 hideFunction() 函数中的“窗口”?

    我有一个非常简单的傀儡师 https github com GoogleChrome puppeteer使用的脚本exposeFunction https github com GoogleChrome puppeteer blob mas
  • Swift 中数组的 endIndex 的正确行为是什么?

    endIndex 返回与 count 相同的值 这是正确的行为还是错误 var ar 1 2 3 4 ar count 4 ar endIndex 4 count是集合中的项目数 而endIndex is the Index 来自Colle
  • Android - 移动网络设置菜单(Jelly Bean)

    以下代码不适用于 Jelly Bean Android 4 1 final ComponentName cn new ComponentName com android phone com android phone Settings fi
  • ios 中纹理的多重采样渲染

    我正在尝试在启用多重采样的 ios 中渲染到纹理 然后在最终输出中使用该纹理 这可能吗 到目前为止 我只得到了黑色纹理或锯齿图像 我正在使用的代码是 glGenTextures 1 texture glBindTexture GL TEXT
  • C# 没有边界检查的 byte[] 比较

    我正在寻找性能高效的方法来比较两个 byte 是否相等 大小超过 1 MB 因此每个数组元素的开销应最小化 我的目标是超越SequenceEqual http msdn microsoft com en us library bb34856
  • python tkinter 列表框事件绑定

    我无法让事件绑定与 python tkinter 一起使用 我只是尝试单击并打印位置 但每次执行此操作时 结果都是 1 这是我的代码 from Tkinter import import Tkinter class make list Tk
  • spring junit 加载应用程序上下文进行测试

    我的 WEB INF 目录下有一些 XML 文件 歌词BaseApp servlet xml 休眠文件 数据源 xml beans xml servlet xml 导入其他 xml 文件
  • 如何旋转图像pygame的蒙版

    您好 我在旋转对象的蒙版时遇到问题 旋转蒙版仍处于与原始图像相同的位置 重点是在赛道上移动掩模以形成碰撞 def init self x y height width self x x width 2 self y y height 2 s
  • Angular - 使用 Restangular 时中止 ajax 请求

    我有一个方法调用角度服务 从而通过该服务发出 ajax 请求 我需要确保如果多次调用此方法 则先前的请求将被中止 如果尚未解决 该方法可以被多次调用 这个方法其实是来自ngTable上的ngTableParams getData funct
  • 如何监听 MongoDB 集合的更改?

    我正在创建一种后台作业队列系统 使用 MongoDB 作为数据存储 在派生工作人员来处理作业之前 如何 侦听 对 MongoDB 集合的插入 我是否需要每隔几秒轮询一次以查看与上次相比是否有任何更改 或者我的脚本是否可以等待插入发生 这是我
  • Web应用程序不会加入Infinispan集群

    我最近一直在玩 Infinispan 之前没有使用 Infinispan 的经验 我遇到了一个有趣的问题 我想知道是否有人能够阐明它 我有一个独立的 Java 应用程序 GridGrabber jar 它捆绑了 Infinispan jar
  • 使用后台附件:在 ipad 上的 safari 中修复

    我希望重新创建类似于科普应用程序的效果 基本上有一个大的背景图像 然后在其上有 HTML CSS 层 当用户滚动内容时 图像的背景位置应保持在原位 而不是滚动 显然 在 常规 浏览器中我会使用background attachment fi
  • NodeJS My SQL 查询与 Chain Promise

    我有3个函数 我想逐步调用这个函数 例如当我调用第一个函数并获取结果时 我必须调用第二个函数并传递从第一次调用返回的参数 在完成第二个调用后 我必须调用第三个函数并传递从第二个函数返回的参数 1 getCategory function b
  • 计算无符号整数中位转换数量的最快方法

    我正在寻找最快的方法来计算位转换的数量unsigned int 如果 int 包含 0b00000000000000000000000000001010 转换次数为 4 如果 int 包含 0b00000000000000000000000
  • 无法更改导航控制器中导航栏的高度(它比正常情况宽得多)

    我有一个从主 TabBarController 扩展并扩展 ViewController 的 NavigationController 和 VC 扩展至 2x TableView 因此 TabBar gt NavigationControl
  • Rails 中的 Object#presence 有什么意义?

    在 Rails 文档中 提供的例子 http api rubyonrails org classes Object html method i presence为了Object presence方法是 region params state
  • 当引导服务器关闭时,具有 transactionIdPrefix 的 DefaultKafkaProducerFactory 会无限等待

    Hy 我正在使用 spring kafka 1 3 0 RELEASE 创建事务生产者 当引导服务器关闭时 DefaultKafkaProducerFactory 会无休止地等待 直到引导服务器启动 我究竟做错了什么 我可以设置超时和 或其
  • 更改 GdkPixbuf (GTK3) 中像素的颜色

    我在用着Gtk StatusIcon 并且想要改变某些像素的颜色 我有一段工作代码 它加载一个带有我想要设置的颜色的 1x1 像素 PNG 文件 然后将其复制到图标 Pixbuf 虽然这种方法有效 但它有一个明显的缺点 即必须为每种颜色创建