Exit early if we're done rendering the main animation, allow background color override.
This commit is contained in:
parent
47525837cd
commit
f209bcbe54
@ -118,7 +118,7 @@ class AFPRenderer(VerboseOutput):
|
|||||||
data.parse()
|
data.parse()
|
||||||
self.swfs[name] = data
|
self.swfs[name] = data
|
||||||
|
|
||||||
def render_path(self, path: str, verbose: bool = False) -> Tuple[int, List[Image.Image]]:
|
def render_path(self, path: str, background_color: Optional[Color] = None, verbose: bool = False) -> Tuple[int, List[Image.Image]]:
|
||||||
# Given a path to a SWF root animation or an exported animation inside a SWF,
|
# Given a path to a SWF root animation or an exported animation inside a SWF,
|
||||||
# attempt to render it to a list of frames, one per image.
|
# attempt to render it to a list of frames, one per image.
|
||||||
components = path.split(".")
|
components = path.split(".")
|
||||||
@ -130,6 +130,7 @@ class AFPRenderer(VerboseOutput):
|
|||||||
if swf.exported_name == components[0]:
|
if swf.exported_name == components[0]:
|
||||||
# This is the SWF we care about.
|
# This is the SWF we care about.
|
||||||
with self.debugging(verbose):
|
with self.debugging(verbose):
|
||||||
|
swf.color = background_color or swf.color
|
||||||
return self.__render(swf, components[1] if len(components) > 1 else None)
|
return self.__render(swf, components[1] if len(components) > 1 else None)
|
||||||
|
|
||||||
raise Exception(f'{path} not found in registered SWFs!')
|
raise Exception(f'{path} not found in registered SWFs!')
|
||||||
@ -598,7 +599,21 @@ class AFPRenderer(VerboseOutput):
|
|||||||
frameno += 1
|
frameno += 1
|
||||||
|
|
||||||
# Garbage collect any clips that we're finished with.
|
# Garbage collect any clips that we're finished with.
|
||||||
|
removed_referenced_tag = False
|
||||||
|
for c in self.__clips:
|
||||||
|
if c.finished:
|
||||||
|
if self.__visible_tag == c.tag_id:
|
||||||
|
removed_referenced_tag = True
|
||||||
|
|
||||||
|
self.vprint(f" Removing clip based on Tag ID {clip.tag_id} because it is finished playing.")
|
||||||
|
|
||||||
self.__clips = [c for c in self.__clips if not c.finished]
|
self.__clips = [c for c in self.__clips if not c.finished]
|
||||||
|
|
||||||
|
# Exit early if we removed all tags we would be rendering.
|
||||||
|
if removed_referenced_tag and self.__clips:
|
||||||
|
if not any(c.tag_id == self.__visible_tag for c in self.__clips):
|
||||||
|
self.vprint("Finishing early because the tag we are rendering has deconstructed.")
|
||||||
|
break
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
# Allow ctrl-c to end early and render a partial animation.
|
# Allow ctrl-c to end early and render a partial animation.
|
||||||
print(f"WARNING: Interrupted early, will render only {len(frames)} of animation!")
|
print(f"WARNING: Interrupted early, will render only {len(frames)} of animation!")
|
||||||
|
@ -9,7 +9,7 @@ import textwrap
|
|||||||
from PIL import Image, ImageDraw # type: ignore
|
from PIL import Image, ImageDraw # type: ignore
|
||||||
from typing import Any, Dict
|
from typing import Any, Dict
|
||||||
|
|
||||||
from bemani.format.afp import TXP2File, Shape, SWF, AFPRenderer
|
from bemani.format.afp import TXP2File, Shape, SWF, AFPRenderer, Color
|
||||||
from bemani.format import IFS
|
from bemani.format import IFS
|
||||||
|
|
||||||
|
|
||||||
@ -167,6 +167,12 @@ def main() -> int:
|
|||||||
action="store_true",
|
action="store_true",
|
||||||
help="Display verbuse debugging output",
|
help="Display verbuse debugging output",
|
||||||
)
|
)
|
||||||
|
render_parser.add_argument(
|
||||||
|
"--background-color",
|
||||||
|
type=str,
|
||||||
|
default=None,
|
||||||
|
help="Set the background color of the animation, overriding a default if present in the SWF.",
|
||||||
|
)
|
||||||
|
|
||||||
list_parser = subparsers.add_parser('list', help='List out the possible paths to render from a series of SWFs')
|
list_parser = subparsers.add_parser('list', help='List out the possible paths to render from a series of SWFs')
|
||||||
list_parser.add_argument(
|
list_parser.add_argument(
|
||||||
@ -558,12 +564,7 @@ def main() -> int:
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
if args.action == "render":
|
if args.action == "render":
|
||||||
# Render the gif/webp frames.
|
# Verify the correct params.
|
||||||
duration, images = renderer.render_path(args.path, verbose=args.verbose)
|
|
||||||
if len(images) == 0:
|
|
||||||
raise Exception("Did not render any frames!")
|
|
||||||
|
|
||||||
# Write them out to a new file.
|
|
||||||
if args.output.lower().endswith(".gif"):
|
if args.output.lower().endswith(".gif"):
|
||||||
fmt = "GIF"
|
fmt = "GIF"
|
||||||
elif args.output.lower().endswith(".webp"):
|
elif args.output.lower().endswith(".webp"):
|
||||||
@ -573,6 +574,28 @@ def main() -> int:
|
|||||||
else:
|
else:
|
||||||
raise Exception("Unrecognized file extension for output!")
|
raise Exception("Unrecognized file extension for output!")
|
||||||
|
|
||||||
|
# Allow overriding background color.
|
||||||
|
if args.background_color:
|
||||||
|
colorvals = args.background_color.split(",")
|
||||||
|
if len(colorvals) not in [3, 4]:
|
||||||
|
raise Exception("Invalid color, specify a color as a comma-separated RGB or RGBA value!")
|
||||||
|
|
||||||
|
if len(colorvals) == 3:
|
||||||
|
colorvals.append("255")
|
||||||
|
colorints = [int(c.strip()) for c in colorvals]
|
||||||
|
for c in colorints:
|
||||||
|
if c < 0 or c > 255:
|
||||||
|
raise Exception("Color values should be between 0 and 255!")
|
||||||
|
|
||||||
|
color = Color(*[c / 255.0 for c in colorints])
|
||||||
|
else:
|
||||||
|
color = None
|
||||||
|
|
||||||
|
# Render the gif/webp frames.
|
||||||
|
duration, images = renderer.render_path(args.path, verbose=args.verbose, background_color=color)
|
||||||
|
if len(images) == 0:
|
||||||
|
raise Exception("Did not render any frames!")
|
||||||
|
|
||||||
if fmt in ["GIF", "WEBP"]:
|
if fmt in ["GIF", "WEBP"]:
|
||||||
# Write all the frames out in one file.
|
# Write all the frames out in one file.
|
||||||
with open(args.output, "wb") as bfp:
|
with open(args.output, "wb") as bfp:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user