PilAnimate is a python library that renders video frame by frame, using PIL.
Documentations are up to date for version 0.4.1. A lot of the library is just a wrapper for PIL, so if you are having trouble it could be useful to reference those if you encounter any issues.
Why use PilAnimate?
I mostly made PilAnimate for my personal use, and I'm sure there's probably better ones out there, but I made PilAnimate to be fairly simple and easily extendable. It renders frame by frame, meaning that even the most complex tasks can be completed on old computers, albeit slowly.
Install
Animation
Class
Creates layers
Parameters:
- layer_num: number of layers
- size (optional=(1600,900)): size in pixels [width,height]
- fps (optional=25): frames per second
- mode (optional="RGBA"): Type and depth of a pixel in the image. See PIL docs.
- color (optional=0): background color to use for the image
Returns: itself
Properties: layers, fps, mode, size
export
Function
Turns frames into video.
Parameters:
- filename (optional="hey"): The name of the output file
Returns: Nothing, creates filename+".avi" video
Layer
Class
Creates layer. A layer is essentially an array of images. When the video is exporting, the layers will be pasted on each other to create an array of frames (layer 0 is at the bottom).
Warning: Do not create this class yourself, making the Animation class will do it for you.
Parameters:
- size: size in pixels [width,height]
- fps: frames per second
- mode (optional="RGBA"): Type and depth of a pixel in the image
- color (optional=0): background color to use for the image
Returns: itself
Properties: size, img, layer, fps, frames, mode
createPoint
Function
Creates a point at coords
Parameters:
- coords: Coordinates of the point [x,y]
- fill (optional=None): Color of pixel
Returns: nothing
createLine
Function
Creates line, where each array [x,y] inside coords is a point, connected in order.
Parameters:
- coords: Coordinates of line [x,y]...]
- fill (optional=None): Color of line
- width (optional=0): Width of line
- joint (optional=None): if 'curve', joint type between the points is curved
Returns: nothing
createArc
Function
Creates arc with starting and ending angles inside the bounding box.
Parameters:
- boundingBox: array consisting of upper left and lower right corners [x,y]]
- startAngle: angle in degreees
- endAngle: angle in degrees
- fill (optional=None): color of arc
- width (optional=0): width of arc line
Returns: nothing
createEllipse
Function
Creates ellipse inside bounding box
Parameters:
- boundingBox: array consisting of upper left and lower right corners [x,y]]
- fill (optional=None): color of ellipse inside
- outline (optional=None): outline color
- width (optional=0): pixel width of outline
Returns: nothing
createPolygon
Function
Creates polygon
Parameters:
- coords: List of points of the polygon outline [x,y]...]
- fill (optional=None): color of polygon inside
- outline (optional=None): outline color
Returns: nothing
createRectangle
Function
Creates rectangle
Parameters:
- boundingBox: array consisting of upper left and lower right corners [x,y]]
- fill (optional=None): color of rectangle inside
- outline (optional=None): outline color
- width (optional=1): width of outline
Returns: nothing
createRoundedRectangle
Function
Creates a rounded rectangle
Parameters:
- boundingBox: array consisting of upper left and lower right corners [x,y]]
- radius (optional=0): radius of the rounded corners of the rectangle
- fill (optional=None): color of rectangle inside
- outline (optional=None): outline color
- width (optional=0): width of outline
Returns: nothing
fillAll
Function
Fills entire layer with color
Parameters:
- fill (optional=None): fill of frame
- outline (optional=None): outline color of frame
- width (optional=0): outline line width
Returns: nothing
createText
Function
Creates text at coords to layer. Has a kinds of parameters that can be fiddled with, making it a really powerful function.
Parameters:
- anchorCoords: Anchor coordinates of the text
- text: The text to be added
- fill (optional=None): Fill color of text
- font (optional=None): A Pil ImageFont
- anchor (optional=None): Relative location of anchor to the text.
- spacing (optional=4): Number of pixels between the lines of text
- align (optional='left'): Alignment of lines (center, left, or right)
- direction (optional=None): Direction of text. See PIL docs for more information.
- features (optional=None): OpenType font features. See PIL docs for more information.
- language (optional=None): Language of text. See PIL docs for more information.
- stroke_width (optional=0): Width of stroke
- stroke_fill (optional=None): Fill color of the stroke
- embedded_color (optional=False): True/False to specify if font embedded color glyphs should be used or not
Returns: nothing
addImage
Function
Adds image to layer
Parameters:
- imageToAdd: PIL Image
- coords (optional=None): Coords to put image. Array that is upper left and lower right corner. ((x,y), (x,y))
Returns: nothing
addGif
Function
Adds a gif to the layer (this function also creates frames for you, for the number of frames long the gif is * times_to_repeat frames)
Parameters:
- gif_location: location of the gif in the file system
- times_to_repeat: times to repeat the gif
- coords (optional=None): Coords to put image. Array that is upper left and lower right corner. ((x,y), (x,y))
Returns: nothing, but appends frames
rotate
Function
Rotates layer
Parameters:
- angle: degrees
- center (optional=None): Center of rotation,
- outsideFillColor (optional=None):
- copy (optional=None): a PIL Image. Probably want this to be a copy of the current layer.
Returns: nothing
translate
Function
Move layer
Parameters:
- x: amount of pixels to move horizontally
- y: amount of pixels to move vertically
- img: copy of current layer
Returns: nothing
changeOpacity
Function
Changes opacity (transparency) of the layer, of every non transparent pixel.
Parameters:
- value: new opacity from 0 to 100, where 0 is invisible and 100 is opaque (fully non transparent)
Returns: nothing
changeEntireOpacity
Function
Changes opacity of entire layer, including transparent pixels, so only use this for layers with no transparent parts
Parameters:
- value: new opacity from 0 to 100, where 0 is invisible and 100 is opaque (fully non transparent)
Returns: nothing
fadeIn
Function
Slowly fades in a layer, going from transparent to fully opaque.
Parameters:
- frames: number of frames it should take to become fully opaque
Returns: nothing, but appends frames
fadeOut
Function
Slowly fades out a layer, going from fully opaque to fully transparent.
Parameters:
- frames: number of frames it should take to become fully transparent
Returns: nothing, but appends frames
transform
Function
Transforms layer. This function is very complicated so and frankly I have no clue what most of thse are, so please refer to PIL Docs for more detail.
Parameters:
- size: output size
- method: transformation method, so please refer to PIL Docs
- data (optional=None): According to PIL docs, 'extra data to the transformation method.'
- resample (optional=0): Resampling filter, please refer to PIL Docs
- fill (optional=1): Please refer to PIL Docs
- fillcolor (optional=None): Fill color for area outside transformed image
Returns: nothing
blur
Function
Blurs layer
Parameters: none
Returns: nothing
clear
Function
Clears area of layer, turning it transparent
Parameters:
- coords: Array that is upper left and lower right corner of the area that should be cleared. ((x,y), (x,y))
clearAll
Function
Clears entire layer, turning it transparent
Parameters: none
Returns: nothing
saveFrame
Function
Adds the layer in its current state to the frames array
Parameters: none
Returns: nothing, but appends a frame
doNothing
Function
Adds frames without changing the layer
Parameters:
- frames: number of frames to append
Returns: nothing
save
Function
Save current layer as a file
Parameters:
- filename: file name of current layer
Returns: nothing
rise
Function
Make layer slowly rise
Parameters:
- frames: number of frames the rising should last
- total_rise_amount: amount of pixels it should move up by
Returns: nothing, but appends frames
descend
Function
Make layer slowly descend
Parameters:
- frames: number of frames the descending should last
- total_descend_amount: amount of pixels it should down up by
Returns: nothing, but appends frames
slide
Function
Makes the layer slide to the side
Parameters:
- frames: number of frames the sliding should last
- total_slide_amount: amount of pixels it should go to the side
Returns: nothing, but appends frames
spin
Function
Makes the layer spin
Parameters:
- frames: number of frames the spinning should last
- degrees: amount of degrees to spin
- center: center where the rest of the image should spin around (x,y) coordinates
Returns: nothing, but appends frames
Example
Here's a basic example that creates a sun rising from the sea:
animation = Animation(3)
animation.layers[0].fillAll(fill="SkyBlue")
#sun layer
animation.layers[1].createEllipse(((700,650),(900,850)), fill="yellow")
#ocean layer
animation.layers[2].createRectangle(((0, 500),(1600,900)), fill="Blue", width=0)
animation.layers[0].doNothing(100)
animation.layers[2].doNothing(100)
animation.layers[1].rise(100, -501)
animation.export()
Extend
Example of an extension I made that makes backgrounds:
import math
class Background():
#remember to add params
def __init__(self, layer, background_image):
self.background_image = background_image
self.layer = layer
self.layer.addImage(self.background_image.copy().crop((0,0,self.layer.size[0],self.layer.size[1])), coords=(0, 0, self.layer.size[0], self.layer.size[1]))
def pan_down(self, frames, all_the_way=True):
#speed is pixels per frame
#(background_image height-layer height)/speed
#
amount = (self.background_image.size[1]-self.layer.size[1])/frames
amount = math.floor(amount)
for i in range(frames-1):
self.layer.addImage(self.background_image.copy().crop((0, i*amount, self.background_image.size[0], i*amount+self.layer.size[1])), coords=(0, 0, self.layer.size[0], self.layer.size[1]))
self.layer.saveFrame()
if all_the_way:
self.layer.addImage(self.background_image.copy().crop((0, (self.background_image.size[1]-self.layer.size[1]), self.background_image.size[0], (self.background_image.size[1]-self.layer.size[1])+self.layer.size[1])), coords=(0, 0, self.layer.size[0], self.layer.size[1]))
self.layer.saveFrame()
PilAnimate is a python library that renders video frame by frame, using PIL.
Documentations are up to date for version 0.4.1. A lot of the library is just a wrapper for PIL, so if you are having trouble it could be useful to reference those if you encounter any issues.
## Why use PilAnimate?
I mostly made PilAnimate for my personal use, and I'm sure there's probably better ones out there, but I made PilAnimate to be fairly simple and easily extendable. It renders frame by frame, meaning that even the most complex tasks can be completed on old computers, albeit slowly.
## Install
```
pip install pilanimate
```
## Animation
**Class**
Creates layers
Parameters:
- layer_num: number of layers
- size (optional=(1600,900)): size in pixels [width,height]
- fps (optional=25): frames per second
- mode (optional="RGBA"): Type and depth of a pixel in the image. See PIL docs.
- color (optional=0): background color to use for the image
Returns: itself
Properties: layers, fps, mode, size
### export
**Function**
Turns frames into video.
Parameters:
- filename (optional="hey"): The name of the output file
Returns: Nothing, creates filename+".avi" video
## Layer
**Class**
Creates layer. A layer is essentially an array of images. When the video is exporting, the layers will be pasted on each other to create an array of frames (layer 0 is at the bottom).
> Warning: Do not create this class yourself, making the Animation class will do it for you.
Parameters:
- size: size in pixels [width,height]
- fps: frames per second
- mode (optional="RGBA"): Type and depth of a pixel in the image
- color (optional=0): background color to use for the image
Returns: itself
Properties: size, img, layer, fps, frames, mode
### createPoint
**Function**
Creates a point at coords
Parameters:
- coords: Coordinates of the point [x,y]
- fill (optional=None): Color of pixel
Returns: nothing
### createLine
**Function**
Creates line, where each array [x,y] inside coords is a point, connected in order.
Parameters:
- coords: Coordinates of line [[x,y],[x,y],[x,y]...]
- fill (optional=None): Color of line
- width (optional=0): Width of line
- joint (optional=None): if 'curve', joint type between the points is curved
Returns: nothing
### createArc
**Function**
Creates arc with starting and ending angles inside the bounding box.
Parameters:
- boundingBox: array consisting of upper left and lower right corners [[x,y],[x,y]]
- startAngle: angle in degreees
- endAngle: angle in degrees
- fill (optional=None): color of arc
- width (optional=0): width of arc line
Returns: nothing
### createEllipse
**Function**
Creates ellipse inside bounding box
Parameters:
- boundingBox: array consisting of upper left and lower right corners [[x,y],[x,y]]
- fill (optional=None): color of ellipse inside
- outline (optional=None): outline color
- width (optional=0): pixel width of outline
Returns: nothing
### createPolygon
**Function**
Creates polygon
Parameters:
- coords: List of points of the polygon outline [[x,y],[x,y],[x,y]...]
- fill (optional=None): color of polygon inside
- outline (optional=None): outline color
Returns: nothing
### createRectangle
**Function**
Creates rectangle
Parameters:
- boundingBox: array consisting of upper left and lower right corners [[x,y],[x,y]]
- fill (optional=None): color of rectangle inside
- outline (optional=None): outline color
- width (optional=1): width of outline
Returns: nothing
### createRoundedRectangle
**Function**
Creates a rounded rectangle
Parameters:
- boundingBox: array consisting of upper left and lower right corners [[x,y],[x,y]]
- radius (optional=0): radius of the rounded corners of the rectangle
- fill (optional=None): color of rectangle inside
- outline (optional=None): outline color
- width (optional=0): width of outline
Returns: nothing
### fillAll
**Function**
Fills entire layer with color
Parameters:
- fill (optional=None): fill of frame
- outline (optional=None): outline color of frame
- width (optional=0): outline line width
Returns: nothing
### createText
**Function**
Creates text at coords to layer. Has a kinds of parameters that can be fiddled with, making it a really powerful function.
Parameters:
- anchorCoords: Anchor coordinates of the text
- text: The text to be added
- fill (optional=None): Fill color of text
- font (optional=None): A Pil ImageFont
- anchor (optional=None): Relative location of anchor to the text.
- spacing (optional=4): Number of pixels between the lines of text
- align (optional='left'): Alignment of lines (center, left, or right)
- direction (optional=None): Direction of text. See PIL docs for more information.
- features (optional=None): OpenType font features. See PIL docs for more information.
- language (optional=None): Language of text. See PIL docs for more information.
- stroke_width (optional=0): Width of stroke
- stroke_fill (optional=None): Fill color of the stroke
- embedded_color (optional=False): True/False to specify if font embedded color glyphs should be used or not
Returns: nothing
### addImage
**Function**
Adds image to layer
Parameters:
- imageToAdd: PIL Image
- coords (optional=None): Coords to put image. Array that is upper left and lower right corner. ((x,y), (x,y))
Returns: nothing
### addGif
**Function**
Adds a gif to the layer (this function also creates frames for you, for the number of frames long the gif is * times_to_repeat frames)
Parameters:
- gif_location: location of the gif in the file system
- times_to_repeat: times to repeat the gif
- coords (optional=None): Coords to put image. Array that is upper left and lower right corner. ((x,y), (x,y))
Returns: nothing, but appends frames
### rotate
**Function**
Rotates layer
Parameters:
- angle: degrees
- center (optional=None): Center of rotation,
- outsideFillColor (optional=None):
- copy (optional=None): a PIL Image. Probably want this to be a copy of the current layer.
Returns: nothing
### translate
**Function**
Move layer
Parameters:
- x: amount of pixels to move horizontally
- y: amount of pixels to move vertically
- img: copy of current layer
Returns: nothing
### changeOpacity
**Function**
Changes opacity (transparency) of the layer, of every non transparent pixel.
Parameters:
- value: new opacity from 0 to 100, where 0 is invisible and 100 is opaque (fully non transparent)
Returns: nothing
### changeEntireOpacity
**Function**
Changes opacity of entire layer, including transparent pixels, so only use this for layers with no transparent parts
Parameters:
- value: new opacity from 0 to 100, where 0 is invisible and 100 is opaque (fully non transparent)
Returns: nothing
### fadeIn
**Function**
Slowly fades in a layer, going from transparent to fully opaque.
Parameters:
- frames: number of frames it should take to become fully opaque
Returns: nothing, but appends frames
### fadeOut
**Function**
Slowly fades out a layer, going from fully opaque to fully transparent.
Parameters:
- frames: number of frames it should take to become fully transparent
Returns: nothing, but appends frames
### transform
**Function**
Transforms layer. This function is very complicated so and frankly I have no clue what most of thse are, so please refer to PIL Docs for more detail.
Parameters:
- size: output size
- method: transformation method, so please refer to PIL Docs
- data (optional=None): According to PIL docs, 'extra data to the transformation method.'
- resample (optional=0): Resampling filter, please refer to PIL Docs
- fill (optional=1): Please refer to PIL Docs
- fillcolor (optional=None): Fill color for area outside transformed image
Returns: nothing
### blur
**Function**
Blurs layer
Parameters: none
Returns: nothing
### clear
**Function**
Clears area of layer, turning it transparent
Parameters:
- coords: Array that is upper left and lower right corner of the area that should be cleared. ((x,y), (x,y))
### clearAll
**Function**
Clears entire layer, turning it transparent
Parameters: none
Returns: nothing
### saveFrame
**Function**
Adds the layer in its current state to the frames array
Parameters: none
Returns: nothing, but appends a frame
### doNothing
**Function**
Adds frames without changing the layer
Parameters:
- frames: number of frames to append
Returns: nothing
### save
**Function**
Save current layer as a file
Parameters:
- filename: file name of current layer
Returns: nothing
### rise
**Function**
Make layer slowly rise
Parameters:
- frames: number of frames the rising should last
- total_rise_amount: amount of pixels it should move up by
Returns: nothing, but appends frames
### descend
**Function**
Make layer slowly descend
Parameters:
- frames: number of frames the descending should last
- total_descend_amount: amount of pixels it should down up by
Returns: nothing, but appends frames
### slide
**Function**
Makes the layer slide to the side
Parameters:
- frames: number of frames the sliding should last
- total_slide_amount: amount of pixels it should go to the side
Returns: nothing, but appends frames
### spin
**Function**
Makes the layer spin
Parameters:
- frames: number of frames the spinning should last
- degrees: amount of degrees to spin
- center: center where the rest of the image should spin around (x,y) coordinates
Returns: nothing, but appends frames
## Example
Here's a basic example that creates a sun rising from the sea:
```
from PilAnimate import Animation, ImageColor, Image
animation = Animation(3)
animation.layers[0].fillAll(fill="SkyBlue")
#sun layer
animation.layers[1].createEllipse(((700,650),(900,850)), fill="yellow")
#ocean layer
animation.layers[2].createRectangle(((0, 500),(1600,900)), fill="Blue", width=0)
animation.layers[0].doNothing(100)
animation.layers[2].doNothing(100)
animation.layers[1].rise(100, -501)
animation.export()
```
## Extend
Example of an extension I made that makes backgrounds:
```
from PilAnimate import Layer
import math
class Background():
#remember to add params
def __init__(self, layer, background_image):
self.background_image = background_image
self.layer = layer
self.layer.addImage(self.background_image.copy().crop((0,0,self.layer.size[0],self.layer.size[1])), coords=(0, 0, self.layer.size[0], self.layer.size[1]))
def pan_down(self, frames, all_the_way=True):
#speed is pixels per frame
#(background_image height-layer height)/speed
#
amount = (self.background_image.size[1]-self.layer.size[1])/frames
amount = math.floor(amount)
for i in range(frames-1):
self.layer.addImage(self.background_image.copy().crop((0, i*amount, self.background_image.size[0], i*amount+self.layer.size[1])), coords=(0, 0, self.layer.size[0], self.layer.size[1]))
self.layer.saveFrame()
if all_the_way:
self.layer.addImage(self.background_image.copy().crop((0, (self.background_image.size[1]-self.layer.size[1]), self.background_image.size[0], (self.background_image.size[1]-self.layer.size[1])+self.layer.size[1])), coords=(0, 0, self.layer.size[0], self.layer.size[1]))
self.layer.saveFrame()
```