我是Tkinter(和Python)的新手,我想找到将RGB值格式化为字符串的最有效方法,以便它可以与PhotoImage.put()
函数一起使用。
假设我有一个存储RGB值的Numpy rank 3数组,第三维的红色,绿色和蓝色长度分别为3。最直观的方法是:
for i in range(0, n_pixels_x):
for j in range(0, n_pixels_y):
hexcode = "#%02x%02x%02x" % (array[i,j,0], array[i,j,1], array[i,j,2])
img.put(hexcode, (j,i))
不幸的是,这对于大型图像来说太慢了。
如PhotoImage Wiki中所述,可以将一个大字符串传递给put()
,因此该函数只被调用一次。然后,我需要有效地将我的数组转换为这样的字符串,其格式应该是这样的(对于4x2图像):
"{#ff0000 #ff0000 #ff0000 #ff0000} {#ff0000 #ff0000 #ff0000 #ff0000}"
同样,这可以通过嵌套for循环轻松完成,但出于效率原因我想避免使用它们。有没有办法使用join()
来做我想做的事情?
如果需要,我可以不同地存储我的数组的内容,唯一的限制是我应该能够轻松地修改颜色值。
编辑:在对此进行了一些处理后,我发现了一种格式化值的方法,比使用嵌套循环快10倍。这是评论的代码:
# 1. Create RGB array
array = np.zeros((n_pixels_x*n_pixels_y, 3))
array = np.asarray(array, dtype = "uint32")
array[1,:] = [0, 100, 255]
# 2. Create a format string
fmt_str = "{" + " ".join(["#%06x"]*n_pixels_x) + "}"
fmt_str = " ".join([fmt_str]*n_pixels_y)
# 3. Convert RGB values to hex
array_hex = (array[:,0]<<16) + (array[:,1]<<8) + array[:,2]
# 4. Format array
img_str = fmt_str % tuple(array_hex)
对于640x480阵列,步骤3和4需要大约0.1秒才能在我的笔记本电脑上执行(使用timeit.default_timer()
评估)。使用嵌套循环,需要0.9s到1.0s。
我仍然希望减少计算时间,但我不确定此时是否还有任何改进。
答案 0 :(得分:0)
我能够找到另一种格式化数组的方法,这似乎是最快的解决方案。解决方案是简单地使用Image
和ImageTk
直接从数组生成图像对象:
array = np.zeros((height, width, 3), 'uint8')
imageObject = Image.fromarray(array)
img = ImageTk.PhotoImage(image = imageObject, mode = 'RGB'))
这需要大约0.02秒才能运行,这足以满足我的需求,并且不需要使用put()
功能。
我实际上从另一个问题找到了这个答案:How do I convert a numpy array to (and display) an image?