1

I want to take a screenshot of the screen and save it to a buffer as a photo(X.jpg) and later I can use the cv2(opencv) to read the same image from the buffer.
i act as follow:

Edit My code:

from PIL import ImageGrab
from io import BytesIO

ii = ImageGrab.grab()
with BytesIO() as output:
    ii.save(output,format="JPEG")# This line has an error 
    cam = output.getvalue()
result, frame = cv2.imencode('.jpg', cam, encode_param)

i get this Errors:

TypeError: img is not a numpy array, neither a scalar

thank you

Community
  • 1
  • 1
jozef
  • 41
  • 7
  • go through this [link](https://stackoverflow.com/questions/3260559/how-to-get-a-window-or-fullscreen-screenshot-in-python-3k-without-pil) – sahasrara62 Dec 17 '18 at 17:40
  • Can you explain what the problem is and show any error messages you get? Also comments in python start with # not // – Silas Coker Dec 17 '18 at 17:40
  • Possible duplicate of [How to Get a Window or Fullscreen Screenshot in Python 3k? (without PIL)](https://stackoverflow.com/questions/3260559/how-to-get-a-window-or-fullscreen-screenshot-in-python-3k-without-pil) – sahasrara62 Dec 17 '18 at 17:43
  • i edited my question – jozef Dec 17 '18 at 18:09
  • If you already saved it to disk as JPEG, why not just read the contents of the file directly into a buffer (rather than decoding it by `imread` and then encoding back with `imencode`)? Or even better, it's [trivial](https://stackoverflow.com/q/384759/3962537) to convert PIL image to a numpy array. Then just directly `imencode` that, instead of the round trip to the filesystem. – Dan Mašek Dec 17 '18 at 19:11
  • @Dan Mašek i want to send screenshot to another system by socket,i want to save that screenshot to buffer so i can read and send by socket,you say i can convert PIL image to numpy array, How? The point here is how can I convert a grabed image into numpy array? – jozef Dec 17 '18 at 19:22
  • It's explained in the post I refer to. Or you can even just use [PIL to encode to a buffer](https://stackoverflow.com/questions/646286/python-pil-how-to-write-png-image-to-string). – Dan Mašek Dec 17 '18 at 19:30
  • @Dan Mašek According to [PIL to encode to a buffer](https://stackoverflow.com/questions/646286/python-pil-how-to-write-png-image-to-string) i get this error `TypeError: img is not a numpy array, neither a scalar` – jozef Dec 17 '18 at 19:54
  • If you changed your code, and are getting a different error, then [edit] the question and update it appropriately. – Dan Mašek Dec 17 '18 at 19:59
  • @Dan Mašek i edit my question – jozef Dec 17 '18 at 20:10
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/185377/discussion-between-jozef-and-dan-masek). – jozef Dec 17 '18 at 20:11
  • The last line is redundant, `cam` already is a buffer containing the JPEG stream, so there's no point trying to encode it again with `cv2.imencode`. If it's the `save` that's failing... whoa... maybe the `grab()` failed to get anything? – Dan Mašek Dec 17 '18 at 20:14
  • @Dan Mašek The `grab()` is work correctly because whene i use `ii.save("E:\\aaa.jpg",format="JPEG",quality=100,optimize=True)` I do not get any errors and everything works properly – jozef Dec 17 '18 at 20:25
  • Sorry, can't reproduce that problem locally, works as expected. – Dan Mašek Dec 17 '18 at 20:34
  • @Dan Mašek Thank you for the time you spent – jozef Dec 17 '18 at 20:42

1 Answers1

2

Here is a demo:

from PIL import ImageGrab
from io import BytesIO
import numpy as np 
import cv2

## (1) Grab the rgb frame as PIL.Image
ii = ImageGrab.grab()
print(type(ii)) # <class 'PIL.Image.Image'>

## (2) Convert PIL.Image to np.array 
rgb = np.array(ii)
print(type(ii)) # <class 'numpy.ndarray'>

## (3) Convert into BGR and display 
bgr = cv2.cvtColor(rgb, cv2.COLOR_RGB2BGR)
cv2.imshow("frame", bgr)
cv2.waitKey()
cv2.destroyAllWindows()
Kinght 金
  • 17,681
  • 4
  • 60
  • 74