将图像转换为二进制流

时间:2014-04-22 16:54:58

标签: python django image image-processing python-imaging-library

我的应用程序有两个方面,一方面我使用C ++来使用Pleora的EBUS SDK从相机读取帧。当首次接收到该流时,在将缓冲区转换为图像之前,我能够一次读取16位流,以便为每个像素执行一些计算,即每个像素存在16位数据块

现在下半部分是一个Django网络应用程序,我也提供了这个视频输出,这次是通过ffmpeg,nginx,hls流。当用户点击视频时,我希望能够获取当前帧及其点击的坐标,并执行与上述C ++部分相同的计算。

现在我使用html5画布捕获帧,我使用canvas.toDataURL()将帧转换为base64编码图像,然后传递base64图像,坐标和框架的尺寸通过AJAX到python。

在python中,我试图以每像素16位的方式操作这个base64编码的图像。目前我做了以下事情:

pos = json.loads(request.GET['pos'])
str_frame = json.loads(request.GET['frame'])
dimensions = json.loads(request.GET['dimensions'])

pixel_index = (dimensions['width'] * pos['y']) + pos['x'] + 1

b64decoded_frame = base64.b64decode(str_frame.encode('utf-8'))

然而,b64decoded_frame中的索引要少得多,那么图像中就有像素,而整数值并不像预期的那么高。我已经检查过,图像完好无损,因为我可以将其保存为png。

总结一下,如何将base64图像转换为序列化二进制流,其中每个像素由16位表示。

更新

我忘了提到我正在使用python3.2

经过一些更多的研究后,我认为我正在尝试做的是获得给定像素的mono16值。我不确定这是否是我想做的,但如果有人能解释如何将图像转换为mono16或像素转换为mono16我可以探索它,看看它是否实际上是解决方案。

1 个答案:

答案 0 :(得分:0)

我选择的解决方案是将图像转换为8位灰度图像,然后将所需像素转换为16位对应图像。解决方案如下所示:

import base64
import io
from PIL import Image

if request.method == 'GET':
    if request.GET['pos'] and request.GET['frame']:
        pos = json.loads(request.GET['pos'])
        str_frame = json.loads(request.GET['frame'])

        # Converts the base64 string into a byte string, we need to encode
        # str_frame as utf-8 first otherwise python3.2 complains about unicode
        b64decoded_frame = base64.b64decode(str_frame.encode('utf-8'))

        # This puts the decoded image into a buffer so that I don't need to save
        # it to disk to use it in PIL
        byte_stream = io.BytesIO(b64decoded_frame)

        # Open the image and convert it to 8-bit greyscale (mono8)
        img = Image.open(byte_stream).convert('L')

        # Get the 8-bit pixel value
        pixel_val = img.getpixel((pos['x'], pos['y']))

        # Convert the 8-bit pixel value to 16-bit by holding the rations
        # i.e. n8 / (2^8 - 1) == x16 / (2^16 - 1)
        pixel_val = int(pixel_val / 255 * 65535)