I create a screen in pygame using:
screen = pygame.display.set_mode((width,height))
Then I draw 200 random gray scale circles on it and save the screen as an image. (I need to save this screen as an image so I can compare it to a target image later on):
pygame.image.save(screen, "Circles.png")
Now, I need to randomly change different parameters of different circles by putting the numpy array that contains the circle parameters for all the circles in a loop with a big number as its iteration value.
And I need to redraw the mutated circles on a screen (at the end of each iteration) and save that screen as a png image again.
Now the problem is, every time I use pygame.display.set_mode((width,height)) it opens up the display window and it significantly slows down my program.
I would like to create a screen and save it in a variable but don't need to display that screen at each iteration. I haven't been able to figure out what command to use to avoid displaying the screen.
I appreciate your help.
If you don't want a window to appear, try creating the surface like this:
screen = pygame.Surface((width,height))
Then you can draw your circles on this surface and save it the same way as you did before. As others have said, clear the surface with the fill() method.
I would probably end up using something like this. This will still popup a screen but it will be tiny and never updated.
import pygame
from pygame.locals import *
pygame.init()
def circle_drawing(surf):
pass
#your circle drawing function using passed in surface
DISPLAY = (1, 1)
DEPTH = 32
FLAGS = 0
screen = pygame.display.set_mode(DISPLAY, FLAGS, DEPTH)
work_surface = pygame.Surface((500,500))
count = 0
while True:
ws = circle_drawing(work_surface.copy())
pygame.image.save(ws, "circles_" + str(count)+".png")
count +=1
Related
I have a game I'm currently working on, and it uses multiple views (for a minimap for example).
Thing is, I would like to have a fading effect added at some point, so I thought I'd create a black image that is the size of the screen and change its alpha value with a timer. That part is not a problem.
What happens right now is the main area (ie window default view) is fading (because the opacity of the image is increasing), but the minimap (minimap view) is unaffected. This is normal behaviour for views, but is there a way to draw an image to the whole window, regardless of the views ?
Thanks in advance
To clarify, you have the default view where you'll draw the main game, then you'll have the minimap view where you would draw the minimap. At some point in the game you want the whole screen to fade to black. It sounds like you've been trying to draw a black image on the default view (changing the alpha) to make this effect work.
So, you need a third view that you draw your black image on to get this fading effect.
I am trying to record sound from mic using pyaudio and plotting it at the same time (in parallel with recording).
I have created a horizontal plot window, who's size is bigger than the main application window.
Code section:
self.fig, self.ax1 = plt.subplots()
rect = self.fig.patch
rect.set_facecolor('white')
#self.ax1.autoscale_view(True,True,True)
self.ax1.set_autoscale_on(True)
plt.subplots_adjust(left=0.0, bottom=0.0, top=0.95, right=10.0)
I am not able to move plot area to the current location of plotting or may be at the end of horizontal plot window. I also tried to use scrolled window. That also didn't work.
any idea?
I'm working on a slideshow app and using SDL 1.2 using a custom dispmanx backend (https://github.com/vanfanel/SDL12-kms-dispmanx) with Pygame to create overlays on top of omxplayer.
It all works well and layers correctly, but I can't seem to make a transparent canvas in dispmanx without making my objects transparent as well. My understanding is Pygame itself cannot handle this and it is up to SDL to handle transparency between dispmanx layers.
My goal is a hardware accelerated transparent canvas the size of my screen above omxplayer that I can draw on.
I suspect there must be a method other than using the alpha settings in vc_dispmanx_element_add to do this? XBMC uses dispmanx and can do opaque overlays above omxplayer, so this must be possible. I've also looked at vc_dispmanx_display_set_background, but this seems to only take RGB and not an alpha.
Rather than creating a transparent window u could take a screenshot of the window and use it as a background. To do this i used pyscreenshot to take the image (though there are other options) and
os.environ['SDL_VIDEO_WINDOW_POS']="0,0"
to make sure the window is in the right spot every time, the only weakness to this is that the window is no longer transparent if something changes behind it
Check out my library built for exactly this use case: https://github.com/dtcooper/python-dispmanx
You can use pygame as follows,
from random import randint
import pygame
from dispmanx import DispmanX
# Generate a random color with alpha compontent
def random_color_with_alpha():
return tuple(randint(0, 0xFF) for _ in range(3)) + (randint(0x44, 0xFF),)
display = DispmanX(pixel_format="RGBA")
surface = pygame.image.frombuffer(
display.buffer, display.size, display.pixel_format
)
clock = pygame.time.Clock()
for _ in range(20):
surface.fill(random_color_with_alpha())
display.update()
clock.tick(2)
Alternately, there's an another C Python extension that I didn't write that also functions the same way: https://github.com/eclispe/pyDispmanx
I'm using two bitmaps to draw graphs on them. After drawing I need to show bitmap pictures in two Images. Assigning bitmap to Image or drawing bitmap to Image sometimes causes Image to disappear (you can see form background).
I have tried this:
Image->Picture->Bitmap->Assign(bitmap1);
Image2->Picture->Bitmap->Assign(bitmap2);
Image->Picture->Graphic = bitmap1;....
Image->Canvas->Draw(0,0,bitmap1);....
Image->Picture->Bitmap->Canvas->Draw(0,0,bitmap1);
If I don't have Sleep(100) between Image and Image2 redrawing, Image2 isn't visible for the most of the time. Also adding Image2->Refresh helps, but the issue still sometimes occurs to both Images.
If I save created bitmaps or Images to .jpeg files, all .jpeg images are correct and none of them are empty. Also Image->height, Image->picture->bitmap->height and width is always correct.
Can anyone tell me, what I'm doing wrong?
After a while I realised, that bitmaps and Images, which I saved, weren't all correct. If I was unable to see picture, it wasn't fully drawn. There were no errors, it occurred randomly, but I found out, that once program started to ignore my drawing commands, it didn't draw anything until the end of the function, which does drawing.
So - to check, if I can still draw, before assigning bitmap to Image, I did this:
Image3->Canvas->Pixels[y][0] = clRed;
TColor test = Image3->Canvas->Pixels[y][0];
Image3->Canvas->TextOut(y, 0, Device1->name);
TColor test2 = Image3->Canvas->Pixels[y][0];
if(test == test2)
{
imageUpdated = false;
delete Image3;
return;
}
Image->Picture->Graphic = Image3;
imageUpdated = true;
It means - I changed one pixel red, and after that printed over text, which should make that changed pixel white. Based on that I checked, if the color changed (was able to change pixel color and print text).
I really don't know reason, why it sometimes starts to ignore drawing commands, but I hope, that if someone runs into the same issue as I did, this answer might help him/her.
I'm new to Qt development so I've being trying to research a solution to a user interface I need to design. My project is to simulate players in an online game moving around a global map. To represent the map I need to display a 2D grid, with each space in the grid representing a region of a map. I then need to display the location of each player in the game. The back-end is all fully working, with the map implemented as a 2D array. I'm just stuck on how to display the grid.
The research I have done has led me to believe a QGraphicsView is the best way to do this, but I can't seem to find a tutorial relevant to what I need. If anyone has any tips on how to implement this it would be much appreciated.
Thanks, Dan
A 2D Grid is nothing more than a set of horizontal and vertical lines. Suppose you have a 500x500 map and you want to draw a grid where the distance between the lines in both directions is 50. The sample code that follows shows you how you can achieve it.
// create a scene and add it your view
QGraphicsScene* scene = new QGraphicsScene;
ui->view->setScene(scene);
// Add the vertical lines first, paint them red
for (int x=0; x<=500; x+=50)
scene->addLine(x,0,x,500, QPen(Qt::red));
// Now add the horizontal lines, paint them green
for (int y=0; y<=500; y+=50)
scene->addLine(0,y,500,y, QPen(Qt::green));
// Fit the view in the scene's bounding rect
ui->view->fitInView(scene->itemsVBoundingRect());
You should check the QGraphicsView and the QGraphicsScene documentation as well as the corresponding examples. Also you can watch the graphics view training videos or some graphics view related videos from the Qt developer days.
Well if you have a constant grid size or even a limited number of grid sizes what i like to do is to draw a grid block in gimp or any other program and then set that as the background brush (draw only bottom and right side of the block) qt will repeat the image and will give you a full grid. I think this is good for performance too.
This is the grid image i used in one of my programs it's 10x10 pixels.
Then call QGraphicsScene setBackgroundBrush as the follwing:
scene->setBackgroundBrush(QBrush(QPixmap(":/grid/grid10.png")));
The more native way is this:
scene = self.getScene() # Your scene.
brush = QBrush()
brush.setColor(QColor('#999'))
brush.setStyle(Qt.CrossPattern) # Grid pattern.
scene.setBackgroundBrush(brush)
borderColor = Qt.black
fillColor = QColor('#DDD')
rect = QRectF(0.0, 0.0, 1280, 720) # Screen res or whatever.
scene.addRect(rect,borderColor,fillColor) # Rectangle for color.
scene.addRect(rect,borderColor,brush) # Rectangle for grid.
Sorry by PyQt...
Suppose a scene is set to the graphicsview then simply below one line will show the grid.
ui->graphicsView->scene()->setBackgroundBrush(Qt::CrossPattern);
There several other values can be passed for ex: Qt::Dense7Pattern
These are members of enum BrushStyle, just click on any used value in Qt creator and it will take you to the enum declaration where you can see all other possible values.
PS:
A scene can be set like this:
ui->graphicsView->setScene(new QGraphicsScene());