快速从字符串python中获取每n个值

时间:2013-09-23 03:14:06

标签: python bitmap

首先,我知道不为此应用程序使用python将有助于加快我的代码。不幸的是python是我最熟悉的,而且这个项目的时间有限。学习C或类似的东西对我的情况不切实际。

所以这是我的问题。我已经将一个位图加载到python中并提取了像素数据,我将其作为原始字节以字符串形式存储,例如:“143 200 30 -1”(这是一个值为143的字节,而不是写入的3个字符数字143)。

我要做的是从字符串中删除每四个字节。第四个字节是alpha通道,我的应用程序不需要它。这是我到目前为止的代码,它采用了尺寸为blockSizeX x blockSizeY的图像的一部分,位于blockY和blockX的位置,并删除了该过程中的alpha通道:

def getScreenBlockFaster(bmpstr, imgWidth):
    pixelData = ''
    pixelCoord = (blockY * blockSizeY * imgWidth + blockSizeX * blockX)* 4
    for y in range(blockSizeY * 4):
        for x in range(0, blockSizeX * 4, 4):
            pixelCoord += x 
            pixelData += bmpstr[pixelCoord : pixelCoord + 3]
        pixelCoord += imgWidth * 4
    return pixelData

这可行,但需要很长时间(几乎一整秒)。我希望这个应用程序获得5-10 fps,而这部分代码本身就太慢了。我打算多线程化这段代码,这有点可以缓解速度问题,但我认为这仍然太慢了。我正在寻找的是一种更快的方式来采样这个位图,这样我就可以获得一部分数据,但我需要快速完成。有什么建议吗?

3 个答案:

答案 0 :(得分:3)

以下是使用itertools的解决方案:

>>> def drop_alpha(s):
...     return ''.join(itertools.compress(
...             s, itertools.cycle([True, True, True, False])))
...
>>> drop_alpha('12345678')
'123567'

内循环中没有解释代码,它是线性时间而不是二次方,所以它应该非常快。如果你要进行比这更复杂的图像处理,那么值得研究可用的各种libraries

答案 1 :(得分:0)

至少不使用字符串连接会有所帮助,使用:

pixelData = []
...
for y in range (blockSizeY * 4):
  ...
  pixelData.extend(bmpstr[pixelCoord : pixelCoord + 3])
...
return "".join(pixelData)

(并删除初始化和引用旧字符串pixelData变量的其他地方)

然而,这似乎也是在加载时更有效的东西 - 无论您用于加载图像的任何库都会在加载时删除alpha通道(或者执行可能在C中实现的内部转换) ?

答案 2 :(得分:0)

我不知道这会有多快,但如果转换为数组,删除就变得容易了:

>>> s = "rgba"*10
>>> s
'rgbargbargbargbargbargbargbargbargbargba'
>>> import array
>>> a = array.array('c', s)
>>> a
array('c', 'rgbargbargbargbargbargbargbargbargbargba')
>>> del a[3::4]
>>> a
array('c', 'rgbrgbrgbrgbrgbrgbrgbrgbrgbrgb')

更好的解决方案是Nick Bastin评论其他答案之一:只需使用PIL进行图像处理。