3030 validate_image_dimensions ,
3131)
3232
33+ _EUR_TO_USD = 1.19
34+
35+
36+ def _tier_price_eur (megapixels : float ) -> float :
37+ """Price in EUR for a single Magnific upscaling step based on input megapixels."""
38+ if megapixels <= 1.3 :
39+ return 0.143
40+ if megapixels <= 3.0 :
41+ return 0.286
42+ if megapixels <= 6.4 :
43+ return 0.429
44+ return 1.716
45+
46+
47+ def _calculate_magnific_upscale_price_usd (width : int , height : int , scale : int ) -> float :
48+ """Calculate total Magnific upscale price in USD for given input dimensions and scale factor."""
49+ num_steps = int (math .log2 (scale ))
50+ total_eur = 0.0
51+ pixels = width * height
52+ for _ in range (num_steps ):
53+ total_eur += _tier_price_eur (pixels / 1_000_000 )
54+ pixels *= 4
55+ return round (total_eur * _EUR_TO_USD , 2 )
56+
3357
3458class MagnificImageUpscalerCreativeNode (IO .ComfyNode ):
3559 @classmethod
@@ -103,11 +127,20 @@ def define_schema(cls):
103127 ],
104128 is_api_node = True ,
105129 price_badge = IO .PriceBadge (
106- depends_on = IO .PriceBadgeDepends (widgets = ["scale_factor" ]),
130+ depends_on = IO .PriceBadgeDepends (widgets = ["scale_factor" , "auto_downscale" ]),
107131 expr = """
108132 (
109- $max := widgets.scale_factor = "2x" ? 1.326 : 1.657;
110- {"type": "range_usd", "min_usd": 0.11, "max_usd": $max}
133+ $ad := widgets.auto_downscale;
134+ $mins := $ad
135+ ? {"2x": 0.172, "4x": 0.343, "8x": 0.515, "16x": 0.515}
136+ : {"2x": 0.172, "4x": 0.343, "8x": 0.515, "16x": 0.844};
137+ $maxs := {"2x": 0.515, "4x": 0.844, "8x": 1.015, "16x": 1.187};
138+ {
139+ "type": "range_usd",
140+ "min_usd": $lookup($mins, widgets.scale_factor),
141+ "max_usd": $lookup($maxs, widgets.scale_factor),
142+ "format": { "approximate": true }
143+ }
111144 )
112145 """ ,
113146 ),
@@ -168,6 +201,10 @@ async def execute(
168201 f"Use a smaller input image or lower scale factor."
169202 )
170203
204+ final_height , final_width = get_image_dimensions (image )
205+ actual_scale = int (scale_factor .rstrip ("x" ))
206+ price_usd = _calculate_magnific_upscale_price_usd (final_width , final_height , actual_scale )
207+
171208 initial_res = await sync_op (
172209 cls ,
173210 ApiEndpoint (path = "/proxy/freepik/v1/ai/image-upscaler" , method = "POST" ),
@@ -189,6 +226,7 @@ async def execute(
189226 ApiEndpoint (path = f"/proxy/freepik/v1/ai/image-upscaler/{ initial_res .task_id } " ),
190227 response_model = TaskResponse ,
191228 status_extractor = lambda x : x .status ,
229+ price_extractor = lambda _ : price_usd ,
192230 poll_interval = 10.0 ,
193231 max_poll_attempts = 480 ,
194232 )
@@ -257,8 +295,14 @@ def define_schema(cls):
257295 depends_on = IO .PriceBadgeDepends (widgets = ["scale_factor" ]),
258296 expr = """
259297 (
260- $max := widgets.scale_factor = "2x" ? 1.326 : 1.657;
261- {"type": "range_usd", "min_usd": 0.11, "max_usd": $max}
298+ $mins := {"2x": 0.172, "4x": 0.343, "8x": 0.515, "16x": 0.844};
299+ $maxs := {"2x": 2.045, "4x": 2.545, "8x": 2.889, "16x": 3.06};
300+ {
301+ "type": "range_usd",
302+ "min_usd": $lookup($mins, widgets.scale_factor),
303+ "max_usd": $lookup($maxs, widgets.scale_factor),
304+ "format": { "approximate": true }
305+ }
262306 )
263307 """ ,
264308 ),
@@ -321,6 +365,9 @@ async def execute(
321365 f"Use a smaller input image or lower scale factor."
322366 )
323367
368+ final_height , final_width = get_image_dimensions (image )
369+ price_usd = _calculate_magnific_upscale_price_usd (final_width , final_height , requested_scale )
370+
324371 initial_res = await sync_op (
325372 cls ,
326373 ApiEndpoint (path = "/proxy/freepik/v1/ai/image-upscaler-precision-v2" , method = "POST" ),
@@ -339,6 +386,7 @@ async def execute(
339386 ApiEndpoint (path = f"/proxy/freepik/v1/ai/image-upscaler-precision-v2/{ initial_res .task_id } " ),
340387 response_model = TaskResponse ,
341388 status_extractor = lambda x : x .status ,
389+ price_extractor = lambda _ : price_usd ,
342390 poll_interval = 10.0 ,
343391 max_poll_attempts = 480 ,
344392 )
@@ -877,8 +925,8 @@ class MagnificExtension(ComfyExtension):
877925 @override
878926 async def get_node_list (self ) -> list [type [IO .ComfyNode ]]:
879927 return [
880- # MagnificImageUpscalerCreativeNode,
881- # MagnificImageUpscalerPreciseV2Node,
928+ MagnificImageUpscalerCreativeNode ,
929+ MagnificImageUpscalerPreciseV2Node ,
882930 MagnificImageStyleTransferNode ,
883931 MagnificImageRelightNode ,
884932 MagnificImageSkinEnhancerNode ,
0 commit comments