How to draw a rectangle with edge roughness - python-3.x

I use Imagedraw module to draw rectangle, which is very simple:
blank=Image.new("RGB",[pixelx,pixely],"black:")
draw=ImageDraw.Draw(blank)
draw.rectangle(x1,y1,x2,y2,fill='white')
This gives me a straight line rectangle in white.
But can I change the roughness of edge of this rectangle?
I am trying to make the rectangle look more similar to practical image.
If I cannot achieve this by Imagedraw, what module can help me do that.
Thanks a lot!

It's difficult to know precisely what effect you are after.
I can tell you that Pillow has filters - https://pillow.readthedocs.io/en/5.2.x/reference/ImageFilter.html
from PIL import ImageFilter
im = im.filter(ImageFilter.BLUR)
Changing the angle of your rectangle - by selecting co-ordinates that are not a flat rectangle - would create pixelated edges.
Otherwise, I might suggest randomly changing individual pixels along the edges using https://pillow.readthedocs.io/en/5.2.x/reference/PixelAccess.html
from PIL import Image
px = im.load()
px[0, 0] = (0, 0, 0)
Although that could be slow. It depends on the size of your image and the need for speed.

Related

read png file names from txt files in pygame [duplicate]

I would like to know how to draw images using pygame. I know how to load them.
I have made a blank window.
When I use screen.blit(blank, (10,10)), it does not draw the image and instead leaves the screen blank.
This is a typical layout:
myimage = pygame.image.load("myimage.bmp")
imagerect = myimage.get_rect()
while 1:
your_code_here
screen.fill(black)
screen.blit(myimage, imagerect)
pygame.display.flip()
import pygame, sys, os
from pygame.locals import *
pygame.init()
screen = pygame.display.set_mode((100, 100))
player = pygame.image.load(os.path.join("player.png"))
player.convert()
while True:
screen.blit(player, (10, 10))
pygame.display.flip()
pygame.quit()
Loads the file player.png.
Run this and it works perfectly. So hopefully you learn something.
Images are represented by "pygame.Surface" objects. A Surface can be created from an image with pygame.image.load:
my_image_surface = pygame.load.image('my_image.jpg')
However, the pygame documentation notes that:
The returned Surface will contain the same color format, colorkey and alpha transparency as the file it came from. You will often want to call convert() with no arguments, to create a copy that will draw more quickly on the screen.
For alpha transparency, like in .png images, use the convert_alpha() method after loading so that the image has per pixel transparency.
Use the appropriate conversion method for best performance:
image_surface = pygame.load.image('my_image.jpg').convert()
alpha_image_surface = pygame.load.image('my_icon.png').convert_alpha()
A Surface can be drawn on or blended with another Surface using the blit method. The first argument to blit is the Surface that should be drawn. The second argument is either a tuple (x, y) representing the upper left corner or a rectangle. With a rectangle, only the upper left corner of the rectangle is taken into account. It should be mentioned that the window respectively display is also represented by a Surface. Therefore, drawing a Surface in the window is the same as drawing a Surface on a Surface:
window_surface.blit(image_surface, (x, y))
window_surface.blit(image_surface,
image_surface.get_rect(center = window_surface.get_rect().center))
Minimal example:
import pygame
pygame.init()
window = pygame.display.set_mode((300, 300))
clock = pygame.time.Clock()
pygameSurface = pygame.image.load('apple.png').convert_alpha()
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
window.fill((127, 127, 127))
window.blit(pygameSurface, pygameSurface.get_rect(center = window.get_rect().center))
pygame.display.flip()
pygame.quit()
exit()
pygame.image.load is bale to load most images. According to the documentation the following formats are supported: JPG, PNG, GIF (non-animated), BMP, PCX, TGA (uncompressed), TIF, LBM (and PBM), PBM (and PGM, PPM), XPM.
If you want to use images in PyGame that are loaded with other libraries, see:
PIL and pygame.image
How do I convert an OpenCV (cv2) image (BGR and BGRA) to a pygame.Surface object
For information on loading Scalable Vector Graphics (SVG) files, see:
SVG rendering in a PyGame application
Loading animated GIF files is presented at:
How can I load an animated GIF and get all of the individual frames in PyGame?
How do I make a sprite as a gif in pygame?
Or see how to load NumPy frames:
Pygame and Numpy Animations
After using blit or any other update on your drawing surface, you have to call pygame.display.flip() to actually update what is displayed.

Extract the 3×3image segment from the input image centred around the position (x,y)

I want to ask how to Extract the a n×n image segment from an input image centered around the position (x,y), the image has format like this [[num,num,num],[num,numm,num],[num,num,num]........], size of image is about 10 * 10. Thank you !
I do really recommend using numpy, when working with multidimensional arrays/when you want to manipulate these arrays, but here you go, a numpy solution and a solution without numpy.
import numpy as np
img = np.array([[1,2,3,4,5],[2,3,4,5,6],[3,4,5,6,7],[4,5,6,7,8],[5,6,7,8,9]])
print('img:\n',img,'\n')
partOfImage = img[0:3,0:3]
print('partOfImage:\n',partOfImage)
img = [[1,2,3,4,5],[2,3,4,5,6],[3,4,5,6,7],[4,5,6,7,8],[5,6,7,8,9]]
noNumpy =[[img[i][j] for j in range(0,3)] for i in range(0,3)]
print(noNumpy)
Question. So you wish to find the center of an image, expand 1 pixel left, left down, down, right down, right, right up, up, and left up to get an image from the middle of your sample. Correct? I do not have a code example, but a conceptual comment.
Fixed spatial images normally start their addressing at upper left for 0,0. Because of their even numbers of pixels approach, it's near-impossible to find a "middle". So finding a "middle pixel" means you need to apply a percentage and choose the nearest "whole pixel" to the choice. Then expand to your 3x3 dimensions.

Why is a generated SVG image less rich than the corresponding PNG image

To set this up, I used svgwrite library to create a sample SVG image (20 squares of length 100 at random locations on a display size of length 400)
import svgwrite
import random
random.seed(42)
dwg = svgwrite.Drawing('x.svg', size=(400,400))
dwg.add(dwg.rect(insert=(0,0), size=('100%', '100%'), fill='white')) # White background
for i in range(20):
coordinates = (random.randint(0,399), random.randint(0,399))
color = (random.randint(0,255), random.randint(0,255), random.randint(0,255))
dwg.add(dwg.rect(coordinates, (100, 100),
stroke='black',
fill=svgwrite.rgb(*color),
stroke_width=1)
)
dwg.save()
I then wrote a sample pygame program to generate a PNG image of the same sample. (A seed has been used to generate the same sequence of squares.)
import pygame
import random
random.seed(42)
display = pygame.display.set_mode((400,400))
display.fill((255,255,255)) # White background
for i in range(20):
coordinates = (random.randint(0,399), random.randint(0,399))
color = (random.randint(0,255), random.randint(0,255), random.randint(0,255))
pygame.draw.rect(display, color, coordinates+(100,100), 0)
pygame.draw.rect(display, (0,0,0), coordinates+(100,100), 1) #For black border
pygame.image.save(display, "x.png")
These are the images that I got (SVG's can't be uploaded to SO, so I have provided a screenshot. Nevertheless, the programs above can be run to output the same).
My question is, why is the PNG (on the left) richer and sharper than the corresponding SVG image? The SVG looks blurred and bland, comparatively.
EDIT: One can notice the fine white line between the first two squares at the top-left corner. It's not very clear in the SVG.
Two things I think may impact:
You are using an image viewer, which could distort the vectorial SVG image. I think all of the vector images viewers get the actual screen size, then export the vectorial image into a matrix image sized in function of the size of the screen you have. Then they display the matrix image. If they render the image with softened sharpness, or if they have a problem by getting the size of your screen, the image may be blurred.
To make the PNG image, you use pygame. But you are using another module to make the SVG image. This module may function differently, and also exports the image with another quality than if you were exporting it with pygame.
For me personally the SVG image appears blurred with Gimp, for example, but not with another SVG viewer.
So I think the problem comes from your image viewer.

Pygame - Changing shape/moving Collision Rect. for the sprite

I have a pygame sprite animation where the position and shape of the sprite changes throughout a certain animation sequence (eg. - attack). How do I adjust the sprite's rect for collisions?
My Image: in one part of the animation, my sprite is at the center of a png image file (96x64 pixels). In another part of the animation, my sprite is near the right side of the png image file (96x64 pixels). In another part of the animation, the sprite changes shape (caused by sword movement). Etc.
Do I have to do some math and calculation to adjust the collision rect. of the sprite each frame of the animation or is there an easier method?
I am new to pygame so I'm not sure of all the different features and am not sure where to begin with creating the different rects. for each frame.
PS. I am using a ready-made sprite I found online - each frame is 96x64 pixels in dimension
Frame 1, 11, 22:
It's been a while since I've worked with Pygame but I believe you can use a pygame.mask object. A mask is basically an object with the precise outline of the foreground of an image. It takes considerably more computation power but if you only create a mask for the one main character then it should be okay.
You can create a mask from the image:
myMask = pygame.mask(myImage)
Then you can either use its rect or create a new surface to use:
myRect = myMask.get_rect() # Returns the pygame.Rect object that conatains mask, or:
mySurface - myMask.to_surface() # Returns a pygame.Surface object of the mask
Hope this helps, my info is from:
https://www.pygame.org/docs/ref/mask.html

convert basic RGB to alpha in pygame

light_green = (0,200,0,100)
pygame.draw.rect(game_display,light_green,(50,200,60,110))
I know that this has the alpha property in the 4th section(100). But it is not transparent when applied on top of a background. It is simply just a solid square block. I want to be able to see the background through the square. Any help always appreciated. Thanks :)
The draw module's functions do not draw transparent. See the documentation for draw
Most of the arguments accept a color argument that is an RGB triplet.
These can also accept an RGBA quadruplet. The alpha value will be
written directly into the Surface if it contains pixel alphas, but the
draw function will not draw transparently.
A workaround is to use the respective functions from the pygame.gfxdraw module instead, they add transparency, for your case the box function.
import pygame.gfxdraw
light_green = (0,200,0,100)
pygame.gfxdraw.box(game_display, pygame.Rect(50,200,60,110), light_green)
If you only want to draw rectangles you can as an alternate way directly fill a Surface and blit it to the screen.
light_green = (0,200,0,100)
s = pygame.Surface((60, 110), pygame.SRCALPHA)
s.fill(light_green)
game_display.blit(s, (50, 200))

Resources