I want to make grid of dots, but I'm not sure this is the right way to do it.
from PIL import Image, ImageDraw
img = Image.new("RGB", (1000,1000), (0, 0, 0))
draw = ImageDraw.Draw(i)
w, h = img.size
step = 100
for n in range(step,w,step):
for x in range(step,h-step,step):
draw.point((n,x), fill="yellow")
img
Thanks in advance!
You can't pass a size parameter to point, so try ellipse:
from PIL import Image, ImageDraw
img = Image.new("RGB", (1000,1000), (0, 0, 0))
draw = ImageDraw.Draw(img)
w, h = img.size
step = 100
size = 10
for size in [1,25]:
for n in range(step,w,step):
for x in range(step,h-step,step):
draw.ellipse([n-size/2,x-size/2,n+size//2,x+size//2], fill="yellow")
img.save('size_{:d}.png'.format(size))
Which gives the following outputs:
Related
I am studying on hologram vision. I want to placed 4 images onto black screen.
I wrote this code:
import numpy as np
import cv2
from screeninfo import get_monitors
if __name__ == '__main__':
screen = get_monitors()[0]
print(screen)
width, height = screen.width, screen.height
image = np.zeros((height, width, 3), dtype=np.float64)
image[:, :] = 0 # black screen
img = cv2.imread("newBen.png")
p = 0.25
w = int(img.shape[1])
h = int(img.shape[0])
new_img = cv2.resize(img, (w, h))
image[:h, :w] = new_img
window_name = 'projector'
cv2.namedWindow(window_name, cv2.WND_PROP_FULLSCREEN)
cv2.moveWindow(window_name, screen.x - 1, screen.y - 1)
cv2.setWindowProperty(window_name, cv2.WND_PROP_FULLSCREEN,
cv2.WINDOW_FULLSCREEN)
cv2.imshow(window_name, image)
cv2.waitKey()
cv2.destroyAllWindows()
But my image looking like this.
How can ı fix it?
The dtype of a normal RGB image is uint8, not float64.
image = np.zeros((height, width, 3), dtype=np.uint8)
Btw: You don't have to set image[:, :] = 0 # black screen. This is already been done by np.zeros.
I am drawing a blue rectangle in framebuffer, and I want to erase it again. Before I draw the rectangle I copy the background where the rectangle will be pasted, and paste it over the rectangle after 2 seconds. The rectangle is not erased.
#!/usr/bin/env python
import numpy as np
import time
from PIL import Image
from io import BytesIO
h, w, c = 1024, 1280, 4
fb = np.memmap('/dev/fb0', dtype='uint8',mode='w+', shape=(h,w,c))
x0, y0 = 50, 200
w, h = 300, 400
# Copy backbround: Does not work?
n0 = fb.read[y0:y0+h, x0:x0+w]
# Paste blue rectangle to framebuffer: This works.
img = Image.new('RGBA', size=(w, h), color=(255,0,0,255))
n = np.array(img)
fb[y0:y0+h, x0:x0+w] = n
# Erase image: Does not work?
time.sleep(2)
fb[y0:y0+h, x0:x0+w] = n0
What am I doing wrong?
If I paste n0 to another place in framebuffer, I get a blue rectangle, not a black one.
I solved it myself by using np.copy:
import numpy as np
import time
from PIL import Image
h, w, c = 1024, 1280, 4
fb = np.memmap('/dev/fb0', dtype='uint8',mode='w+', shape=(h,w,c))
x0, y0 = 50, 200
w, h = 300, 400
# Copy background:
### n0 = fb.read[y0:y0+h, x0:x0+w]
n0 = np.copy(fb[y0:y0+h, x0:x0+w])
# Paste blue rectangle to framebuffer: This works.
img = Image.new('RGBA', size=(w, h), color=(255,0,0,255))
n = np.array(img)
fb[y0:y0+h, x0:x0+w] = n
# Erase image:
time.sleep(2)
### fb[y0:y0+h, x0:x0+w] = n0
fb[y0:y0+h, x0:x0+w] = np.copy(n0)
Ok, so I tried to edit an image and turn the edited result into a pixel map.
That worked well, but I just don't know how to turn that pixel map into an actual image and show it.
This is my code:
from PIL import Image
import numpy as np
img = Image.open('sample.jpg')
pixels = img.load()
for i in range(img.size[0]): # for every pixel:
for j in range(img.size[1]):
if pixels[i,j] == (255, 0, 0):
pixels[i,j] = (0, 0 ,0)
im2 = Image.fromarray(pixels)
im2.show()
Also, I'm getting this error message:
Traceback (most recent call last):
File "C:\Users\Haris.Sabotic\Desktop\Image Color Inverter\code.py", line 15, in <module>
im2 = Image.fromarray(pixels)
File "C:\Users\Haris.Sabotic\AppData\Local\Programs\Python\Python37-32\lib\site-packages\PIL\Image.py", line 2508, in fromarray
arr = obj.__array_interface__
AttributeError: 'PixelAccess' object has no attribute '__array_interface__'
You don't have to convert pixels back to image because pixels changes values in original img - so you have to display img.show()
from PIL import Image
img = Image.open('sample.jpg')
pixels = img.load()
width, height = img.size
for col in range(width):
for row in range(height):
if pixels[col,row] == (255, 0, 0):
pixels[col,row] = (0, 0 ,0)
img.show()
EDIT: You need fromarray() when you convert to numpy array
from PIL import Image
import numpy as np
img1 = Image.open('sample.jpg')
pixels = np.array(img1)
pixels[np.all(pixels == (255, 0, 0), axis=-1)] = (0,0,0)
img2 = Image.fromarray(pixels)
img2.show()
BTW: if you have to get pixel in array then remeber that array uses [row,col] instead of [col,row]
How can I make watermark image transparent? For example, 60% transparent. I have tried with putalpha but seems that it's doesn't work as expected
from PIL import Image
temp_image = Image.open('test1.jpg')
watermark = Image.open('watermark.png')
x, y = temp_image.size
image_with_watermark = Image.new('RGBA', (x, y), (0, 0, 0, 0))
image_with_watermark.paste(temp_image, (0, 0))
image_with_watermark.paste(watermark, (0, 0), mask=watermark)
image_with_watermark.show()
EDIT:
ok, this works, need to figure out how to set it up using %
from PIL import Image
temp_image = Image.open('test1.jpg')
watermark = Image.open('watermark.png')
x, y = temp_image.size
watermask = watermark.convert("L").point(lambda x: min(x, 50))
watermark.putalpha(watermask)
image_with_watermark = Image.new('RGBA', (x, y), (0, 0, 0, 0))
image_with_watermark.paste(temp_image, (0, 0))
image_with_watermark.paste(watermark, (0, 0), mask=watermark)
image_with_watermark.show()
meh, quality of the watermark is very low after:
watermask = watermark.convert("L").point(lambda x: min(x, 50))
watermark.putalpha(watermask)
What is the best way to achieve what I need?
Here's a solution that will work for both RGB and RGBA watermark images:
from PIL import Image
TRANSPARENCY = 65 # percentage
temp_image = Image.open('test1.jpg')
watermark = Image.open('watermark.png')
if watermark.mode!='RGBA':
alpha = Image.new('L', watermark.size, 255)
watermark.putalpha(alpha)
paste_mask = watermark.split()[3].point(lambda i: i * TRANSPARENCY / 100.)
temp_image.paste(watermark, (0,0), mask=paste_mask)
temp_image.save('res.png')
Sample image (author - Neil Howard):
Sample watermark (the background is transparent):
Sample result:
How do I generate circular image thumbnails using PIL?
The space outside the circle should be transparent.
Snippets would be highly appreciated, thank you in advance.
The easiest way to do it is by using masks. Create a black and white mask with any shape you want. And use putalpha to put that shape as an alpha layer:
from PIL import Image, ImageOps
mask = Image.open('mask.png').convert('L')
im = Image.open('image.png')
output = ImageOps.fit(im, mask.size, centering=(0.5, 0.5))
output.putalpha(mask)
output.save('output.png')
Here is the mask I used:
If you want the thumbnail size to be variable you can use ImageDraw and draw the mask:
from PIL import Image, ImageOps, ImageDraw
size = (128, 128)
mask = Image.new('L', size, 0)
draw = ImageDraw.Draw(mask)
draw.ellipse((0, 0) + size, fill=255)
im = Image.open('image.jpg')
output = ImageOps.fit(im, mask.size, centering=(0.5, 0.5))
output.putalpha(mask)
output.save('output.png')
If you want the output in GIF then you need to use the paste function instead of putalpha:
from PIL import Image, ImageOps, ImageDraw
size = (128, 128)
mask = Image.new('L', size, 255)
draw = ImageDraw.Draw(mask)
draw.ellipse((0, 0) + size, fill=0)
im = Image.open('image.jpg')
output = ImageOps.fit(im, mask.size, centering=(0.5, 0.5))
output.paste(0, mask=mask)
output.convert('P', palette=Image.ADAPTIVE)
output.save('output.gif', transparency=0)
Note that I did the following changes:
The mask is now inverted. The white
was replaced with black and vice versa.
I'm converting into 'P' with an 'adaptive' palette. Otherwise, PIL will only use web-safe colors and the result will look bad.
I'm adding transparency info to the image.
Please note: There is a big issue with this approach. If the GIF image contained black parts, all of them will become transparent as well. You can work around this by choosing another color for the transparency.
I would strongly advise you to use PNG format for this. But if you can't then that is the best you could do.
I would like to add to the already accepted answer a solution to antialias the resulting circle, the trick is to produce a bigger mask and then scale it down using an ANTIALIAS filter:
here is the code
from PIL import Image, ImageOps, ImageDraw
im = Image.open('image.jpg')
bigsize = (im.size[0] * 3, im.size[1] * 3)
mask = Image.new('L', bigsize, 0)
draw = ImageDraw.Draw(mask)
draw.ellipse((0, 0) + bigsize, fill=255)
mask = mask.resize(im.size, Image.ANTIALIAS)
im.putalpha(mask)
this produces a far better result in my opinion.
Slight modification on #DRC's solution to also support images which already have transparency. He sets the alpha channel to 0 (invisible) outside the circle and to 255 inside (opaque), so I use darker which takes the min of the mask and the original alpha channel (which can be anywhere betwen 0-255) :-)
from PIL import Image, ImageChops, ImageDraw
def crop_to_circle(im):
bigsize = (im.size[0] * 3, im.size[1] * 3)
mask = Image.new('L', bigsize, 0)
ImageDraw.Draw(mask).ellipse((0, 0) + bigsize, fill=255)
mask = mask.resize(im.size, Image.ANTIALIAS)
mask = ImageChops.darker(mask, im.split()[-1])
im.putalpha(mask)
im = Image.open('0.png').convert('RGBA')
crop_to_circle(im)
im.save('cropped.png')
Thank you very much. I was looking for hours and your idea does the trick.
Together with this other script from there.
PIL round edges and add border
it works perfectly for me.
from PIL import Image
from PIL import ImageDraw, ImageChops
def add_corners( im, rad=100):
circle = Image.new('L', (rad * 2, rad * 2), 0)
draw = ImageDraw.Draw(circle)
draw.ellipse((0, 0, rad * 2, rad * 2), fill=255)
alpha = Image.new('L', im.size, "white")
w, h = im.size
alpha.paste(circle.crop((0, 0, rad, rad)), (0, 0))
alpha.paste(circle.crop((0, rad, rad, rad * 2)), (0, h - rad))
alpha.paste(circle.crop((rad, 0, rad * 2, rad)), (w - rad, 0))
alpha.paste(circle.crop((rad, rad, rad * 2, rad * 2)), (w - rad, h - rad))
alpha = ImageChops.darker(alpha, im.split()[-1])
im.putalpha(alpha)
return im
im = Image.open ('AceOfSpades.png').convert('RGBA')
im = add_corners (im, 24)
im.show()
im.save("perfect.png")
Name this image AceOfSpades.png for testing