尽可能快地将 Base64 转换为 np 数组,反之亦然

Base64 to nparray and viceversa as fast as possible

目前我的Python服务器接收一个base64编码的PNG图像并将其转换为nparray如下:

input = data['frame'].split(",")[1]
img_data = base64.b64decode(input)
nparr = np.frombuffer(img_data, np.uint8)
img_np = cv2.imdecode(nparr, cv2.IMREAD_COLOR)

反之亦然:

retval, buffer = cv2.imencode('.jpg', output)
pic_str = base64.b64encode(buffer)
pic_str = pic_str.decode()
image_data = "data:image/jpeg;base64," + pic_str

但是我的实时应用程序需要太多时间,是否存在更快的方法?在这两个操作之间,nparray 被转换为 Tensor(反之亦然),因此 base64 <-> Tensor 转换也可以。

更新速度将取决于输入图像的大小。但是下面的方法对我来说工作得更快一点:

  • 编码

    def arr_to_base64(image: np.ndarray, ext='jpeg'):
        """ Convert an array to an image source that can be displayed."""
        image = Image.fromarray(image)
        if ext == 'jpg': ext = 'jpeg'
        if ext == 'jpeg' and image.mode in ('RGBA', 'A'):
            background = Image.new(image.mode[:-1], image.size, (255, 255, 255))
            background.paste(image, image.split()[-1])
            image = background
    
        buffer = io.BytesIO()
        image.save(buffer, format=ext)
        encoded = base64.b64encode(buffer.getvalue()).decode('utf-8')
        return f'data:image/{ext};base64,' + encoded
    
  • 解码

    def arr_from_base64(base_string):
        msg = base64.b64decode(base_string[23:])  # Chop of metadata from above
        buf = io.BytesIO(msg)
        img = Image.open(buf)
        return np.array(img)
    

针对随机输入图像 (np.random.randint(0, 255, (n, n, 3), dtype=np.uint8)),通过 运行ning 操作 100 次执行了以下测试。

(n, n, 3) 图像进行 100 次编码:

对一张(n, n, 3)图像进行100次编码和解码:

备注

  • 请不要使用内置变量 (input)。
  • 花在这上面的时间似乎很不重要。对于 512 x 512 的大图像,您仍然可以 运行 每秒大约 80 张图像。您需要 23 岁左右才能获得良好的现实生活。也许您想检查实时消耗。