3131)
3232
3333
34+ _EUR_TO_USD = 1.19
35+
36+
37+ def _tier_price_eur (megapixels : float ) -> float :
38+ """Price in EUR for a single Magnific upscaling step based on input megapixels."""
39+ if megapixels <= 1.3 :
40+ return 0.10
41+ if megapixels <= 3.0 :
42+ return 0.20
43+ if megapixels <= 6.4 :
44+ return 0.30
45+ return 1.20
46+
47+
48+ def _calculate_magnific_upscale_price_usd (width : int , height : int , scale : int ) -> float :
49+ """Calculate total Magnific upscale price in USD for given input dimensions and scale factor."""
50+ num_steps = int (math .log2 (scale ))
51+ total_eur = 0.0
52+ pixels = width * height
53+ for _ in range (num_steps ):
54+ total_eur += _tier_price_eur (pixels / 1_000_000 )
55+ pixels *= 4
56+ return round (total_eur * _EUR_TO_USD , 2 )
57+
58+
3459class MagnificImageUpscalerCreativeNode (IO .ComfyNode ):
3560 @classmethod
3661 def define_schema (cls ):
@@ -103,11 +128,20 @@ def define_schema(cls):
103128 ],
104129 is_api_node = True ,
105130 price_badge = IO .PriceBadge (
106- depends_on = IO .PriceBadgeDepends (widgets = ["scale_factor" ]),
131+ depends_on = IO .PriceBadgeDepends (widgets = ["scale_factor" , "auto_downscale" ]),
107132 expr = """
108133 (
109- $max := widgets.scale_factor = "2x" ? 1.326 : 1.657;
110- {"type": "range_usd", "min_usd": 0.11, "max_usd": $max}
134+ $ad := widgets.auto_downscale;
135+ $mins := $ad
136+ ? {"2x": 0.12, "4x": 0.24, "8x": 0.36, "16x": 0.36}
137+ : {"2x": 0.12, "4x": 0.24, "8x": 0.36, "16x": 0.59};
138+ $maxs := {"2x": 0.36, "4x": 0.59, "8x": 0.71, "16x": 0.83};
139+ {
140+ "type": "range_usd",
141+ "min_usd": $lookup($mins, widgets.scale_factor),
142+ "max_usd": $lookup($maxs, widgets.scale_factor),
143+ "format": { "approximate": true }
144+ }
111145 )
112146 """ ,
113147 ),
@@ -168,6 +202,10 @@ async def execute(
168202 f"Use a smaller input image or lower scale factor."
169203 )
170204
205+ final_height , final_width = get_image_dimensions (image )
206+ actual_scale = int (scale_factor .rstrip ("x" ))
207+ price_usd = _calculate_magnific_upscale_price_usd (final_width , final_height , actual_scale )
208+
171209 initial_res = await sync_op (
172210 cls ,
173211 ApiEndpoint (path = "/proxy/freepik/v1/ai/image-upscaler" , method = "POST" ),
@@ -189,6 +227,7 @@ async def execute(
189227 ApiEndpoint (path = f"/proxy/freepik/v1/ai/image-upscaler/{ initial_res .task_id } " ),
190228 response_model = TaskResponse ,
191229 status_extractor = lambda x : x .status ,
230+ price_extractor = lambda _ : price_usd ,
192231 poll_interval = 10.0 ,
193232 max_poll_attempts = 480 ,
194233 )
@@ -257,8 +296,14 @@ def define_schema(cls):
257296 depends_on = IO .PriceBadgeDepends (widgets = ["scale_factor" ]),
258297 expr = """
259298 (
260- $max := widgets.scale_factor = "2x" ? 1.326 : 1.657;
261- {"type": "range_usd", "min_usd": 0.11, "max_usd": $max}
299+ $mins := {"2x": 0.12, "4x": 0.24, "8x": 0.36, "16x": 0.59};
300+ $maxs := {"2x": 1.43, "4x": 1.78, "8x": 2.02, "16x": 2.14};
301+ {
302+ "type": "range_usd",
303+ "min_usd": $lookup($mins, widgets.scale_factor),
304+ "max_usd": $lookup($maxs, widgets.scale_factor),
305+ "format": { "approximate": true }
306+ }
262307 )
263308 """ ,
264309 ),
@@ -321,6 +366,9 @@ async def execute(
321366 f"Use a smaller input image or lower scale factor."
322367 )
323368
369+ final_height , final_width = get_image_dimensions (image )
370+ price_usd = _calculate_magnific_upscale_price_usd (final_width , final_height , requested_scale )
371+
324372 initial_res = await sync_op (
325373 cls ,
326374 ApiEndpoint (path = "/proxy/freepik/v1/ai/image-upscaler-precision-v2" , method = "POST" ),
@@ -339,6 +387,7 @@ async def execute(
339387 ApiEndpoint (path = f"/proxy/freepik/v1/ai/image-upscaler-precision-v2/{ initial_res .task_id } " ),
340388 response_model = TaskResponse ,
341389 status_extractor = lambda x : x .status ,
390+ price_extractor = lambda _ : price_usd ,
342391 poll_interval = 10.0 ,
343392 max_poll_attempts = 480 ,
344393 )
0 commit comments