图像的字节数组

0 投票
3 回答
1907 浏览
提问于 2025-05-01 02:57

我正在尝试制作一个基于浏览器的远程桌面控制器。为此,我的做法是定期截取远程桌面的屏幕截图,并将这些截图传输给客户端。不过,这种方法效率很低,因为屏幕变化不大。因此,我想到了一个办法,只传输连续截图之间的差异。这样一来,我也能提高帧率(fps)。最开始,我使用Python的PIL库将截图转换成像素数组,然后比较这两个数组,找出不同的像素并只发送这些不同的部分。但这个过程花了很多时间来获取截图的像素数组。

后来我发现可以使用字节数组来表示图像。将图像转换为字节数组的速度比转换为像素数组(rgba)快得多。但是,我该如何理解字节数组呢?图像的字节数组中存储了什么?我使用这段代码将字节数组转换成了8位整数数组:

bytes = readimage("./scimg1.png")

i = 0
bytearr = [] 
while i < len(bytes):
    bytearr.append(bytes[i])
    i+=1

接下来,我想知道如何使用这个字节数组比较两张图像并找出它们的差异。我发现,即使是尺寸相同(长度和宽度)的两张图像,它们的数组长度也会不同。

暂无标签

3 个回答

0

你可以使用 ImageChops 模块来计算图片之间的差异。通过使用 ImageChops.difference(image1, image2) 这个方法,你可以得到两张截图之间的不同之处。

在发送图片之前,你还应该使用 gzip 来压缩这些图片。这样每次发送的数据量就会减少,传输会更快。这里是 gzip 库 的相关文档。

0

我建议你使用一些视频编码库,比如 PyMedia 或者 pyffmpeg。你显然是在追求速度,而在传输图像方面,可能没有比这更快的了。需要注意的是,PyMedia 只支持比较老的 mpeg1 和 mpeg2 格式。

另外一个选择是放弃自定义的方法,直接使用一些已经存在的协议,比如 Windows 的 RDP 协议或者适用于任何平台的 VNC。(不过 VNC 的响应速度不是特别快)

1

一般来说,逐字节比较在所有情况下都不是最有效的方式。你可以使用这段代码 来自这篇文章 来检查图片之间的差异。你可以根据自己的需要进行定制,以查看差异具体在哪里。

from itertools import izip
import Image

i1 = Image.open("image1.jpg")
i2 = Image.open("image2.jpg")
assert i1.mode == i2.mode, "Different kinds of images."
assert i1.size == i2.size, "Different sizes."

pairs = izip(i1.getdata(), i2.getdata())
if len(i1.getbands()) == 1:
    # for gray-scale jpegs
    dif = sum(abs(p1-p2) for p1,p2 in pairs)
else:
    dif = sum(abs(c1-c2) for p1,p2 in pairs for c1,c2 in zip(p1,p2))

ncomponents = i1.size[0] * i1.size[1] * 3
print "Difference (percentage):", (dif / 255.0 * 100) / ncomponents

另外,可以看看 filecmp.cmp() 这个函数,它在 filecmp 包 中,可能会对你有帮助。

更新

我在尝试找出比较两张图片的最快方法:逐像素比较使用PIL库,或者使用统计技术,但我没有注意到性能上有很大的差别。问题可能和图片的大小有关。

from PIL import Image, ImageChops

pixelsDifference = ImageChops.difference(Image.open('image1.png'), Image.open('image2.png')).convert('L')
pixelsDifference = pixelsDifference.point(([0] + ([255] * 255)))
Img = pixelsDifference.convert('RGB')

撰写回答