feat: Implement upscale functionality with ONNX models

- Added upscale operator to handle image upscaling by 4x using AI models.
- Introduced new jobs for upscale processing in the server, including debug and standard upscale jobs.
- Created a new ONNX model handler for upscale operations, supporting tiled inference and resource management.
- Updated tests to cover new upscale functionality, including input validation and output verification.
- Added documentation for the upscale feature, detailing usage and model options.
This commit is contained in:
2026-08-23 20:34:35 +08:00
parent 1613bd3194
commit 0cf04a13c6
66 changed files with 2156 additions and 1088 deletions

View File

@@ -30,10 +30,12 @@ from .common import (
draw_dashed_line,
draw_image_mask_operator_settings,
draw_polygon_fill,
ImageEditWarning,
image_edit_poll,
image_mask_refine_request,
polygon_bounds,
replace_empty_image_pixels,
report_image_edit_exception,
resolve_image_edit_click,
)
@@ -141,7 +143,6 @@ def edit_image_object(source_object, selection_mask, invert=False):
pixels,
(right - left, bottom - top),
crop_bounds,
suffix=".mask",
)
@@ -389,7 +390,8 @@ class EditImageMask(bpy.types.Operator):
else:
path = self._screen_polygon()
if len(path) < 3:
raise ValueError("Draw a larger image region")
self._finish(context)
return {"CANCELLED"}
polygon = screen_path_to_image_pixels(
path,
context.region,
@@ -444,7 +446,7 @@ class EditImageMask(bpy.types.Operator):
try:
return self._complete(context)
except (RuntimeError, TypeError, ValueError) as error:
self.report({"ERROR"}, str(error))
report_image_edit_exception(self, error)
self._finish(context)
return {"CANCELLED"}
return {"PASS_THROUGH"}
@@ -482,7 +484,7 @@ class EditImageMask(bpy.types.Operator):
try:
return self._complete(context)
except (RuntimeError, TypeError, ValueError) as error:
self.report({"ERROR"}, str(error))
report_image_edit_exception(self, error)
self._finish(context)
return {"CANCELLED"}
@@ -518,7 +520,7 @@ class EditImageMask(bpy.types.Operator):
self.invert,
)
except (json.JSONDecodeError, RuntimeError, TypeError, ValueError) as error:
self.report({"ERROR"}, str(error))
report_image_edit_exception(self, error)
return {"CANCELLED"}
return {"FINISHED"}
@@ -559,7 +561,11 @@ class RefineImageMask(JobOperatorBase, bpy.types.Operator):
)
finally:
bpy.data.images.remove(refined_image, do_unlink=True)
edit_image_object(source_object, mask, self.invert)
try:
edit_image_object(source_object, mask, self.invert)
except ImageEditWarning as error:
self.report({"WARNING"}, str(error))
return str(error)
push_undo("Edit Image Mask")
return "Image selection refined"