1
0
mirror of synced 2025-01-18 22:24:04 +01:00

Implement support for adding a background image on top of the background color but below the animation.

This commit is contained in:
Jennifer Taylor 2021-05-23 23:37:05 +00:00
parent cc5cdde995
commit 7eb41a45e7
2 changed files with 85 additions and 3 deletions

View File

@ -291,6 +291,7 @@ class AFPRenderer(VerboseOutput):
self,
path: str,
background_color: Optional[Color] = None,
background_image: Optional[Image.Image] = None,
only_depths: Optional[List[int]] = None,
movie_transform: Matrix = Matrix.identity(),
verbose: bool = False,
@ -301,7 +302,7 @@ class AFPRenderer(VerboseOutput):
# This is the SWF we care about.
with self.debugging(verbose):
swf.color = background_color or swf.color
return self.__render(swf, only_depths, movie_transform)
return self.__render(swf, only_depths, movie_transform, background_image)
raise Exception(f'{path} not found in registered SWFs!')
@ -1009,7 +1010,13 @@ class AFPRenderer(VerboseOutput):
# We didn't find the tag we were after.
return None
def __render(self, swf: SWF, only_depths: Optional[List[int]], movie_transform: Matrix) -> Tuple[int, List[Image.Image]]:
def __render(
self,
swf: SWF,
only_depths: Optional[List[int]],
movie_transform: Matrix,
background_image: Optional[Image.Image],
) -> Tuple[int, List[Image.Image]]:
# First, let's attempt to resolve imports.
self.__registered_objects = self.__handle_imports(swf)
@ -1039,6 +1046,69 @@ class AFPRenderer(VerboseOutput):
)
self.__movie = Movie(root_clip)
# If we have a background image, add it to the root clip.
if background_image:
# Stretch the image to make sure it fits the entire frame.
imgwidth = float(background_image.width)
imgheight = float(background_image.height)
background_matrix = Matrix(
a=swf.location.width / imgwidth,
b=0,
c=0,
d=swf.location.height / imgheight,
tx=0,
ty=0,
)
# Register the background image with the texture library.
name = f"{swf.exported_name}_inserted_background"
self.textures[name] = background_image.convert("RGBA")
# Place an instance of this background on the root clip.
root_clip.placed_objects.append(
PlacedShape(
-1,
-1,
Point.identity(),
background_matrix,
Color(1.0, 1.0, 1.0, 1.0),
Color(0.0, 0.0, 0.0, 0.0),
0,
None,
RegisteredShape(
-1,
# The coordinates of the rectangle of the shape in screen space.
[
Point(0.0, 0.0),
Point(imgwidth, 0.0),
Point(imgwidth, imgheight),
Point(0.0, imgheight),
],
# The coordinates of the original texture in UV space (we don't use this).
[
Point(0.0, 0.0),
Point(1.0, 0.0),
Point(1.0, 1.0),
Point(0.0, 1.0),
],
# No texture colors.
[],
[
DrawParams(
# Instantiable, includes texture.
0x3,
# The texture this should use for drawing.
name,
# The coordinates of the triangles that get drawn (we don't use this).
[0, 1, 2, 2, 1, 3],
# The blend color.
None,
),
],
),
),
)
# Create the root mask for where to draw the root clip.
movie_mask = Image.new("RGBA", actual_size, color=(255, 0, 0, 255))

View File

@ -262,6 +262,12 @@ def main() -> int:
default=None,
help="Set the background color of the animation as a comma-separated RGB or RGBA color, overriding a default if present in the SWF.",
)
render_parser.add_argument(
"--background-image",
type=str,
default=None,
help="Set a background image to be placed behind the animation. Note that it will be stretched to fit the animation.",
)
render_parser.add_argument(
"--only-depths",
type=str,
@ -731,6 +737,12 @@ def main() -> int:
else:
color = None
# Allow inserting a background image.
if args.background_image:
background = Image.open(args.background_image)
else:
background = None
# Calculate the size of the SWF so we can apply scaling options.
swf_location = renderer.compute_path_location(args.path)
requested_width = swf_location.width
@ -783,7 +795,7 @@ def main() -> int:
depths = [int(d.strip()) for d in args.only_depths.split(",")]
else:
depths = None
duration, images = renderer.render_path(args.path, verbose=args.verbose, background_color=color, only_depths=depths, movie_transform=transform)
duration, images = renderer.render_path(args.path, verbose=args.verbose, background_color=color, background_image=background, only_depths=depths, movie_transform=transform)
if len(images) == 0:
raise Exception("Did not render any frames!")