我想把两个数组组合成一个0(1)的新数组。然后,我想改变这个新数组中的值来改变旧数组中的值。
这是在PyGame的surfarray模块的上下文中,该模块没有返回RGBA (n*m*4)数组的函数——只有RGB (n*m*3)和a (n*m)数组。理想情况下,我会在0(1)中创建一个引用"RGB"one_answers"a"数组的新数组"RGBA"。改变"RGBA"会同时改变"RGB"one_answers"A",从而改变表面。
我不知道这是否可能,因为我想不出用c来做这件事的方法。然而,我可以想到一些主意。例如,可能存在一个numpy数组类型,它封装了一些子数组,并在内部将索引重定向到C级别的正确索引。
您可以创建自己的类来管理引用过程,如下面的示例所示。您应该进一步研究这一点,以包括__getslice__
, __add__
, __mul__
等的切片功能。
import numpy as np
a1 = np.arange(1,11)
a2 = np.arange(101,111)
class Combiner():
def __init__(self, *args):
self.arrays = [arg for arg in args]
self.lens = [len(arg) for arg in args]
def __getitem__(self,i):
if i >=0:
shift = 0
acc = 0
for j,l in enumerate(self.lens):
acc += l
if i<acc:
return self.arrays[j][i-shift]
shift += l
if i<0:
shift = 0
acc = 0
for j in xrange(len(self.lens)-1,-1,-1):
l = self.lens[j]
acc -= l
if i>=acc:
return self.arrays[j][i+shift]
shift += l
def __setitem__(self,i,v):
if i >=0:
shift = 0
acc = 0.
for j,l in enumerate(self.lens):
acc += l
if i<acc:
self.arrays[j][i-shift] = v
return
shift += l
if i<0:
shift = 0
acc = 0
for j in xrange(len(self.lens)-1,-1,-1):
l = self.lens[j]
acc -= l
if i>=acc:
self.arrays[j][i+shift] = v
return
shift += l
a3 = Combiner(a1,a2)
print a3[-10]
# 101
a3[-2] = 22222
a3[ 4] = 11111
print a1
#[ 1 2 3 4 11111 6 7 8 9 10]
print a2
#[ 101 102 103 104 105 106 107 108 22222 110]
我不确定我是否完全理解了这个问题。据我所知,pygame表面是在RGBA(确切地说,BGRA)连续数组中,如果您初始化pygame和这样的表面(注意每行"32"):
# display surface
DISP = pygame.display.set_mode((window_w, window_h), 0, 32)
# some surface
window = pygame.Surface((w, h), 0, 32)
我还建议尽可能使用32位,而不是24位,因为24位表面很难与数组互操作(我使用numpy
来存储和操作图像数据)。
例如,一个24位表面必须具有可被4整除的像素量,如果我没有弄错的话。
例如,用
openCV
库加载图像并将其转换为BGRA数组:
# BGR 3d numpy array array (shape = h, w, 3) with image data
img = cv2.imread(filename)
# BGRA 3d numpy array (shape = h, w, 4)
img = cv2.cvtColor(img, cv2.COLOR_BGR2BGRA)
然后这个函数将整个数组数据复制到一个表面,只需要确保它们具有相同的像素大小:
# copy array data into a pygame surface
def copy_arr(surface, myarray):
bv = surface.get_buffer()
bv.write(myarray.tostring(), 0)
但也可以是你想做别的事情