图像抖动:如何在纯python中提高像素阵列效率?

时间:2019-04-08 11:43:13

标签: python arrays performance gif

我目前正在使用python 3.5脚本将bmp图像(或任何像素数组)转换为gif图像。我想不使用诸如numpy或枕头之类的笨重的python模块来执行此操作,我正在使用准纯python。 为了达到这个目的,我需要将颜色数量减少到256种,并对像素进行抖动处理。 我已经有一个可以正常运行的脚本,但是它非常慢(570x370图像大约需要3s,1900x1100图像大约需要30s),这是不可接受的:-)

这是我编写的代码。 “ px”是这样创建的[高度] x [宽度] x [3种颜色]的数组

px = []
for i in range(height):
    px.append([[0,0,0]]*width)

并用bmp值填充(例如px [10] [12] = [101,203,255])

减色和抖动处理是通过以下代码完成的(使用Sierra Lite抖动处理http://www.tannerhelland.com/4660/dithering-eleven-algorithms-source-code/):

data=bytearray(height*width) # Output data array
i = 0
for ligne in range(height):
    for col in range(width):
        [R,G,B] = px[ligne][col] # Get colors of pixel
        Idx = GetColorIdx(R,G,B) # Get table index of nearest color
        data[i] = Idx            # Store index
        i += 1
        [Rnew,Gnew,Bnew] = GetIdxColor(Idx) # Get colors of table index
        e = (R+G+B)/3-(Rnew+Gnew+Bnew)/3    # error between colors

        # Error diffusion on nearest pixels if available
        if col < width-1:
            [R,G,B] = px[ligne][col+1]
            px[ligne][col+1] = [clip(R+e/2),clip(G+e/2),clip(B+e/2)]
        if ligne < height-1:
            if col > 0:
                [R,G,B] = px[ligne+1][col-1]
                px[ligne+1][col-1] = [clip(R+e/4),clip(G+e/4),clip(B+e/4)]
            [R,G,B] = px[ligne+1][col]
            px[ligne+1][col] = [clip(R+e/4),clip(G+e/4),clip(B+e/4)]

以下是辅助功能:

# 256 8-8-4 color palette inspired from
# https://en.wikipedia.org/wiki/List_of_software_palettes#8-8-4_levels_RGB
def GetColorIdx(R,G,B): # Get color index from RGB colors
    return round(R/36.5)+round(G/36.5)*8+round(B/85)*64

def GetIdxColor(Idx): # Get RGB colors from table index
    R=int(Idx%8*36.5)
    G=int(Idx//8%8*36.5)
    B=int(Idx//64*85)
    return [R,G,B]

def clip(n): # Trim n between 0 and 255
    if n<0: return 0
    elif n>255: return 255
    return round(n)

非常慢的部分是围绕宽度和高度的双倍for循环。 您是否对如何在纯python下改善这一点有任何想法? 我已经尝试了几种方法,例如使用dict而不是list,将颜色编码为3个字节而不是3个值,但这没有实际效果...

这部分之后是gif编码和书写部分。我认为这也可以改善,但这将是下一步^^

谢谢!!

0 个答案:

没有答案