|
|
Line 244: |
Line 244: |
| [[File:Kaleidogif1.gif]] | | [[File:Kaleidogif1.gif]] |
|
| |
|
| Source image : illustration from Oliver Jeffers
| | [[File:Kaleidogif2.gif]] |
| [[File:JEFFERS>JPG]] | |
|
| |
|
| This is the code of Gif Version
| |
|
| |
|
| [[Media:jeffers.gif |Example result .GIF]]
| |
|
| |
|
| ======Kaleidoscope 360 GIF ========
| | The complete code can be found here in the GitHub link. |
| <pre style="font-size:normal" >
| |
| | |
| from PIL import Image, ImageDraw,ImageFilter
| |
| import PIL.ImageOps as im
| |
| import numpy as np
| |
| import moviepy.editor as mpy
| |
| | |
| | |
| | |
| def onepic():
| |
| global output
| |
| #creat mask base the same size with source image
| |
| mask = Image.new('RGBA', base.size, (255,255,255,0))
| |
| x, y = base.size
| |
| print("base size: %sx%s"%(x,y))
| |
| | |
| # one variable to vary the size of triangle
| |
| var = y/28
| |
| | |
| # Define triangle mask position (triangle with 20 degree)
| |
| (originx,originy) = (int(0.4*x),int(y))
| |
| trih = int(12*var) #fix formular for triangle height
| |
| triw = int(4.2*var) #fix formular for triangle width
| |
| polygonpos = [(originx,originy),
| |
| (originx+triw,originy),
| |
| (originx+triw/2,originy-trih)]
| |
| print(trih,triw)
| |
| | |
| | |
| # Create mask
| |
| draw = ImageDraw.Draw(mask,'RGBA')
| |
| draw.polygon(polygonpos,(0,0,0,255))
| |
| del draw
| |
| mask.save("mask.png")
| |
| | |
| # Get the Alpha band from the template
| |
| tmplt = Image.open('mask.png')
| |
| A = tmplt.split()[3]
| |
| | |
| | |
| #make one piece of triangle on transparent bg
| |
| [R,G,B]=base.split()
| |
| tri = Image.merge('RGBA', (R, G, B, A))
| |
| | |
| #crop it to the exact size of triangle!! to create primary pattern
| |
| #box (left, top , right, buttom)
| |
| box =(originx,(originy-trih),(originx+triw),originy)
| |
| pattern_plain=tri.crop(box)
| |
| pattern_plain.save('pattern_plain.png')
| |
| print('....pattern created....')
| |
| | |
| | |
| # add style to pattern
| |
| pattern = pattern_plain
| |
| #pattern= pattern_plain.filter(ImageFilter.EDGE_ENHANCE)
| |
| pattern.save('pattern_tri.png')
| |
| print('....stylized pattern....')
| |
| | |
| | |
| #make square canvas for the output (wide = double size of height of primary pattern)
| |
| canvas =Image.new('RGBA',(2*trih,2*trih), (255,255,255,0))
| |
| canvas.save('tmpcanvas.png')
| |
| pcanvas=Image.new('RGBA',(2*trih,2*trih), (255,255,255,0))
| |
| | |
| | |
| | |
| | |
| #put pattern on the canvas
| |
| #make sure to put the tip of the triangle at the center of the canvas
| |
| #because when we rotate the center of the object is the pivot point
| |
| #note: paste command require the coordinate of top left corner
| |
| #so point to paste the pattern is . . .
| |
| ccenterx = int(trih-triw/2)
| |
| canvas.paste(pattern_plain,(ccenterx,trih))
| |
| | |
| | |
| # start rotate the pattern around every 40 degree
| |
| | |
| for i in range (0,360,40):
| |
| tmpcanvas = canvas
| |
| tmppat = canvas.rotate(i)
| |
| canvas= Image.alpha_composite(tmpcanvas,tmppat)
| |
| | |
| # now we get half of the things
| |
| half = canvas
| |
| print('half already')
| |
| #mirror the half and put in the space to create simple kaleidoscpoe effect
| |
| mirror = im.mirror(half)
| |
| half2= mirror.rotate(20)
| |
| print('mirrored')
| |
| | |
| #merge 2 half
| |
| output=Image.alpha_composite(half,half2)
| |
| output.save("output.png")
| |
| | |
| | |
| #def makegif():
| |
| #clip = mpy.ImageSequenceClip(outfilename, fps=3)
| |
| #clip.write_gif("%s.gif"%filename)
| |
| | |
| def makekaleido(image) :
| |
| global base, filename, source, imgfile, n, outfilename
| |
| #IN CASE Working on filename in the laptop
| |
| #put image path
| |
| imgfile = "tweetimg.jpg"
| |
| filename = imgfile[:-4]
| |
| print(filename)
| |
|
| |
| #load Image
| |
| source = Image.open(imgfile)
| |
|
| |
| #source = image.copy()
| |
| x, y = source.size
| |
| | |
| if x > 1000:
| |
| newy = int(1000*y/x)
| |
| source =source.resize((1000,newy), Image.ANTIALIAS)
| |
| print('resize to %sx%s'%source.size)
| |
| | |
| #creat mask base the same size with source image
| |
| mask = Image.new('RGBA', source.size, (255,255,255,0))
| |
| print("mask size:%sx%s"%source.size)
| |
|
| |
| | |
| #rotate source n times for a degree
| |
| n= 10
| |
| outfilename=[]
| |
| for a in range(n+n-2):
| |
| outfilename.insert(a,'0')
| |
| a= 10
| |
| base = source
| |
| for i in range(n):
| |
| base = source.rotate(31+i*a)
| |
| onepic()
| |
| output.save('%s%s.png'%(filename,i))
| |
| outfilename[i] = filename+str(i)+'.png'
| |
| if i!=0:
| |
| outfilename[2*n-2-i] = filename+str(i)+'.png'
| |
|
| |
| clip = mpy.ImageSequenceClip(outfilename, fps=3)
| |
| clip.write_gif("%s.gif"%filename)
| |
| image2 = Image.open('tweetimg3.png')
| |
| | |
| return image2,clip
| |
| | |
|
| |
| | |
| if __name__ == '__main__':
| |
| | |
| makekaleido(image)
| |
| </pre>
| |