1212upscale_cache = {}
1313
1414
15+ def limitSizeByOneDemention (size : tuple , limit : int ):
16+ w , h = size
17+ if h > w :
18+ if h > limit :
19+ w = limit / h * w
20+ h = limit
21+ else :
22+ if w > limit :
23+ h = limit / w * h
24+ w = limit
25+ return (int (w ), int (h ))
26+
27+
1528class ScriptPostprocessingUpscale (scripts_postprocessing .ScriptPostprocessing ):
1629 name = "Upscale"
1730 order = 1000
@@ -31,6 +44,11 @@ def ui(self):
3144 with gr .Tabs (elem_id = "extras_resize_mode" ):
3245 with gr .TabItem ('Scale by' , elem_id = "extras_scale_by_tab" ) as tab_scale_by :
3346 upscaling_resize = gr .Slider (minimum = 1.0 , maximum = 8.0 , step = 0.05 , label = "Resize" , value = 4 , elem_id = "extras_upscaling_resize" )
47+ if shared .opts .show_limit_target_resolution_in_extras_upscale :
48+ limit_target_resolution = gr .Slider (minimum = 0 , maximum = 10000 , step = 8 , label = "Limit target resolution" , value = 8000 , elem_id = "extras_upscale_limit_target_resolution" ,
49+ tooltip = "0 = no limit. Limit maximal target resolution by the biggest demension. Useful for batches where can be big images." )
50+ else :
51+ limit_target_resolution = gr .Number (0 , visible = False )
3452
3553 with gr .TabItem ('Scale to' , elem_id = "extras_scale_to_tab" ) as tab_scale_to :
3654 with FormRow ():
@@ -61,6 +79,7 @@ def on_selected_upscale_method(upscale_method):
6179 "upscale_enabled" : upscale_enabled ,
6280 "upscale_mode" : selected_tab ,
6381 "upscale_by" : upscaling_resize ,
82+ "limit_target_resolution" : limit_target_resolution ,
6483 "upscale_to_width" : upscaling_resize_w ,
6584 "upscale_to_height" : upscaling_resize_h ,
6685 "upscale_crop" : upscaling_crop ,
@@ -69,12 +88,18 @@ def on_selected_upscale_method(upscale_method):
6988 "upscaler_2_visibility" : extras_upscaler_2_visibility ,
7089 }
7190
72- def upscale (self , image , info , upscaler , upscale_mode , upscale_by , upscale_to_width , upscale_to_height , upscale_crop ):
91+ def upscale (self , image , info , upscaler , upscale_mode , upscale_by , limit_target_resolution , upscale_to_width , upscale_to_height , upscale_crop ):
7392 if upscale_mode == 1 :
7493 upscale_by = max (upscale_to_width / image .width , upscale_to_height / image .height )
7594 info ["Postprocess upscale to" ] = f"{ upscale_to_width } x{ upscale_to_height } "
7695 else :
7796 info ["Postprocess upscale by" ] = upscale_by
97+ if limit_target_resolution != 0 and max (* image .size )* upscale_by > limit_target_resolution :
98+ upscale_mode = 1
99+ upscale_crop = False
100+ upscale_to_width , upscale_to_height = limitSizeByOneDemention ((image .width * upscale_by , image .height * upscale_by ), limit_target_resolution )
101+ upscale_by = max (upscale_to_width / image .width , upscale_to_height / image .height )
102+ info ["Limit target resolution" ] = limit_target_resolution
78103
79104 cache_key = (hash (np .array (image .getdata ()).tobytes ()), upscaler .name , upscale_mode , upscale_by , upscale_to_width , upscale_to_height , upscale_crop )
80105 cached_image = upscale_cache .pop (cache_key , None )
@@ -96,18 +121,21 @@ def upscale(self, image, info, upscaler, upscale_mode, upscale_by, upscale_to_w
96121
97122 return image
98123
99- def process_firstpass (self , pp : scripts_postprocessing .PostprocessedImage , upscale_enabled = True , upscale_mode = 1 , upscale_by = 2.0 , upscale_to_width = None , upscale_to_height = None , upscale_crop = False , upscaler_1_name = None , upscaler_2_name = None , upscaler_2_visibility = 0.0 ):
100- if upscale_mode == 1 :
101- pp .shared .target_width = upscale_to_width
102- pp .shared .target_height = upscale_to_height
124+ def process_firstpass (self , pp : scripts_postprocessing .PostprocessedImage , ** args ):
125+ if args [ ' upscale_mode' ] == 1 :
126+ pp .shared .target_width = args [ ' upscale_to_width' ]
127+ pp .shared .target_height = args [ ' upscale_to_height' ]
103128 else :
104- pp .shared .target_width = int (pp .image .width * upscale_by )
105- pp .shared .target_height = int (pp .image .height * upscale_by )
129+ pp .shared .target_width = int (pp .image .width * args ['upscale_by' ])
130+ pp .shared .target_height = int (pp .image .height * args ['upscale_by' ])
131+ if args ['limit_target_resolution' ] != 0 :
132+ pp .shared .target_width , pp .shared .target_height = limitSizeByOneDemention ((pp .shared .target_width , pp .shared .target_height ), args ['limit_target_resolution' ])
106133
107- def process (self , pp : scripts_postprocessing .PostprocessedImage , upscale_enabled = True , upscale_mode = 1 , upscale_by = 2.0 , upscale_to_width = None , upscale_to_height = None , upscale_crop = False , upscaler_1_name = None , upscaler_2_name = None , upscaler_2_visibility = 0.0 ):
108- if not upscale_enabled :
134+ def process (self , pp : scripts_postprocessing .PostprocessedImage , ** args ):
135+ if not args [ ' upscale_enabled' ] :
109136 return
110137
138+ upscaler_1_name = args ['upscaler_1_name' ]
111139 if upscaler_1_name == "None" :
112140 upscaler_1_name = None
113141
@@ -117,18 +145,21 @@ def process(self, pp: scripts_postprocessing.PostprocessedImage, upscale_enabled
117145 if not upscaler1 :
118146 return
119147
148+ upscaler_2_name = args ['upscaler_2_name' ]
120149 if upscaler_2_name == "None" :
121150 upscaler_2_name = None
122151
123152 upscaler2 = next (iter ([x for x in shared .sd_upscalers if x .name == upscaler_2_name and x .name != "None" ]), None )
124153 assert upscaler2 or (upscaler_2_name is None ), f'could not find upscaler named { upscaler_2_name } '
125154
126- upscaled_image = self .upscale (pp .image , pp .info , upscaler1 , upscale_mode , upscale_by , upscale_to_width , upscale_to_height , upscale_crop )
155+ upscaled_image = self .upscale (pp .image , pp .info , upscaler1 , args ['upscale_mode' ], args ['upscale_by' ], args ['limit_target_resolution' ], args ['upscale_to_width' ],
156+ args ['upscale_to_height' ], args ['upscale_crop' ])
127157 pp .info ["Postprocess upscaler" ] = upscaler1 .name
128158
129- if upscaler2 and upscaler_2_visibility > 0 :
130- second_upscale = self .upscale (pp .image , pp .info , upscaler2 , upscale_mode , upscale_by , upscale_to_width , upscale_to_height , upscale_crop )
131- upscaled_image = Image .blend (upscaled_image , second_upscale , upscaler_2_visibility )
159+ if upscaler2 and args ['upscaler_2_visibility' ] > 0 :
160+ second_upscale = self .upscale (pp .image , pp .info , upscaler2 , args ['upscale_mode' ], args ['upscale_by' ], args ['upscale_to_width' ],
161+ args ['upscale_to_height' ], args ['upscale_crop' ])
162+ upscaled_image = Image .blend (upscaled_image , second_upscale , args ['upscaler_2_visibility' ])
132163
133164 pp .info ["Postprocess upscaler 2" ] = upscaler2 .name
134165
@@ -163,5 +194,5 @@ def process(self, pp: scripts_postprocessing.PostprocessedImage, upscale_by=2.0,
163194 upscaler1 = next (iter ([x for x in shared .sd_upscalers if x .name == upscaler_name ]), None )
164195 assert upscaler1 , f'could not find upscaler named { upscaler_name } '
165196
166- pp .image = self .upscale (pp .image , pp .info , upscaler1 , 0 , upscale_by , 0 , 0 , False )
197+ pp .image = self .upscale (pp .image , pp .info , upscaler1 , 0 , upscale_by , 0 , 0 , 0 , False )
167198 pp .info ["Postprocess upscaler" ] = upscaler1 .name
0 commit comments