【问题标题】:Speeding up grabbing alphachannel加速抓取 alphachannel
【发布时间】:2020-07-17 16:41:36
【问题描述】:

我不知道是否可以做任何事情来加速我的代码,如果有的话,可能不会太多,但我想我会在这里问。

我正在为使用自定义嵌入式 python 解释器的程序编写 python 脚本,因此我只能使用默认库。 Pillow 和 Numpy 等外部库不起作用,因为它们更改了 python dll 的名称,因此预编译的库无法与之交互。

此程序不支持从剪贴板粘贴其专有格式之外的透明图像。所以我正在编写一个脚本来涵盖该功能。它使用 ctypes 从剪贴板中抓取 CF_DIBv5 格式,并检查它是否为 32bpp 以及是否存在 alphamask。

这是缓慢的部分。然后我需要隔离 alpha 通道并将其保存为自己的单独图像。我可以很容易地做到这一点。只需从字节字符串中获取一个 Long 和获取 alpha 通道的掩码,然后将其添加回我的新位图字节字符串。在 300x300 的小图像上,这需要将近 10 秒。这并不可怕。我很乐意接受这一点。但是,我担心它在较大的百万像素图像上会非常缓慢。

我没有在这里显示完整的代码,因为它是一个可怕的丑陋的混乱,其中大部分只是定义我用于我的位图类的结构并让 ctypes 工作。但这里是我循环数据的重要部分。

        rowsizemask = calcRowSize(24,bmp.header.bV5Width) #returns bytes per row needed
        rowmaskpadding = b'\x00'*(rowsizemask - bmp.header.bV5Width*3) #creates padding bytes
        
        #loop over image data
        for y in range(bmp.header.bV5Height):
            for x in range(bmp.header.bV5Width):
                offset, color = unpack(offset,">L",buff) #calls struct.unpack in custom function
                color = color[0] & bmp.header.bV5AlphaMask #gets alpha channel
                newbmp.pixels += struct.pack(">3B", color,color,color) #creates 24bpp listing
            newbmp.pixels += rowmaskpadding #pad row to meet BMP specs

那你怎么看?我错过了一些明显的东西吗?或者这是否与纯 python 一样好?

【问题讨论】:

  • 好的,所以我才意识到(我傻了)这显然是字符串创建的问题。我添加了一条打印语句,以向我展示它在各行中的进展速度,并且在第 230 行之前运行速度非常快。然后它会减慢速度。显然是因为它不断地复制、添加和销毁字符串。我只是不知道该怎么处理。我知道没有可变字符串选项可以让我预先创建一个足够大小的字符串并用我新打包的字节字符串替换字节。

标签: python python-2.7 performance bitmap


【解决方案1】:

好的,所以在进一步挖掘之后。我意识到我可以使用 ctypes.create_string_buffer 创建一个完美大小的二进制字符串,然后使用切片来更改值。

我可以进行更多微小的优化和代码清理,但这已将其从在 900x900 像素图像上很容易需要几分钟才能完成的脚本变为只需几秒钟。

这是最好的选择吗?不知道,但它有效。它比我想象的要快。在此处查看编辑后的代码。变化很小。

        rowSizeMask = calcRowSize(24,bmp.header.bV5Width) #returns bytes per row needed
        paddingLength = (rowSizeMask = bmp.header.bV5Width*3)
        rowMaskPadding = b'\x00'*paddingLength #creates padding bytes
        writeOffset = 0

        #create pixel buffer
        #rowsize mask includes padding, multiply by height for total byte count
        newBmp.pixels = ctypes.create_string_buffer(bmp.heaer.bV5Height * rowSizeMask)

        #loop over image data
        for y in range(bmp.header.bV5Height):
            for x in range(bmp.header.bV5Width):
                offset, color = unpack(offset,">L",buff) #calls struct.unpack in custom function
                color = color[0] & bmp.header.bV5AlphaMask #gets alpha channel
                newBmp.pixels[writeOffset:writeOffset+3] = struct.pack(">3B", color,color,color) #creates 24bpp listing
                writeOffset += 3
            newBmp.pixels += rowMaskPadding #pad row to meet BMP specs
            writeOffset += paddingLength

【讨论】:

    猜你喜欢
    • 2013-06-06
    • 2021-10-28
    • 1970-01-01
    • 2020-04-11
    • 1970-01-01
    • 1970-01-01
    • 2020-05-24
    • 1970-01-01
    • 2022-06-10
    相关资源
    最近更新 更多