简体   繁体   中英

Python screen capture error

I am trying to modify the code given here for screen streaming. In the above tutorial it was for reading images from disk whereas I am trying to take screenshots. I receive this error.

assert isinstance(data, bytes), 'applications must write bytes' AssertionError: applications must write bytes

What changes should I make for it to work?

This is what I've done so far -

<br>index.html<br>
<html>
  <head>
    <title>Video Streaming Demonstration</title>
  </head>
  <body>
    <h1>Video Streaming Demonstration</h1>
    <img src="{{ url_for('video_feed') }}">
  </body>
</html>


app.py

#!/usr/bin/env python
from flask import Flask, render_template, Response
import time
# emulated camera
from camera import Camera

# Raspberry Pi camera module (requires picamera package)
# from camera_pi import Camera

app = Flask(__name__)


@app.route('/')
def index():
    """Video streaming home page."""
    return render_template('index.html')


def gen(camera):
    """Video streaming generator function."""
    while True:
        time.sleep(0.1)
        frame = camera.get_frame()
        yield (frame)


@app.route('/video_feed')
def video_feed():
    """Video streaming route. Put this in the src attribute of an img tag."""
    return Response(gen(Camera()),
                    mimetype='multipart/x-mixed-replace; boundary=frame')


if __name__ == '__main__':
    app.run(host='0.0.0.0', debug=True, threaded=True)


camera.py

from time import time

from PIL import Image
from PIL import ImageGrab
import sys

if sys.platform == "win32":
    grabber = Image.core.grabscreen

class Camera(object):

    def __init__(self):
        #self.frames = [open('shot0' + str(f) + '.png', 'rb').read() for f in range(1,61)]
        self.frames = [ImageGrab.grab() for f in range(1,61)]

    def get_frame(self):
        return self.frames[int(time()) % 3]

Full error : Link

The response payload must be a sequence of bytes. In the example, the images returned are JPEGs as bytes objects.

However, the image returned by ImageGrab.grab() is some PIL image class instead of bytes. So, try saving the image as JPEG as bytes :

import io

Take screenshot only for every iteration in gen:

class Camera(object):
    def get_frame(self):
        frame = ImageGrab.grab()
        img_bytes = io.BytesIO()
        frame.save(img_bytes, format='JPEG')
        return img_bytes.getvalue()

gen function:

def gen(camera):
    while True:
        time.sleep(0.1)
        frame = camera.get_frame()
        yield (b'--frame\r\n'
               b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM