How to display a loaded image on a pygame.Overlay() - python

I am trying to use overlays in pygame to display video. The trouble is that my frames are loaded as RGB Surface()s while Overlay().display() requires YUV format.
I saw that pygame.camera module contains a colorspace() function that should be able to convert RGB Surface() to YUV one. Does anyone know how to do the trick? The conversion and the displaying?
pygame.camera.colorspace() is not very well documented.
If this doesn't work, does anyone know how to do this by using PIL to convert to YUV?

I haven't had much time to play with .Overlay()
but the colorspace function seems to go as follows:
yuv_surface = pygame.camera.colorspace(rgb_surface,"YUV")
This example runs without error:
import pygame
import pygame.camera
pygame.init()
pygame.camera.init()
screen = pygame.display.set_mode((400,400))
rgb_surface = pygame.Surface((400,400))
yuv_surface = pygame.camera.colorspace(rgb_surface,"YUV")
screen.blit(yuv_surface,(0,0))
clock = pygame.time.Clock()
while True:
pygame.display.flip()
clock.tick(30)

Related

Pygame cam.get_raw() returns None

I'm fairly new to useing pygame and I'm trying to take a picture from the webcam and saving it as a png file. This is my code:
import pygame
import pygame.camera
from pygame.locals import *
pygame.init()
pygame.camera.init()
cam = pygame.camera.Camera('Integrated Webcam',(640,480))
cam.start()
image = cam.get_image()
pygame.image.save(image, 'test.png')
print(cam.get_raw())
This prints out None and the png file that it creates is completely black
Problem is solved, needed to pause for about .65 seconds to give time for the camera to power on.

How to display Images loaded with Pillow with Pygame in Python 3.7?

I imported an image to my project using
from PIL import Image
myImage = Image.open("myImageDirectory.png")
So myImage is now imported as a png file. But I want to display it to the Screen using Pygame. Normally I use
import pygame
win = pygame.display.set_mode((500, 500))
win.blit(myImage, (50, 50))
Now I get the Error that the function needs a surface, not a png File.
Has anyone an idea how I can convert the image to a surface or how I can display it?
I tried not much yet​ because I didn't found anything that could solve my problem.
Edit:
What is wrong with this way that I get the error: Couldn't open bg.png
See PIL and pygame.image. Use Image.tobytes() get the image data as a bytes object and pygame.image.fromstring() to load the data to an pygame.Surface object:
from PIL import Image
import pygame
pilImage = Image.open("myImageDirectory.png")
myImage = pygame.image.fromstring(pilImage.tobytes(), pilImage.size, pilImage.mode)

pygame with FULLSCREEN flag renders content scaled

I'm using pygame on a raspberry pi.
This same code used to cover the full screen at 800x600, now, at 1280x720 it doesn't, and it's not over/underscan:
Pygame example output:
Video playback via omxplayer:
All the code in the pygame example image is just a demo for the problem:
import pygame
import time
pygame.display.init()
pygame.font.init()
screen = pygame.display.set_mode((1280, 720)) #, pygame.FULLSCREEN)
screen.fill((255, 0, 0))
pygame.display.flip()
time.sleep(45)
You can use the list_modes function which returns a list of available full screen resolutions:
modes = pygame.display.list_modes()
if modes: # check if the list is not empty
screen = pygame.display.set_mode(modes[0], pygame.FULLSCREEN) # use the first one
else:
screen = pygame.display.set_mode((800, 600)) # use a default resolution
Note: if you have problems with high DPI scaling on Windows (e. g. a part of your display is not visible), you can use this code to fix them:
import ctypes
ctypes.windll.shcore.SetProcessDpiAwareness(1)

display cv2.VideoCapture image inside Pygame surface

I'm trying to use opencv (cv2) to stream a webcam feed into a pygame surface object. The problem is the colors aren't displaying correctly. I think it is the type casting, but I'm having trouble understanding the pygame surface documentation to know what it expects.
This code demonstrates what I'm talking about
import pygame
from pygame.locals import *
import cv2
import numpy
color=False#True#False
camera_index = 0
camera=cv2.VideoCapture(camera_index)
camera.set(3,640)
camera.set(4,480)
#This shows an image the way it should be
cv2.namedWindow("w1",cv2.CV_WINDOW_AUTOSIZE)
retval,frame=camera.read()
if not color:
frame=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
cv2.flip(frame,1,frame)#mirror the image
cv2.imshow("w1",frame)
#This shows an image weirdly...
screen_width, screen_height = 640, 480
screen=pygame.display.set_mode((screen_width,screen_height))
def getCamFrame(color,camera):
retval,frame=camera.read()
if not color:
frame=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
frame=numpy.rot90(frame)
frame=pygame.surfarray.make_surface(frame) #I think the color error lies in this line?
return frame
def blitCamFrame(frame,screen):
screen.blit(frame,(0,0))
return screen
screen.fill(0) #set pygame screen to black
frame=getCamFrame(color,camera)
screen=blitCamFrame(frame,screen)
pygame.display.flip()
running=True
while running:
for event in pygame.event.get(): #process events since last loop cycle
if event.type == KEYDOWN:
running=False
pygame.quit()
cv2.destroyAllWindows()
The ultimate goal I have is to create a small photo booth application for a DIY wedding next year. I'm new to programming, but I've managed to cobble this together. I was also trying to accomplish this with VideoCapture, which outputs a PIL, which I also couldn't get to work with the surface object. I want to use a pygame surface so I can animate and overlay count-down text, borders, etc.
Update: The issue was that the cv2 function camera.read() returns a BGR image, but the pygame.surfarray expects a RGB image. This is fixed with the line
frame=cv2.cvtColor(frame,cv2.COLOR_BGR2RGB)
Also, when converting to grayscale, the following code works:
frame=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
frame=cv2.cvtColor(frame,cv2.COLOR_GRAY2RGB)
So, the function getCamFrame should now be
def getCamFrame(color,camera):
retval,frame=camera.read()
frame=cv2.cvtColor(frame,cv2.COLOR_BGR2RGB)
if not color:
frame=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
frame=cv2.cvtColor(frame,cv2.COLOR_GRAY2RGB)
frame=numpy.rot90(frame)
frame=pygame.surfarray.make_surface(frame)
return frame
No the color error lies in here
frame=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
so for normal screen color u simply change that to
frame=cv2.cvtColor(frame,cv2.COLOR_BGR2RGB)
That will do because it works for me
I tried your code, but I'm only getting a picture not a movie, so i copied
frame=getCamFrame(color,camera)
screen=blitCamFrame(frame,screen)
pygame.display.flip()
into a while loop, it worked but then the video was flipped, to fix it i added cv2.flip(frame,1,frame) # mirror the image
before
frame=numpy.rot90(frame) in getcamFrame function and now everything works fine.
Sorry for the poor English.
This worked for me
to adapt it in your code ...
windowSurface = screen #or use directly variable screen
# convert windowSurface to cv2 ------------------------------------
view = pygame.surfarray.array3d(windowSurface)
# convert from (width, height, channel) to (height, width, channel)
view = view.transpose([1, 0, 2])
# convert from rgb to bgr
img_bgr = cv2.cvtColor(view, cv2.COLOR_RGB2BGR)
cv2.imshow('windowname',img_bgr)
cv2.waitKey(10)

python pygame blit. Getting an image to display

I'm trying to get my webcam to show video through pygame. Here is the code:
# import the relevant libraries
import time
import pygame
import pygame.camera
from pygame.locals import *
# this is where one sets how long the script
# sleeps for, between frames.sleeptime__in_seconds = 0.05
# initialise the display window
pygame.init()
pygame.camera.init()
screen = pygame.display.set_mode((640, 480), 0, 32)
# set up a camera object
cam = pygame.camera.Camera(0)
# start the camera
cam.start()
while 1:
# sleep between every frame
time.sleep( 10 )
# fetch the camera image
image = cam.get_image()
# blank out the screen
screen.fill((0,0,2))
# copy the camera image to the screen
screen.blit( image, ( 0, 0 ) )
# update the screen to show the latest screen image
pygame.display.update()
When i try this I get an error from the screen.blit( image, ( 0, 0 ) ) part
Traceback (most recent call last):
File "C:\Python32\src\webcam.py", line 28, in <module>
screen.blit( image, ( 0, 0 ) )
TypeError: argument 1 must be pygame.Surface, not None
I assume It's because I didn't convert the image into whatever works with pygame, but i don't know.
Any help would be appreciated.Thanks.
-Alex
OK so here is the new code:
This one works because it saves the picture to the current folder. figured out why the last one work. the screen is still black although=\
# import the relevant libraries
import time
import pygame
import pygame.camera
from pygame.locals import *
# this is where one sets how long the script
# sleeps for, between frames.sleeptime__in_seconds = 0.05
# initialise the display window
pygame.init()
pygame.camera.init()
# set up a camera object
size = (640,480)
screen = pygame.display.set_mode(size,0)
surface = pygame.surface.Surface(size,0,screen)
cam = pygame.camera.Camera(0,size)
# start the camera
cam.start()
while 1:
# sleep between every frame
time.sleep( 10 )
# fetch the camera image
pic = cam.get_image(surface)
# blank out the screen
#screen.fill((0,0,0))
# copy the camera image to the screen
screen.blit(pic,(0,0))
# update the screen to show the latest screen image
p=("outimage.jpg")
pygame.image.save(surface,p)
pygame.display.update()
Try creating a Camera like this.
cam = pygame.camera.Camera(camlist[0],(640,480))
That's how it's done on this page of the pygame docs.
Looking at the API page for pygame.camera, I found two things that might help. First,
Pygame currently supports only Linux and v4l2 cameras.
EXPERIMENTAL!: This api may change or disappear in later pygame
releases. If you use this, your code will very likely break with the
next pygame release.
Keep that in mind when wondering why this surprisingly fails.
On a more up-beat note... you can try calling camera.get_raw() and printing the result. It should be a string with raw image data. If you get an empty string, None, or some non-sense text: please share that with us here. It'll tell if you're getting anything from the camera.
Gets an image from a camera as a string in the native pixelformat of the camera. Useful for integration with other libraries.

Categories

Resources