├── Halogen.ttf ├── mask.png ├── owl.jpg ├── picture.jpg ├── pillow1_basics.py ├── pillow2_manipulation.py ├── pillow3_enhance.py ├── pillow4_filters.py ├── pillow5_colors.py ├── pillow6_ImageOps.py ├── pillow7_deformer.py ├── pillow8_shapes.py ├── pillow9_merging.py └── python.png /Halogen.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clear-code-projects/Pillow/ef5f631dd9329d3c4421454cfa3b9ad57ba40fc0/Halogen.ttf -------------------------------------------------------------------------------- /mask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clear-code-projects/Pillow/ef5f631dd9329d3c4421454cfa3b9ad57ba40fc0/mask.png -------------------------------------------------------------------------------- /owl.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clear-code-projects/Pillow/ef5f631dd9329d3c4421454cfa3b9ad57ba40fc0/owl.jpg -------------------------------------------------------------------------------- /picture.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clear-code-projects/Pillow/ef5f631dd9329d3c4421454cfa3b9ad57ba40fc0/picture.jpg -------------------------------------------------------------------------------- /pillow1_basics.py: -------------------------------------------------------------------------------- 1 | from PIL import Image 2 | 3 | # create new image by import 4 | image = Image.open('picture.jpg') 5 | 6 | # alternative way to import an image 7 | # with Image.open('picture.jpg') as image: 8 | # image.show() 9 | 10 | # create a new image from scratch 11 | image_blank = Image.new('RGBA',(1000,600)) 12 | 13 | # show the picture 14 | # image_blank.show() 15 | 16 | # saving the picture 17 | #image.save('test_save.png') 18 | 19 | # image information 20 | print(image.size) 21 | print(image.filename) 22 | print(image.format) 23 | print(image.format_description) -------------------------------------------------------------------------------- /pillow2_manipulation.py: -------------------------------------------------------------------------------- 1 | from PIL import Image, ImageColor 2 | 3 | # image import 4 | image = Image.open('picture.jpg') 5 | 6 | # documentation 7 | # https://pillow.readthedocs.io/en/stable/reference/Image.html? 8 | print(ImageColor.colormap) 9 | # rotate 10 | # image_rotate = image.rotate(60,expand = True, fillcolor = ImageColor.getcolor('red','RGB')) 11 | 12 | # # crop 13 | # image_crop = image.crop((550,400,1500,1150)) 14 | 15 | # # flipping the image / transpose the image 16 | # image_flip_horizontal = image.transpose(Image.Transpose.FLIP_LEFT_RIGHT) 17 | # image_flip_vertical = image.transpose(Image.Transpose.FLIP_TOP_BOTTOM) 18 | # image_transpose = image.transpose(Image.Transpose.TRANSPOSE) 19 | # # options: FLIP_LEFT_RIGHT, FLIP_TOP_BOTTOM, ROTATE_90, ROTATE_180, ROTATE_270, TRANSPOSE, TRANSVERSE. 20 | 21 | # # resize 22 | # image_resize = image.resize((600,1000)) # bad example 23 | 24 | # # better example 25 | # scale_factor = 2 26 | # new_image_size = (image.size[0] * scale_factor,image.size[1] * scale_factor) 27 | # image_resize_better = image.resize(new_image_size) 28 | 29 | # display 30 | #image_resize_better.show() -------------------------------------------------------------------------------- /pillow3_enhance.py: -------------------------------------------------------------------------------- 1 | from PIL import Image, ImageEnhance 2 | # https://pillow.readthedocs.io/en/stable/reference/ImageEnhance.html 3 | 4 | # image import 5 | image = Image.open('picture.jpg') 6 | 7 | # create an enhancer 8 | color_enhancer = ImageEnhance.Color(image) # vibrance 9 | contrast_enhancer = ImageEnhance.Contrast(image) # contrast 10 | brightness_enhancer = ImageEnhance.Brightness(image) # contrast 11 | sharpness_enhancer = ImageEnhance.Sharpness(image) # contrast 12 | 13 | # applying the enhancer 14 | enhanced_image = brightness_enhancer.enhance(5) 15 | enhanced_image.show() -------------------------------------------------------------------------------- /pillow4_filters.py: -------------------------------------------------------------------------------- 1 | from PIL import Image, ImageFilter 2 | # https://pillow.readthedocs.io/en/stable/reference/ImageFilter.html 3 | 4 | # image import 5 | image = Image.open('picture.jpg') 6 | 7 | # basic filters 8 | image_blur = image.filter(ImageFilter.BLUR) 9 | image_contour = image.filter(ImageFilter.CONTOUR) 10 | image_detail = image.filter(ImageFilter.DETAIL) 11 | image_edge = image.filter(ImageFilter.EDGE_ENHANCE) 12 | image_edge_more = image.filter(ImageFilter.EDGE_ENHANCE_MORE) 13 | image_find_edges = image.filter(ImageFilter.FIND_EDGES) 14 | image_emboss = image.filter(ImageFilter.EMBOSS) 15 | image_sharp = image.filter(ImageFilter.SHARPEN) 16 | image_smooth = image.filter(ImageFilter.SMOOTH) 17 | image_smooth_more = image.filter(ImageFilter.SMOOTH_MORE) 18 | 19 | # # rank filters 20 | # image_filtered_min = image.filter(ImageFilter.MinFilter(size = 5)) 21 | # image_filtered_median = image.filter(ImageFilter.MedianFilter(size = 5)) 22 | # image_filtered_max = image.filter(ImageFilter.MaxFilter(size = 5)) 23 | 24 | # multiband 25 | image_boxblur = image.filter(ImageFilter.BoxBlur(radius = 4)) 26 | image_gaussblur = image.filter(ImageFilter.GaussianBlur(radius = 10)) 27 | image_unsharp = image.filter(ImageFilter.UnsharpMask(radius = 4)) 28 | 29 | # combine filters: blur + emboss 30 | image_emboss = image.filter(ImageFilter.EMBOSS) 31 | image_emboss_blur = image_emboss.filter(ImageFilter.GaussianBlur(radius = 2)) 32 | 33 | image_gaussblur.save('7.png') -------------------------------------------------------------------------------- /pillow5_colors.py: -------------------------------------------------------------------------------- 1 | from PIL import Image, ImageFilter 2 | from numpy import array 3 | 4 | # image import 5 | image = Image.open('picture.jpg') 6 | 7 | ################################# 8 | # Analysing picture information # 9 | ################################# 10 | 11 | # numpy section 12 | # print(array(image)) 13 | # print(array(image.getchannel('R'))) 14 | 15 | # colors only 16 | # print(image.getpixel((0,0))) 17 | # print(image.getcolors(maxcolors = image.size[0] * image.size[1])) # maxcolors argument = 256 -> if image has more colors it returns none 18 | 19 | # getting picture information 20 | # print(image.mode) 21 | # print(image.getbands()) 22 | # print(image.info) 23 | 24 | # channels 25 | # red_channel = image.getchannel('R') 26 | # red_channel.show() 27 | 28 | ##################### 29 | # Color conversions # 30 | ##################### 31 | 32 | # 1 bit grayscale image 33 | # image_grayscale_1bit = image.convert('1') 34 | # print(array(image_grayscale_1bit, dtype = int)) 35 | # print(image_grayscale_1bit.getbands()) 36 | # image_grayscale_1bit.show() 37 | 38 | # 8 bit grayscale 39 | # grayscale_l = image.convert('L') 40 | # print(array(grayscale_l)) 41 | # print(grayscale_l.getbands()) 42 | # grayscale_l.show() 43 | 44 | # Palette 45 | # palette = image.convert('P') # 256 colors only 46 | # print(array(palette)) # not colors! references to a color in a palette 47 | # print(palette.getpalette()) 48 | # print(array(palette.getpalette()).reshape(256,3)) 49 | 50 | # palette_16 = image.convert('P',palette = Image.Palette.ADAPTIVE, colors = 16) 51 | 52 | # update the color palette 53 | # new_palette = [x // 2 for x in palette_16.getpalette()] 54 | # palette_16.putpalette(new_palette) 55 | # palette_16.show() 56 | 57 | ############################ 58 | # change individual pixels # 59 | ############################ 60 | 61 | # image.putpixel((100,200),(255,0,0)) 62 | for x in range(image.size[0]): 63 | for y in range(image.size[1]): 64 | if image.getpixel((x,y))[0] > 200: 65 | image.putpixel((x,y),(0,0,0)) 66 | image.show() -------------------------------------------------------------------------------- /pillow6_ImageOps.py: -------------------------------------------------------------------------------- 1 | from PIL import Image, ImageOps 2 | 3 | # image import 4 | image = Image.open('picture.jpg') 5 | 6 | # color changes 7 | image_contrast = ImageOps.autocontrast(image = image, cutoff = 5) 8 | image_inverted = ImageOps.invert(image) 9 | image_solarize = ImageOps.solarize(image = image, threshold = 100) 10 | image_posterize = ImageOps.posterize(image = image, bits = 1) 11 | image_grayscale = ImageOps.grayscale(image = image) 12 | image_equalized = ImageOps.equalize(image = image) 13 | image_colorize = ImageOps.colorize(image = image.convert('L'), black = 'blue', white = 'red') 14 | 15 | # dimension changes 16 | image_mirror = ImageOps.mirror(image) 17 | image_flip = ImageOps.flip(image) 18 | image_scale = ImageOps.scale(image = image, factor = 0.4) 19 | image_contain = ImageOps.contain(image = image, size = (500,200)) 20 | 21 | # Adding and removing 22 | image_border = ImageOps.expand(image = image, border = 100, fill = (255,255,0)) 23 | image_padded = ImageOps.pad(image = image, size = (2500,1600)) 24 | image_fit = ImageOps.fit(image = image, size = (500,300)) 25 | image_crop = ImageOps.crop(image = image, border = 400) 26 | 27 | image_flip.show() -------------------------------------------------------------------------------- /pillow7_deformer.py: -------------------------------------------------------------------------------- 1 | from PIL import Image, ImageOps 2 | 3 | class Deformer(): 4 | def getmesh(self,img): 5 | w,h = img.size 6 | # # define a shape in the original image 7 | # source_shape = (0,0,0,h,w - 1000,h,w,0) 8 | # # define a rectangle in the new image 9 | # target_rect = (0,0,w,h) # left,top,right,bottom 10 | 11 | left = ((0,0,w // 2, h),(0, 0, 0, h, w // 2, h, w // 2 , 0)) 12 | right = ((w // 2,0,w,h),(w // 2, 0, w // 2, h, 0, h, 0 , 0)) 13 | flip = ((w // 2, 0, w, h ),(w // 2, h, w // 2, 0, w, 0, w - 1000 , h)) 14 | 15 | # return all the shapes 16 | return [left,right] 17 | 18 | # image import 19 | image = Image.open('picture.jpg') 20 | deform = ImageOps.deform(image,Deformer()) 21 | deform.save('17.png') 22 | 23 | # more advanced example: https://www.pythoninformer.com/python-libraries/pillow/imageops-deforming/ -------------------------------------------------------------------------------- /pillow8_shapes.py: -------------------------------------------------------------------------------- 1 | from PIL import Image, ImageDraw, ImageFont 2 | 3 | # image import 4 | image = Image.open('picture.jpg') 5 | draw = ImageDraw.Draw(image) # creates a draw object 6 | 7 | # draw shapes 8 | draw.rectangle((200,400,700,600), fill = (255,0,0), outline = 'yellow', width = 5) 9 | draw.ellipse((200,400,700,600), fill = (255,0,255), outline = 'purple', width = 5) 10 | draw.polygon(((0,0),(100,0),(100,100),(50,200)),fill = 'blue',outline = 'pink') 11 | draw.line(((800,1000),(1000,1100),(1200,1000)),fill = 'black', width = 10, joint = 'curve') 12 | 13 | # draw circle thingies 14 | # draw.arc((800,100,1000,300),start = 10, end = 40, width = 10, fill = 'red') 15 | # draw.chord((800,100,1000,300),start = 10, end = 180, width = 10, fill = 'red') 16 | draw.pieslice((800,100,1000,300),start = 10, end = 180, width = 10, fill = 'red') 17 | 18 | # draw text 19 | font = ImageFont.truetype('Halogen.ttf', size = 80) 20 | draw.text((1300,640),'panda', font = font, fill = (0,255,255), align = 'center', anchor = 'rt') 21 | 22 | 23 | image.save('18.png') -------------------------------------------------------------------------------- /pillow9_merging.py: -------------------------------------------------------------------------------- 1 | from PIL import Image, ImageChops 2 | 3 | panda = Image.open('picture.jpg').convert('RGBA') 4 | owl = Image.open('owl.jpg') # same size as panda image 5 | python = Image.open('python.png') # smaller than the panda image + has transparency 6 | 7 | # merging images with image.methods() 8 | image_blend = Image.blend(panda,owl,10) # both images need same size and mode 9 | # image_composite = Image.composite(panda,owl,Image.new('L',panda.size,50)) 10 | 11 | # image paste 12 | panda.paste(python,(100,300), mask = python) 13 | 14 | # channel operations 15 | # image_overlay = ImageChops.overlay(panda,owl) 16 | # image_darker = ImageChops.darker(panda,owl) 17 | # image_lighter = ImageChops.lighter(panda,owl) 18 | # image_soft_light = ImageChops.soft_light(panda,owl) 19 | # image_hard_light = ImageChops.hard_light(panda,owl) 20 | # image_difference = ImageChops.difference(panda,owl) 21 | # image_modulo = ImageChops.add_modulo(panda,owl) 22 | # image_screen = ImageChops.screen(panda,owl) 23 | 24 | # more complex channel operations 25 | # image_add = ImageChops.add(panda,owl,scale = 2.0,offset = 100) 26 | # image_subtract = ImageChops.subtract(panda,owl,scale = 2.0,offset = 100) 27 | # image_logical_and = ImageChops.logical_and(panda.convert('1'),owl.convert('1')) 28 | # image_logical_or = ImageChops.logical_or(panda.convert('1'),owl.convert('1')) 29 | 30 | # super easy 31 | # image_invert = ImageChops.invert(panda) 32 | 33 | # masking 34 | # mask must have a specfic mode: RGBA, 1 or L 35 | # mask = Image.open('mask.png') 36 | # image_masked_alpha = Image.alpha_composite(panda.convert('RGBA'),mask) 37 | # image_masked = Image.composite(owl,panda,mask.convert('L')) 38 | 39 | panda.show() -------------------------------------------------------------------------------- /python.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clear-code-projects/Pillow/ef5f631dd9329d3c4421454cfa3b9ad57ba40fc0/python.png --------------------------------------------------------------------------------