Pygame : Getting rid of strange gradient effect on displayed image - python

Hello fellow programmers,
I wrote a little python program which is use to launch random games on a retrograming distribution, and I use pygame to display the image of the game before launching it
I use a background and my issue is that the background image is clean but when displaying it and the cover of the game over it, it appears with a strange ugly gradient effect as you can see there : https://imgur.com/a/BnNdoqn
It appears mostly in the corner and the cover itself is entirely unaffected.
Here is my pygame code displaying both images :
log('showPic %s' %file)
# INITS
pygame.init()
pygame.mouse.set_visible(0)
backgroundPicture = pygame.image.load(backgroundFile)
picture = pygame.image.load(file)
# # CREATE FULLSCREEN DISPLAY. X = 1920- Y = 1080
fullscreen = pygame.display.set_mode((1920,1080), FULLSCREEN)
fullscreen.blit(backgroundPicture, (0,0))
# # PASTE PICTURE ON FULLSCREEN
x = (1920 - picture.get_width()) /2
y = (1080 - picture.get_height()) /2
fullscreen.blit(picture, (x,y))
# # SHOW FULLSCREEN
pygame.display.flip()
# # WAIT 5 SECONDS (need import time)
time.sleep(5)
# # EXIT PYGAME (Not needed but recommanded)
pygame.display.quit()
pygame.quit()
backgroundPicture is the background image and picture is the cover of the game, I combined the too like it appears in second capture.
So mainly I don't know much at all about display, images, graphical libraries and all that.
I think that this might be related to transparency or alpha layer or compression format of the image but I have no knowledge at all about that either.
The code is launched on a raspberry pi with a linux distribution, don't know much more about it.
Also strangely, one of my users said the strange gradient effect seems to disappear after ten or so launches of the script, but I couldn't reproduce that.
So what am I missing to get rid of that ugly effect ?
Here is the background image here if its characteristic might be related to the problem :
Thank you for your help !

The effect you are seeing is called "banding", see Wikipedia article. It is caused by not having enough bit-depth to represent fine gradations of colour and is most noticeable in large, untextured areas.
There are not many things you can do about it. Your options are basically:
to go to a 16-bit setup instead of 8-bit, if pygame can do that, or
add a small amount of random noise, or dithering to break it up.

Related

Pygame/MoviePy - The video displays with a terrible framerate and the window size is bigger than my screen [duplicate]

This question already has answers here:
How to load and play a video in pygame
(3 answers)
Closed last year.
I've been looking around for a while trying to find a way to display videos in Pygame because of a new story video-game project. I finally stumbled across Moviepy which works alright...except that the video displays showing only one of the 24 frames each second and the window it displays in is bigger than by screen.
(on a Windows 10 laptop with an 11inch(I think) screen)
The sound is alright but the video also goes too fast so is out of sync.
I've tried the resize function as said on the docs but it gives no effect.
And I can't find anything to do with the framerate.
So I need a way to make the window smaller and correct the framerate.
This is the code I used:
from moviepy.editor import VideoFileClip
from moviepy.video.fx.resize import resize
import pygame
pygame.display.set_caption('My video!')
clip = VideoFileClip('Eleeza Crafter And The Cloud Colours Trailer.mp4')
clip.fx(resize, width=240)
clip.preview(fps=24)
pygame.quit()
Any help would be appreciated. Thanks :)
EDIT: I tested a different video at the same framerate and it works perfectly?
Then again it was just a simple line flying around the screen.
A 2 seconds google gave me this link.
It states :
A clip can be previewed as follows
my_clip.preview() # preview with default fps=15
my_clip.preview(fps=25)
my_clip.preview(fps=15, audio=False) # don't generate/play the audio.
my_audio_clip.preview(fps=22000)
Also (depending of your import method:
This way you can use clip.resize(width=240) instead of the longer clip.fx( resize, width=240).
Still from the documentation:
For advanced image processing you will need one or several of these packages. For instance using the method clip.resize requires that at least one of Scipy, PIL, Pillow or OpenCV are installed.
I don't know if this is the problem, but for screen size you should use pygame.display.set_mode((WIDTH, HEIGHT)) (change the WIDTH value to your desired width and the HEIGHT value to your desired height. Also, something I have noticed with pygame is that the big windows have lots of lag, so maybe a smaller window size would be recommended. I find that 500x500 is the maximum size for no lag (at least on my laptop)

Code changes - Python - Piphone - Raspberry Pi

Right now I'm working hard to finish a project named Pihpone; I've been following the adafruit tutorial and I've also bought all the items that were suggested by them
The problem is that..the code was written for 2,8" while I have a 3.5" screen
I've succeeded in making some changes like modifying the 320x240 with 480x320
Still not enough but I dont know what to do further; pls come with any suggestion;
Here are the screenshots:
Before
After
https://github.com/climberhunt/Piphone/archive/master.zip
From there you can download the code made by Adafruit; you can find the code in piphone.py.
The code in piphone.py appears to be using the pygame module to do the graphics. The problem is all the hardcoded coordinates and sizes for things like the Buttons. To fix this, the values must be computed at run-time and depend on the display resolution. Line 255 sets the display mode.
screen = pygame.display.set_mode(modes[0], FULLSCREEN, 16)
After doing that, you can get a video display information object from pygame.display.Info() and obtain the width and height of the current video mode, then use those values to scale and position the buttons.
You may also need to create different sets of image files for the various sizes of display you want the program to support.

pygame.error No video mode large enough

I have been working on a game using the pygame module for python and am having an issue getting it to display properly on other computers. When I first starting writing I chose a resolution of (1400,1000). There was no real reason for this choice, I was/am new to programming and it seemed like a nice round number. The issue I am having is that on many laptops the screen is bigger than the max resolution. I can run it in windowed mode but then the screen runs off to the right and the bottom and there are things that the user cannot see. I then tried to run it in full screen mode, but then I get the error message "pygame.error No video mode large enough for 1400 , 1000"
The most obvious solution is to reduce my screen resolution I suppose, but all my GUI menu buttons are blitted to the screen assumming a resolution of (1400,1000) and changing everything would be extremely tedious.
The most curious thing happens when I connect a USB moniter with a resolution high enough to display it properly; The game will display properly on the connected moniter, and will also resize itself to display properly on the laptop moniter as well!. I can then disconnect the other moniter and go about playing the game no problem!
If I could somehow "trick" the computer into thinking there is a moniter connected with a proper resolution everything would work perfect. Not a perfect or elegant solution I admit, but I loathe having to go back and redo my entire GUI...
size = (1400, 1000)
screen = pygame.display.set_mode(size,pygame.FULLSCREEN)
Read up on pygame.org/docs
pygame.display.set_mode() will use your current screen resolution automatically, no matter what computer you are on as long as you don't pass in any parameters.
As to why 1400 by 1000 wasn't working for you, that is not a common screen resolution (not even sure if it exists). Some common ones include:
1280 by 720
1600 by 900
1920 by 1200
"The most obvious solution is to reduce my screen resolution I suppose, but all my GUI menu buttons are blitted to the screen assumming a resolution of (1400,1000) and changing everything would be extremely tedious."
A way to avoid this issue is to work in terms of your screen area. For example, lets say I work in a resultion of 1280 by 800.
width = 1280
height = 800
screen = pygame.display.set_mode([width, height])
I want my position to be in the middle of the screen. Instead of saying
position = 1280 / 2 # Hardcoded
do
position = width/2
Now no matter what you change your screen width to, your position will be preserved. I recommend looking into http://www.pygame.org/docs/ref/rect.html for information about how to track locations in pygame in a nice way.
About the flags: I don't know much about these so I won't say much, other than that I never use them and don't have any issues doing anything.
I hope this helps
```
from win32api import GetSystemMetrics
width = GetSystemMetrics(0)
height = GetSystemMetrics(1)
size = (width, height)
```
I would try to incorporate this into into your code

Pygame bliting scaled image

When i try to blit an image in pygame the image blits smaller than the actual image, my simplified code is
import pygame
pygame.init()
screen = pygame.display.set_mode((1176,674),0,32)
background = pygame.image.load("picture.jpg").convert()
while True:
screen.blit(background, (0,0))
pygame.display.flip()
The resulting image is about half the size it should be
It is entirely possible that when you view it you have zoomed in. Or there could be formatting irregularities. Either way, there are two simple solutions. Solution number 1 is to just scale up the image in an image editor, if you don't have one, GIMP is free online. A better way is to scale it in the code. You can just double the size of an image you loaded with this modification to your code, solving your problem. Use pygame.transform:
import pygame
pygame.init()
screen = pygame.display.set_mode((1176,674),0,32)
background = pygame.image.load("start_screen.jpg").convert()
background = pygame.transform.scale(background, (1176,674))
while True:
screen.blit(background, (0,0))
pygame.display.flip()
this should work
I found that the issue came from my MacBooks retina screen resolution, once i downloaded a program to adjust the resolution the program worked properly

How would you draw multiple screens in PyGame (in only one window)?

I'm trying to port over some code from Javascript to Python, and I'm having trouble even figuring out where to start. I've looked at a good dozen tutorials for PyGame, but none of them seem to click for me. So, I was hoping to get a quick example here, or at least a point in the right direction.
I'm wanting to make a number of screens I can switch back and forth between, depending on what the user is doing at the time, and even display two side by side. At the moment, all I've got is some Javascript that draws random circles onto the screen. The PyGame logic is the only thing I'm having trouble with.
Here's my javascript for reference.
You can create a Subsurface for each subscreen that you want to create.
Then you may treat each as if it were a full screen / single surface, yet they still reference the original screen.
Pygame is a wrapper for SDL. SDL uses a surface to represent a bitmap, or anything that can be drawn on screen. With the pygame.display.set_mode((w,h),0,d) you can get the surface, or the whole canvas. You can then draw or blit the other surfaces and then call flip(), to show changes. If you wish to have a few screens, you could have a current state number, and blit the screens accordingly.
For example:
if(current_state == MAIN_SCREEN):
drawAll(screen)
else
drawEnemiesOnly(screen)
you could change the screens with the number keys:
for event in pygame.event.get():
if event.type == KEY_DOWN:
if(event.key == K_1):
current_state = 1

Categories

Resources