8 Queens (pyglet-python) - python

I'm trying to make 8 queens game on pyglet. I have succesfully generated board.png on window. Now when I paste queen.png image on it, I want it to show only queen on it not the white part. I removed white part using photoshop, but as I call it on board.png in pyglet it again shows that white part please help.
import pyglet
from pyglet.window import Window, mouse, gl
# Display an image in the application window
image = pyglet.image.Texture.create(800,800)
board = pyglet.image.load('resources/Board.png')
queen = pyglet.image.load('resources/QUEEN.png')
image.blit_into(board,0,0,0)
image.blit_into(queen,128,0,0)
# creating a window
width = board.width
height = board.height
mygame = Window(width, height,
resizable=False,
caption="8 Queens",
config=pyglet.gl.Config(double_buffer=True),
vsync=False)
# Making list of tiles
print("Height: ", board.height, "\nWidth: ", board.width)
#mygame.event
def on_draw():
mygame.clear()
image.blit(0, 0)
def updated(dt):
on_draw()
pyglet.clock.schedule_interval(updated, 1 / 60)
# Launch the application
pyglet.app.run()
These are the images:
queen.png
board.png

Your image is a rectangle. So necessarily, you will have a white space around your queen whatever you do.
I would recommend a bit of hacking (it's not very beautiful) and create two queen versions: queen_yellow and queen_black. Whenever the queen is standing on a yellow tile, display queen_yellow, and otherwise display queen_black.
To find out whether a tile is a yellow tile (using a matrix with x and y coordinates, where the top value for y is 0 and the very left value for x is 0):
if tile_y%2=0: #is it an even row?
if tile_x%2=0: #is it an even column?
queentype = queen_yellow
else:
queentype = queen_black
else: #is it an uneven row?
if tile_x%2!=0: #is it an uneven column?
queentype = queen_yellow
else: queentype = queen_black
Hope that helped,
Narusan

First of all, please verify that there is no background (you can use GIMP for that). Once that is done go ahead with this:
Since it is a PNG image, you can't just put it there on the window as it will lose its transparency. You need to import the PNGImageDecoder from pyglet like
from pyglet.image.codecs.png import PNGImageDecoder
then use it for loading the PNG image like
kitten = pyglet.image.load('kitten.png', decoder=PNGImageDecoder())
and finally draw it on the window by using
kitten.draw(), after specifying the x and y coordinates where you would like to have them.
The document for the above can be found here.
Hope this helps!

Related

Windows: Draw rectangle on camera preview

Similar questions have been asked a lot for Android, but so far I haven´t been able to find resources related to Windows OS. So basically, as the topic suggests, I would like to draw a rectangle on my camera preview. Some work has been done, but there´s still some problem in my program. Due to some limits, I would like to avoid using opencv as much as possible. Following is my approach:
Open Window´s built-in camera app
Run Python code that draws rectangle on screen, pixel by pixel (see below)
Click on screen with mouse to move rectangle with its upper-left corner
As you can see in the code, I´m not actually drawing on the camera preview but rather drawing on my screen, where the camer preview runs on one layer lower.
Here´s the python code:
import win32gui, win32ui, win32api, win32con
from win32api import GetSystemMetrics
dc = win32gui.GetDC(0)
dcObj = win32ui.CreateDCFromHandle(dc)
hwnd = win32gui.WindowFromPoint((0,0))
monitor = (0, 0, GetSystemMetrics(0), GetSystemMetrics(1))
red = win32api.RGB(255, 0, 0) # Red
past_coordinates = monitor
rec_x = 200 # width of rectangle
rec_y = 100 # height of rectangle
m = (100, 100) # initialize start coordinate
def is_mouse_down():
key_code = win32con.VK_LBUTTON
state = win32api.GetAsyncKeyState(key_code)
return state != 0
while True:
if(is_mouse_down() == True):
m = win32gui.GetCursorPos()
for x in range(rec_x):
win32gui.SetPixel(dc, m[0]+x, m[1], red)
win32gui.SetPixel(dc, m[0]+x, m[1]+rec_y, red)
for y in range(rec_y):
win32gui.SetPixel(dc, m[0], m[1]+y, red)
win32gui.SetPixel(dc, m[0]+rec_x, m[1]+y, red)
As a result, I´m able to draw a red rectangle. However, because the screen is constantly being refreshed, the two horizontal lines of my rectangle (see gif below) are shown as running dots that go from left to right. I can´t find or think of a way to improve this, whilst keeping the possibility to move the rectangle around per ckick.
PS. Ignore white rectangle. It´s a built-in thing of the camera app when you click anywhere on the preview.
Here are the references I used to get to this step:
How to draw an empty rectangle on screen with Python
https://python-forum.io/Thread-How-to-trigger-a-function-by-clicking-the-left-mouse-click

How to remove an image in pygame?

I'm working on a game and I have some problems working with images.
I have loaded a few images . loading them and using screen.blit() was okay like below:
img1 = pygame.image.load("leaf.png")
img1 = pygame.transform.scale(img1, (25,25))
leaf = img1.get_rect()
leaf.x = random.randint(0, 570)
leaf.y = random.randint(0, 570)
but I don't know how to remove them in an if statement like this for example:
if count == 1:
...
and I though maybe there is no way and I should draw a rectangle on the image to disappear it. Also I don't know how to use screen.fill() while I don't want the other images to get disappeared. Is there any other way?
You can fill individual images, since they are pygame Surfaces.
First, what I would do is I would put something like this after defining the leaf's x/y:
leaf.image = img1
Then, I would create a color variable called transparent:
transparent = (0, 0, 0, 0)
The first 3 numbers, as you might know, represent RGB color values. The last number is the alpha (transparency) value of a color. 0 is completely invisible.
Finally, I would add this code to make the leaf completely transparent:
leaf.image.fill(transparent)
This makes the leaf transparent without making every other image in your window disappear. Hope this helped!

Programmatically remove Apple Screen Capture Shadow borders

The built-in MacOS screen capture program (command-shift-4) has a nice feature where you can hit the spacebar and capture just a window, like this:
I would like to programmatically look at a directory of images (they are PNGs), determinate if they have the shadow, and automatically crop it. I need this to run on a Mac. I'd like to write this in Python. I am told that Pillow is the correct way to manage images in Python now, but I'm not sure how to read individual pixel and to crop images.
Here are some recommendations regardless of the library you will be using.
There are invariants on the window: 4 corners, title bar with mostly uniform color and 3 disk-shaped buttons.
If you can detect the buttons and the title bar, you can easily find the top corners. The bottom corners are symmetrical to the top corners.
A possible solution
Apply Hough transform to find circles
Find 3 consecutive circles along the horizontal axis (the buttons)
Apply Hough transform to find vertical and horizontal lines
Find a quad containing the 3 circles (title bar)
The 2 top corners of the window are located around the top corners of the title bar.
Form a patch by taking a neighborhood around a corner
Apply an edge detection algorithm in the patch
Reflect the pixels of the patch vertically
Apply patch matching vertically. For example with DP
Repeat the matching for the 2 top corners to find the bottom ones
With the 4 corner you know the bounding box of the window and you can solve the cropping problem
Here is code that uses Python Image Library and Python 2.7 to do the trick:
#!/usr/bin/env
# Removes the shadow from MacOS-Generated screen shots.
import Image,os
if __name__=="__main__":
image = Image.open(os.sys.argv[1])
image = image.convert('RGBA')
(width,height) = image.size
def find_first_non_alpha_x():
for i in range(width):
if image.getpixel((i,height/2))[3]==255:
return i
raise RuntimeError("No non-alpha pixels on midline")
def find_last_non_alpha_x():
for i in range(width-1,0,-1):
if image.getpixel((i,height/2))[3]==255:
return i
raise RuntimeError("No non-alpha pixels on midline")
def find_first_non_alpha_y():
for i in range(height):
if image.getpixel((width/2,i))[3]==255:
return i
raise RuntimeError("No non-alpha pixels on midline")
def find_last_non_alpha_y():
for i in range(height-1,0,-1):
if image.getpixel((width/2,i))[3]==255:
return i
raise RuntimeError("No non-alpha pixels on midline")
x1 = find_first_non_alpha_x()
y1 = find_first_non_alpha_y()
x2 = find_last_non_alpha_x()
y2 = find_last_non_alpha_y()
y = image.crop((x1-1,y1-1,x2+1,y2+1))
y.save(os.sys.argv[1]+"-cropped.png")

Mirror Image but wrong size

I am trying to input an image (image1) and flip it horizontally and then save to a file (image2). This works but not the way I want it to
currently this code gives me a flipped image but it just shows the bottom right quarter of the image, so it is the wrong size. Am I overwriting something somewhere? I just want the code to flip the image horizontally and show the whole picture flipped. Where did I go wrong?
and I cannot just use a mirror function or reverse function, I need to write an algorithm
I get the correct window size but the incorrect image size
def Flip(image1, image2):
img = graphics.Image(graphics.Point(0, 0), image1)
X, Y = img.getWidth(), img.getHeight()
for y in range(Y):
for x in range(X):
r, g, b = img.getPixel(x,y)
color = graphics.color_rgb(r, g, b)
img.setPixel(X-x, y, color)
win = graphics.GraphWin(img, img.getWidth(), img.getHeight())
img.draw(win)
img.save(image2)
I think your problem is in this line:
win = graphics.GraphWin(img, img.getWidth(), img.getHeight())
The first argument to the GraphWin constructor is supposed to be the title, but you are instead giving it an Image object. It makes me believe that maybe the width and height you are supplying are then being ignored. The default width and height for GraphWin is 200 x 200, so depending on the size of your image, that may be why only part of it is being drawn.
Try something like this:
win = graphics.GraphWin("Flipping an Image", img.getWidth(), img.getHeight())
Another problem is that your anchor point for the image is wrong. According to the docs, the anchor point is where the center of the image will be rendered (thus at 0,0 you are only seeing the bottom right quadrant of the picture). Here is a possible solution if you don't know what the size of the image is at the time of creation:
img = graphics.Image(graphics.Point(0, 0), image1)
img.move(img.getWidth() / 2, img.getHeight() / 2)
You are editing your source image. It would be
better to create an image copy and set those pixels instead:
create a new image for editing:
img_new = img
Assign the pixel values to that:
img_new.setPixel(X-x, y, color)
And draw that instead:
win = graphics.GraphWin(img_new, img_new.getWidth(), img_new.getHeight())
img_new.draw(win)
img_new.save(image2)
This will also check that your ranges are correct. if they are not, you will see both flipped and unflipped portions in the final image, showing which portions are outside of your ranges.
If you're not opposed to using an external library, I'd recommend the Python Imaging Library. In particular, the ImageOps module has a mirror function that should do exactly what you want.

Process image from screenshot - Python

I'm trying to take a screenshot of a game, bejeweled (an 8x8 board), and extract the board position from the screenshot. I've tried Image/Imagestat, autopy, and grabbing individual pixels from the middle of the slots but these haven't worked. So I'm thinking taking the average value for each square of the 8x8 grid would identify each piece - but I've been unable to do so with Image/Imagestat and autopy.
Anyone know a way to get the pixel or color values for a region of an image? Or a better way to identify segments of an image with a dominant color?
I've found a way to do this with PIL using Imagegrab and ImageStat. Here's to grab the screen and crop to the game window:
def getScreen():
# Grab image and crop it to the desired window. Find pixel borders manually.
box = (left, top, right, bottom)
im = ImageGrab.grab().crop(box)
#im.save('testcrop.jpg') # optionally save your crop
for y in reversed(range(8)):
for x in reversed(range(8)):
#sqh,sqw are the height and width of each piece.
#each pieceim is one of the game piece squares
piecebox = ( sqw*(x), sqh*(y), sqw*(x+1), sqh*(y+1))
pieceim = im.crop(piecebox)
#pieceim.save('piececrop_xy_'+ str(x) + str(y) + '.jpg')
stats = ImageStat.Stat(pieceim)
statsmean = stats.mean
Rows[x][y] = whichpiece(statsmean)
The above creates an image for all 64 pieces, identifies piecetype, and stores that in the array of arrays 'Rows'. I then grabbed the average RGB values with stats.mean for each piecetype and stored them in a dictionary (rgbdict). Copy all the outputs into Excel and filter by color type to get those averages. Then I used an RSS method and that dictionary to statistically match the images to the known piecetypes. (RSS ref: http://www.charlesrcook.com/archive/2010/09/05/creating-a-bejeweled-blitz-bot-in-c.aspx)
rgbdict = {
'blue':[65.48478993, 149.0030965, 179.4636593], #1
'red':[105.3613444,55.95710092, 36.07481793], #2
......
}
def whichpiece(statsmean):
bestScore = 100
curScore= 0
pieceColor = 'empty'
for key in rgbdict.keys():
curScore = (math.pow( (statsmean[0]/255) - (rgbdict[key][0]/255), 2)
+ math.pow( (statsmean[1]/255) - (rgbdict[key][1]/255), 2)
+ math.pow( (statsmean[2]/255) - (rgbdict[key][2]/255), 2) )
if curScore < bestScore:
pieceColor = key
bestScore = curScore
return piececolor
With these two functions the screen can be scraped, and the board state transferred into an array upon which moves can be decided. Best of luck if this helps anyone, and let me know if you fine tune a move picker.

Categories

Resources