mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
Tidy up tiles invocations, add documentation.
This commit is contained in:
parent
76b888de17
commit
7f816c9243
@ -15,65 +15,65 @@ from invokeai.app.invocations.baseinvocation import (
|
||||
)
|
||||
from invokeai.app.invocations.primitives import ImageField, ImageOutput
|
||||
from invokeai.app.services.image_records.image_records_common import ImageCategory, ResourceOrigin
|
||||
from invokeai.backend.tiles.tiles import calc_tiles, merge_tiles_with_linear_blending
|
||||
from invokeai.backend.tiles.tiles import calc_tiles_with_overlap, merge_tiles_with_linear_blending
|
||||
from invokeai.backend.tiles.utils import Tile
|
||||
|
||||
# TODO(ryand): Is this important?
|
||||
_DIMENSION_MULTIPLE_OF = 8
|
||||
|
||||
|
||||
class TileWithImage(BaseModel):
|
||||
tile: Tile
|
||||
image: ImageField
|
||||
|
||||
|
||||
@invocation_output("calc_tiles_output")
|
||||
class CalcTilesOutput(BaseInvocationOutput):
|
||||
# TODO(ryand): Add description from FieldDescriptions.
|
||||
tiles: list[Tile] = OutputField(description="")
|
||||
@invocation_output("calculate_image_tiles_output")
|
||||
class CalculateImageTilesOutput(BaseInvocationOutput):
|
||||
tiles: list[Tile] = OutputField(description="The tiles coordinates that cover a particular image shape.")
|
||||
|
||||
|
||||
@invocation("calculate_tiles", title="Calculate Tiles", tags=["tiles"], category="tiles", version="1.0.0")
|
||||
class CalcTiles(BaseInvocation):
|
||||
"""TODO(ryand)"""
|
||||
@invocation("calculate_image_tiles", title="Calculate Image Tiles", tags=["tiles"], category="tiles", version="1.0.0")
|
||||
class CalculateImageTiles(BaseInvocation):
|
||||
"""Calculate the coordinates and overlaps of tiles that cover a target image shape."""
|
||||
|
||||
# Inputs
|
||||
image_height: int = InputField(ge=1)
|
||||
image_width: int = InputField(ge=1)
|
||||
tile_height: int = InputField(ge=1, multiple_of=_DIMENSION_MULTIPLE_OF, default=576)
|
||||
tile_width: int = InputField(ge=1, multiple_of=_DIMENSION_MULTIPLE_OF, default=576)
|
||||
overlap: int = InputField(ge=0, multiple_of=_DIMENSION_MULTIPLE_OF, default=64)
|
||||
image_height: int = InputField(
|
||||
ge=1, default=1024, description="The image height, in pixels, to calculate tiles for."
|
||||
)
|
||||
image_width: int = InputField(ge=1, default=1024, description="The image width, in pixels, to calculate tiles for.")
|
||||
tile_height: int = InputField(ge=1, default=576, description="The tile height, in pixels.")
|
||||
tile_width: int = InputField(ge=1, default=576, description="The tile width, in pixels.")
|
||||
overlap: int = InputField(
|
||||
ge=0,
|
||||
default=128,
|
||||
description="The target overlap, in pixels, between adjacent tiles. Adjacent tiles will overlap by at least this amount",
|
||||
)
|
||||
|
||||
def invoke(self, context: InvocationContext) -> CalcTilesOutput:
|
||||
tiles = calc_tiles(
|
||||
def invoke(self, context: InvocationContext) -> CalculateImageTilesOutput:
|
||||
tiles = calc_tiles_with_overlap(
|
||||
image_height=self.image_height,
|
||||
image_width=self.image_width,
|
||||
tile_height=self.tile_height,
|
||||
tile_width=self.tile_width,
|
||||
overlap=self.overlap,
|
||||
)
|
||||
return CalcTilesOutput(tiles=tiles)
|
||||
return CalculateImageTilesOutput(tiles=tiles)
|
||||
|
||||
|
||||
@invocation_output("tile_to_properties_output")
|
||||
class TileToPropertiesOutput(BaseInvocationOutput):
|
||||
# TODO(ryand): Add descriptions.
|
||||
coords_top: int = OutputField(description="")
|
||||
coords_bottom: int = OutputField(description="")
|
||||
coords_left: int = OutputField(description="")
|
||||
coords_right: int = OutputField(description="")
|
||||
coords_top: int = OutputField(description="Top coordinate of the tile relative to its parent image.")
|
||||
coords_bottom: int = OutputField(description="Bottom coordinate of the tile relative to its parent image.")
|
||||
coords_left: int = OutputField(description="Left coordinate of the tile relative to its parent image.")
|
||||
coords_right: int = OutputField(description="Right coordinate of the tile relative to its parent image.")
|
||||
|
||||
overlap_top: int = OutputField(description="")
|
||||
overlap_bottom: int = OutputField(description="")
|
||||
overlap_left: int = OutputField(description="")
|
||||
overlap_right: int = OutputField(description="")
|
||||
overlap_top: int = OutputField(description="Overlap between this tile and its top neighbor.")
|
||||
overlap_bottom: int = OutputField(description="Overlap between this tile and its bottom neighbor.")
|
||||
overlap_left: int = OutputField(description="Overlap between this tile and its left neighbor.")
|
||||
overlap_right: int = OutputField(description="Overlap between this tile and its right neighbor.")
|
||||
|
||||
|
||||
@invocation("tile_to_properties")
|
||||
@invocation("tile_to_properties", title="Tile to Properties", tags=["tiles"], category="tiles", version="1.0.0")
|
||||
class TileToProperties(BaseInvocation):
|
||||
"""Split a Tile into its individual properties."""
|
||||
|
||||
tile: Tile = InputField()
|
||||
tile: Tile = InputField(description="The tile to split into properties.")
|
||||
|
||||
def invoke(self, context: InvocationContext) -> TileToPropertiesOutput:
|
||||
return TileToPropertiesOutput(
|
||||
@ -88,19 +88,20 @@ class TileToProperties(BaseInvocation):
|
||||
)
|
||||
|
||||
|
||||
# HACK(ryand): The only reason that PairTileImage is needed is because the iterate/collect nodes don't preserve order.
|
||||
# Can this be fixed?
|
||||
|
||||
|
||||
@invocation_output("pair_tile_image_output")
|
||||
class PairTileImageOutput(BaseInvocationOutput):
|
||||
tile_with_image: TileWithImage = OutputField(description="")
|
||||
tile_with_image: TileWithImage = OutputField(description="A tile description with its corresponding image.")
|
||||
|
||||
|
||||
@invocation("pair_tile_image", title="Pair Tile with Image", tags=["tiles"], category="tiles", version="1.0.0")
|
||||
class PairTileImage(BaseInvocation):
|
||||
image: ImageField = InputField()
|
||||
tile: Tile = InputField()
|
||||
"""Pair an image with its tile properties."""
|
||||
|
||||
# TODO(ryand): The only reason that PairTileImage is needed is because the iterate/collect nodes don't preserve
|
||||
# order. Can this be fixed?
|
||||
|
||||
image: ImageField = InputField(description="The tile image.")
|
||||
tile: Tile = InputField(description="The tile properties.")
|
||||
|
||||
def invoke(self, context: InvocationContext) -> PairTileImageOutput:
|
||||
return PairTileImageOutput(
|
||||
@ -111,15 +112,18 @@ class PairTileImage(BaseInvocation):
|
||||
)
|
||||
|
||||
|
||||
@invocation("merge_tiles_to_image", title="Merge Tiles To Image", tags=["tiles"], category="tiles", version="1.0.0")
|
||||
@invocation("merge_tiles_to_image", title="Merge Tiles to Image", tags=["tiles"], category="tiles", version="1.0.0")
|
||||
class MergeTilesToImage(BaseInvocation, WithMetadata, WithWorkflow):
|
||||
"""TODO(ryand)"""
|
||||
"""Merge multiple tile images into a single image."""
|
||||
|
||||
# Inputs
|
||||
image_height: int = InputField(ge=1)
|
||||
image_width: int = InputField(ge=1)
|
||||
tiles_with_images: list[TileWithImage] = InputField()
|
||||
blend_amount: int = InputField(ge=0)
|
||||
image_height: int = InputField(ge=1, description="The height of the output image, in pixels.")
|
||||
image_width: int = InputField(ge=1, description="The width of the output image, in pixels.")
|
||||
tiles_with_images: list[TileWithImage] = InputField(description="A list of tile images with tile properties.")
|
||||
blend_amount: int = InputField(
|
||||
ge=0,
|
||||
description="The amount to blend adjacent tiles in pixels. Must be <= the amount of overlap between adjacent tiles.",
|
||||
)
|
||||
|
||||
def invoke(self, context: InvocationContext) -> ImageOutput:
|
||||
images = [twi.image for twi in self.tiles_with_images]
|
||||
|
Loading…
Reference in New Issue
Block a user