mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2026-05-29 18:37:23 +08:00
Compare commits
5 Commits
4b51c8f774
...
6620c1898b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6620c1898b | ||
|
|
7069f6a92f | ||
|
|
c77b36d98f | ||
|
|
5cca14c798 | ||
|
|
1e8fc2f1a8 |
@ -971,7 +971,7 @@ class SaveImageAdvanced(IO.ComfyNode):
|
||||
advanced=True,
|
||||
),
|
||||
IO.Combo.Input(
|
||||
"interept_as",
|
||||
"interpret_as",
|
||||
options=["sRGB", "Linear", "Raw/Data"],
|
||||
default="sRGB",
|
||||
advanced=True,
|
||||
@ -983,13 +983,13 @@ class SaveImageAdvanced(IO.ComfyNode):
|
||||
[
|
||||
IO.Combo.Input(
|
||||
"bit_depth",
|
||||
options=["8-bit", "10-bit", "12-bit"],
|
||||
options=["8-bit", "10-bit"],
|
||||
default="8-bit",
|
||||
advanced=True,
|
||||
),
|
||||
IO.Combo.Input(
|
||||
"interept_as",
|
||||
options=["sRGB", "Raw/Data"],
|
||||
"interpret_as",
|
||||
options=["sRGB", "Linear", "Raw/Data"],
|
||||
default="sRGB",
|
||||
advanced=True,
|
||||
),
|
||||
@ -1000,13 +1000,13 @@ class SaveImageAdvanced(IO.ComfyNode):
|
||||
[
|
||||
IO.Combo.Input(
|
||||
"bit_depth",
|
||||
options=["16-bit", "32-bit"],
|
||||
default="16-bit",
|
||||
options=["32-bit"],
|
||||
default="32-bit",
|
||||
advanced=True,
|
||||
),
|
||||
IO.Combo.Input(
|
||||
"interept_as",
|
||||
options=["Linear", "Raw/Data"],
|
||||
"interpret_as",
|
||||
options=["sRGB", "Linear", "Raw/Data"],
|
||||
default="Linear",
|
||||
advanced=True,
|
||||
),
|
||||
@ -1032,7 +1032,7 @@ class SaveImageAdvanced(IO.ComfyNode):
|
||||
# get widget values from dynamic combo
|
||||
file_format = format["format"]
|
||||
bit_depth = format["bit_depth"]
|
||||
interept_as = format["interept_as"]
|
||||
interpret_as = format["interpret_as"]
|
||||
|
||||
img_tensor = image.clone()
|
||||
|
||||
@ -1042,22 +1042,18 @@ class SaveImageAdvanced(IO.ComfyNode):
|
||||
# file pathing
|
||||
filename_with_batch_num = filename.replace("%batch_num%", str(batch_number))
|
||||
|
||||
file = f"{filename_with_batch_num}_{counter:05}.{file_format}"
|
||||
file = f"{filename_with_batch_num}_{counter:05}_.{file_format}"
|
||||
file_path = os.path.join(full_output_folder, file)
|
||||
|
||||
if file_format in ["png", "exr", "avif"]:
|
||||
|
||||
if bit_depth == "32-bit":
|
||||
img_np = img_tensor.cpu().numpy().astype(np.float32)
|
||||
img_np = img_np[:, :, [1, 2, 0, 3]] if has_alpha else img_np[:, :,[1, 2, 0]]
|
||||
av_fmt = 'gbrapf32le' if has_alpha else 'gbrpf32le'
|
||||
elif bit_depth == "16-bit":
|
||||
if file_format == "exr":
|
||||
# default pyav build doesn't come with a codec for float16 exr format
|
||||
img_np = img_tensor.cpu().numpy().astype(np.float32)
|
||||
av_fmt = 'gbrapf32le' if has_alpha else 'gbrpf32le'
|
||||
else:
|
||||
img_np = (img_tensor * 65535.0).clamp(0, 65535).to(torch.int32).cpu().numpy().astype(np.uint16)
|
||||
av_fmt = 'rgba64le' if has_alpha else 'rgb48le'
|
||||
elif bit_depth in ["10-bit", "12-bit", "16-bit"]:
|
||||
img_np = (img_tensor * 65535.0).clamp(0, 65535).to(torch.int32).cpu().numpy().astype(np.uint16)
|
||||
av_fmt = 'rgba64le' if has_alpha else 'rgb48le'
|
||||
else:
|
||||
img_np = (img_tensor * 255.0).clamp(0, 255).to(torch.int32).cpu().numpy().astype(np.uint8)
|
||||
av_fmt = 'rgba' if has_alpha else 'rgb24'
|
||||
@ -1079,15 +1075,26 @@ class SaveImageAdvanced(IO.ComfyNode):
|
||||
|
||||
stream.time_base = Fraction(1, 1)
|
||||
|
||||
if bit_depth in ["16-bit", "32-bit"]:
|
||||
if bit_depth == "12-bit":
|
||||
stream.pix_fmt = 'yuv420p12le'
|
||||
elif bit_depth in ["10-bit", "16-bit", "32-bit"]:
|
||||
stream.pix_fmt = 'yuv420p10le'
|
||||
else:
|
||||
stream.pix_fmt = 'yuv420p'
|
||||
|
||||
stream.codec_context.color_range = 2
|
||||
stream.codec_context.colorspace = 1
|
||||
stream.codec_context.color_primaries = 1
|
||||
stream.codec_context.color_trc = 1
|
||||
if interpret_as == "Raw/Data": # 2 == unspecified
|
||||
stream.codec_context.colorspace = 2
|
||||
stream.codec_context.color_primaries = 2
|
||||
stream.codec_context.color_trc = 2
|
||||
elif interpret_as == "Linear":
|
||||
stream.codec_context.colorspace = 1
|
||||
stream.codec_context.color_primaries = 1
|
||||
stream.codec_context.color_trc = 8
|
||||
else: # sRGB
|
||||
stream.codec_context.colorspace = 1
|
||||
stream.codec_context.color_primaries = 1
|
||||
stream.codec_context.color_trc = 13
|
||||
|
||||
stream.options = {
|
||||
'preset': '10',
|
||||
@ -1106,12 +1113,6 @@ class SaveImageAdvanced(IO.ComfyNode):
|
||||
stream.height = height
|
||||
stream.time_base = Fraction(1, 1)
|
||||
|
||||
is_planar = av_fmt.startswith('gbrp') or 'p' in av_fmt.split('rgba')[-1]
|
||||
if is_planar:
|
||||
if av_fmt.startswith('gbrp'):
|
||||
img_np = img_np[:, :, [1, 2, 0, 3]] if has_alpha else img_np[:, :, [1, 2, 0]]
|
||||
img_np = img_np.transpose(2, 0, 1)
|
||||
|
||||
try:
|
||||
frame = av.VideoFrame.from_ndarray(img_np, format=av_fmt)
|
||||
except ValueError:
|
||||
@ -1133,7 +1134,7 @@ class SaveImageAdvanced(IO.ComfyNode):
|
||||
frame.time_base = stream.time_base
|
||||
if file_format == "avif":
|
||||
frame.color_range = 2
|
||||
frame.colorspace = 1
|
||||
frame.colorspace = stream.codec_context.colorspace
|
||||
|
||||
for packet in stream.encode(frame):
|
||||
container.mux(packet)
|
||||
@ -1188,7 +1189,6 @@ class ImagesExtension(ComfyExtension):
|
||||
ImageScaleToMaxDimension,
|
||||
SplitImageToTileList,
|
||||
ImageMergeTileList,
|
||||
SaveImageAdvanced
|
||||
]
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user