o
    iy                     @  s  d dl mZ d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dl	Z
d dlmZ d dlmZmZmZ d dlmZ ejjZejZG dd dejZG dd	 d	ejZG d
d dejZG dd dejZG dd dejZG dd dejZG dd dejZG dd dejZG dd dejZG dd dejZ G dd dejZ!G dd dejZ"G dd dejZ#G d d! d!ejZ$G d"d# d#ejZ%G d$d% d%ejZ&G d&d' d'ejZ'G d(d) d)eZ(d-d+d,Z)dS ).    )annotationsN)PromptServer)ComfyExtensionIOUI)overridec                   @  *   e Zd Zedd ZedddZeZdS )		ImageCropc                 C  s   t jddgddddt jdt jjdd	d
tjd
dt jjdd	d
tjd
dt jjdddtjd
dt jjdddtjd
dgt j gdS )Nr	   trimzImage Crop (Deprecated)image/transformTImage Toolsimagewidth      defaultminmaxstepheightxr   y)node_idsearch_aliasesdisplay_namecategoryis_deprecatedessentials_categoryinputsoutputs)r   SchemaImageInputIntnodesMAX_RESOLUTIONOutputcls r*   7/mnt/c/Users/fbmor/ComfyUI/comfy_extras/nodes_images.pydefine_schema   s   

zImageCrop.define_schemareturnIO.NodeOutputc           	      C  sb   t ||jd d }t ||jd d }|| }|| }|d d ||||d d f }t|S )N   r   )r   shaper   
NodeOutput)	r)   r   r   r   r   r   to_xto_yimgr*   r*   r+   execute)   s    
zImageCrop.executeNr-   r.   )__name__
__module____qualname__classmethodr,   r5   cropr*   r*   r*   r+   r	      s    
r	   c                   @  &   e Zd Zedd ZedddZdS )	ImageCropV2c                 C  s<   t jddgddddt jdt jjdd	d
gt j gdS )Nr=   r
   z
Image Cropr   r   Tr   crop_regionr	   )	component)r   r   r   r   r   has_intermediate_outputr   r    )r   r!   r"   r#   BoundingBoxr'   r(   r*   r*   r+   r,   6   s   

zImageCropV2.define_schemar-   r.   c           
      C  s   | dd}| dd}| dd}| dd}t||jd d }t||jd d }|| }|| }|d d ||||d d f }	tj|	t|	d	S )
Nr   r   r   r   r   r   r/   r   ui)getr   r0   r   r1   r   PreviewImage)
r)   r   r>   r   r   r   r   r2   r3   r4   r*   r*   r+   r5   F   s    zImageCropV2.executeNr6   r7   r8   r9   r:   r,   r5   r*   r*   r*   r+   r=   5   s
    
r=   c                   @  r<   )	rA   c                 C  sd   t jdddt jjdddtdt jjdddtdt jjdd	d
tdt jjdd	d
tdgt j gdS )NPrimitiveBoundingBoxzBounding Boxzutils/primitiver   r   r   r   r   r   r   r   r   r   )r   r   r   r   r    )r   r!   r$   r#   r&   rA   r'   r(   r*   r*   r+   r,   V   s   
zBoundingBox.define_schemar-   r.   c                 C  s   t ||||dS )N)r   r   r   r   )r   r1   )r)   r   r   r   r   r*   r*   r+   r5   e   s   zBoundingBox.executeNr6   rF   r*   r*   r*   r+   rA   U   s
    
rA   c                   @  r   )	RepeatImageBatchc                 C  s<   t jdddgdt jdt jjddddd	gt j gd
S )NrI   zduplicate imagezclone imageimage/batchr   amountr      rH   r   r   r   r   r    r   r!   r"   r#   r$   r'   r(   r*   r*   r+   r,   k      

zRepeatImageBatch.define_schemar-   r.   c                 C  s   | |dddf}t|S )Nr   )repeatr   r1   )r)   r   rK   sr*   r*   r+   r5   x   s   
zRepeatImageBatch.executeNr6   r7   r8   r9   r:   r,   r5   rP   r*   r*   r*   r+   rI   j   s    
rI   c                   @  r   )	ImageFromBatchc                 C  sN   t jdg ddt jdt jjdddddt jjd	d
d
ddgt j gdS )NrS   )zselect imagezpick from batchzextract imagerJ   r   batch_indexr   i  rH   lengthr   rL   rM   rN   r(   r*   r*   r+   r,      s   

zImageFromBatch.define_schemar-   r.   c                 C  sJ   |}t |jd d |}t |jd | |}||||   }t|S )Nr   r   )r   r0   cloner   r1   )r)   r   rT   rU   s_inrQ   r*   r*   r+   r5      s
   
zImageFromBatch.executeNr6   )r7   r8   r9   r:   r,   r5   	frombatchr*   r*   r*   r+   rS      s    
rS   c                   @  r   )	ImageAddNoisec                 C  sR   t jddgdt jdt jjddddddd	t jjd
dddddgt j gdS )NrY   z
film grainr   seedr   l    Tz,The random seed used for creating the noise.)r   r   r   control_after_generatetooltipstrengthg      ?              ?{Gz?r   rM   )r   r!   r"   r#   r$   Floatr'   r(   r*   r*   r+   r,      s"   

zImageAddNoise.define_schemar-   r.   c                 C  sB   t |}t j||t j| |dd|  ddd}t|S )Ncpu)	generatordevicer^   r_   )r   r   )torchmanual_seedcliprandnsizetor   r1   )r)   r   rZ   r]   rc   rQ   r*   r*   r+   r5      s   
.
zImageAddNoise.executeNr6   rR   r*   r*   r*   r+   rY      s    
rY   c                   @  s8   e Zd ZddddZedd Zeddd	d
ZeZdS )SaveAnimatedWEBP   r      )r   fastestslowestc                 C  s   t jddt jdt jjdddt jjddd	d
d	dt jjdddt jjdddddt jjdt	| j
 dgt jjt jjgddS )Nrk   image/animationimagesfilename_prefixComfyUIr   fps      @r`        @@r   losslessTqualityP   r   d   rH   methodoptionsr   r   r   hiddenis_output_node)r   r!   r"   r#   Stringra   Booleanr$   CombolistCOMPRESS_METHODSkeysHiddenpromptextra_pnginfor(   r*   r*   r+   r,      s   
	zSaveAnimatedWEBP.define_schemar-   r.   c                 C  s*   t jtjj||| |||| j|ddS )N)rq   rr   r)   ru   rx   ry   r|   rB   )r   r1   r   ImageSaveHelperget_save_animated_webp_uir   rD   )r)   rq   ru   rr   rx   ry   r|   
num_framesr*   r*   r+   r5      s   
zSaveAnimatedWEBP.executeN)r   r6   )r7   r8   r9   r   r:   r,   r5   save_imagesr*   r*   r*   r+   rk      s    
rk   c                   @  s,   e Zd Zedd Zed	d
ddZeZdS )SaveAnimatedPNGc                 C  s`   t jddt jdt jjdddt jjddd	d
d	dt jjddddddgt jjt jj	gddS )Nr   rp   rq   rr   rs   rt   ru   rv   r`   rw   r   compress_levelrl   r   	   T)r   r   r   advancedr   )
r   r!   r"   r#   r   ra   r$   r   r   r   r(   r*   r*   r+   r,      s   
zSaveAnimatedPNG.define_schemars   r-   r.   c                 C  s   t jtjj||| ||ddS )N)rq   rr   r)   ru   r   rB   )r   r1   r   r   get_save_animated_png_ui)r)   rq   ru   r   rr   r*   r*   r+   r5      s   zSaveAnimatedPNG.executeN)rs   r6   )r7   r8   r9   r:   r,   r5   r   r*   r*   r*   r+   r      s    
r   c                   @  s2   e Zd ZdZedd Ze	d	d
ddZeZdS )ImageStitchz8Upstreamed from https://github.com/kijai/ComfyUI-KJNodesc                 C  s   t jdg ddddt jdt jjdg dd	d
t jjdddt jjdddddddt jjdg ddddt jjdddgt j gdS )Nr   )zcombine imageszjoin imageszconcatenate imageszside by sidezImage StitchzStitches image2 to image1 in the specified direction.
If image2 is not provided, returns image1 unchanged.
Optional spacing can be added between images.r   image1	direction)rightdownleftupr   )r~   r   match_image_sizeTrt   spacing_widthr      r/   )r   r   r   r   r   spacing_colorwhiteblackredgreenbluer   )r~   r   r   image2)optional)r   r   r   descriptionr   r   r    )r   r!   r"   r#   r   r   r$   r'   r(   r*   r*   r+   r,     s   

zImageStitch.define_schemaNr-   r.   c              	   C  s  |d u r	t |S |jd |jd krXt|jd |jd }|jd |k r;t||dd  ||jd  dddg}|jd |k rXt||dd  ||jd  dddg}|r|jdd \}}	|jdd \}
}||
 }|dv r~|t|| }}n	|	t|	| }}tj	
|dd||dddd}dd	d
ddd}|| }|sl|jdd \}}	|jdd \}
}d	}t|ts|}|dv r||
krt||
}||k r|| }|d ||d  }}tjjj|dddd||fd|d}|
|k r||
 }|d ||d  }}tjjj|dddd||fd|d}nP|	|krlt|	|}|	|k rI||	 }|d ||d  }}tjjj|dd||fd|d}||k rl|| }|d ||d  }}tjjj|dd||fd|d}|jd |jd krt|jd |jd }|jd |k rtj|tjg |jd d ||jd  R d|jigdd}|jd |k rtj|tjg |jd d ||jd  R d|jigdd}|dkrY||d  }|dv r|jd t|jd |jd ||jd f}n|jd |t|jd |jd |jd f}tj|d	|jd}t|tr?t|D ]\}}||jd k r0||d|f< q|jd dkr>d|d< n||dd td|jd f< |jd dkrYd|d< |dv rb||gn||g}|dkrq|d| |dv rxdnd}t tj||dS )Nr   r      )r   r   lanczosdisabledr_   r^   )r_   r^   r^   )r^   r_   r^   )r^   r^   r_   r   r/   constant)modevaluerd   )dim)rd   .rl   ).r   )r   r   )r   r1   r0   r   re   catrP   intcomfyutilscommon_upscalemovedim
isinstancetuplenn
functionalpadonesrd   full	enumerater   insert)r)   r   r   r   r   r   r   	max_batchh1w1h2w2aspect_ratiotarget_htarget_w	color_map	color_val	pad_valuepad_hpad_top
pad_bottompad_wpad_left	pad_rightmax_channelsspacing_shapespacingicrq   
concat_dimr*   r*   r+   r5     s   

$$



"
"






zImageStitch.executeNr6   )r7   r8   r9   __doc__r:   r,   r5   stitchr*   r*   r*   r+   r      s    
 r   c                   @  r   )	ResizeAndPadImagec                 C  s|   t jddgdt jdt jjdddtjddt jjd	ddtjddt jjd
ddgddt jjdg dddgt j gdS )Nr   zfit to sizer   r   target_widthr   r   r   target_heightpadding_colorr   r   T)r~   r   interpolation)areabicubicnearest-exactbilinearr   rM   )	r   r!   r"   r#   r$   r%   r&   r   r'   r(   r*   r*   r+   r,     s   

zResizeAndPadImage.define_schemar-   r.   c                 C  s   |j \}}}}	|| }
|| }t|
|}t|| }t|| }|dddd}tj||||d}|dkr8dnd}tj||	||f||j	|j
d	}|| d }|| d }||d d d d ||| ||| f< |dddd}t|S )
Nr   r   r   r/   r   r   r^   r_   )dtyperd   )r0   r   r   permuter   r   r   re   r   r   rd   r   r1   )r)   r   r   r   r   r   
batch_sizeorig_height
orig_widthchannelsscale_wscale_hscale	new_width
new_heightimage_permutedresizedr   paddedy_offsetx_offsetoutputr*   r*   r+   r5     s(   

(
zResizeAndPadImage.executeNr6   )r7   r8   r9   r:   r,   r5   resize_and_padr*   r*   r*   r+   r     s    
r   c                   @  s,   e Zd Zedd Zedddd	ZeZd
S )SaveSVGNodec                 C  sB   t jdddgddt jdt jjddd	d
gt jjt jjgddS )Nr   zexport vectorzsave vector graphicszSave SVG files on disk.z
image/savesvgrr   svg/ComfyUIzThe prefix for the file to save. This may include formatting information such as %date:yyyy-MM-dd% or %Empty Latent Image.width% to include values from nodes.)r   r\   T)r   r   r   r   r   r   r   )r   r!   SVGr#   r   r   r   r   r(   r*   r*   r+   r,     s   
zSaveSVGNode.define_schemar   r   IO.SVG.Typer-   r.   c              	     s^  t |t  \}}}}}g }i }| jjd ur| jj|d< | jjd ur*|| jj |r3tj|ddnd }	t	|j
D ]l\}
}|dt|
}| d|dd}|d | d	}|	rsd
|	 d  fdd}tjd||tjd}ttj||d}||d	 W d    n1 sw   Y  |tj||tjjd |d7 }q:tjd|idS )Nr   r/   )indentz%batch_num%_05z_.svgr   zutf-8z3  <metadata>
                <![CDATA[
            z9
                ]]>
            </metadata>
            c                   s   |  dd   S )Nr   
)group)matchmetadata_elementr*   r+   replacement  s   z(SaveSVGNode.execute.<locals>.replacementz(<svg[^>]*>))flagswb)filename	subfoldertyper   rq   rB   ) folder_pathsget_save_image_pathget_output_directoryr   r   r   updatejsondumpsr   datareplacestrseekreaddecoderesubUNICODEopenospathjoinwriteencodeappendr   SavedResultr   
FolderTyper   r1   )r)   r   rr   full_output_folderr  counterr  resultsmetadata_dictmetadata_jsonbatch_number	svg_bytesfilename_with_batch_numfilesvg_contentr  svg_filer*   r   r+   r5     s2   

zSaveSVGNode.executeN)r   )r   r   r-   r.   )r7   r8   r9   r:   r,   r5   save_svgr*   r*   r*   r+   r     s    
0r   c                   @  r   )	GetImageSizec                 C  sR   t jdg ddddt jdgt jjddt jjddt jjd	dgt jjgd
S )Nr+  )
dimensions
resolutionz
image infozGet Image SizezGReturns width and height of the image, and passes it through unchanged.r   r   )r   r   r   )r   r   r   r   r   r   r    r   )r   r!   r"   r#   r$   r'   r   	unique_idr(   r*   r*   r+   r,   +  s   
zGetImageSize.define_schemar-   r.   c                 C  sX   |j d }|j d }|j d }| jjr%tjd| d| d| | jj t|||S )Nr   r/   r   zwidth: z
, height: z
 batch size: )r0   r   r.  r   instancesend_progress_textr   r1   )r)   r   r   r   r   r*   r*   r+   r5   >  s   


$zGetImageSize.executeNr6   )r7   r8   r9   r:   r,   r5   get_sizer*   r*   r*   r+   r+  *  s    
r+  c                   @  r   )	ImageRotatec                 C  s@   t jddddgddt jdt jjdg d	d
gt j gdS )Nr2  zImage Rotateturnzflip orientationr   r   r   rotation)nonez
90 degreesz180 degreesz270 degreesr}   )r   r   r   r   r   r   r    r   r!   r"   r#   r   r'   r(   r*   r*   r+   r,   N  s   

zImageRotate.define_schemar-   r.   c                 C  sP   d}| dr
d}n| drd}n| drd}tj||ddgd}t|S )	Nr   90r   180r/   270r   )kdims)
startswithre   rot90r   r1   )r)   r   r4  	rotate_byr*   r*   r+   r5   ]  s   



zImageRotate.executeNr6   )r7   r8   r9   r:   r,   r5   rotater*   r*   r*   r+   r2  M  s    
r2  c                   @  r   )		ImageFlipc              	   C  s<   t jdddgdt jdt jjdddgd	gt j gd
S )Nr@  mirrorreflectr   r   flip_methodzx-axis: verticallyzy-axis: horizontallyr}   rM   r6  r(   r*   r*   r+   r,   n  rO   zImageFlip.define_schemar-   r.   c                 C  s@   | drtj|dgd}n| drtj|dgd}t|S )Nr   r   )r;  r   r/   )r<  re   flipr   r1   )r)   r   rC  r*   r*   r+   r5   {  s
   


zImageFlip.executeNr6   )r7   r8   r9   r:   r,   r5   rD  r*   r*   r*   r+   r@  m  s    
r@  c                   @  r   )	ImageScaleToMaxDimensionc                 C  sJ   t jddt jdt jjdg ddt jjddd	td
dgt j gdS )NrE  zimage/upscalingr   upscale_method)r   r   r   r   r   r   r}   largest_sizer   r   r   r   )r   r   r   r    )r   r!   r"   r#   r   r$   r&   r'   r(   r*   r*   r+   r,     s   

z&ImageScaleToMaxDimension.define_schemar-   r.   c                 C  s   |j d }|j d }||krt|| | }|}n||kr(t|| | }|}n|}|}|dd}tj||||d}|dd}t|S )Nr   r/   r   r   )r0   roundr   r   r   r   r   r1   )r)   r   rF  rG  r   r   samplesrQ   r*   r*   r+   r5     s   


z ImageScaleToMaxDimension.executeNr6   )r7   r8   r9   r:   r,   r5   upscaler*   r*   r*   r+   rE    s    
rE  c                   @  s0   e Zd Zedd Zedd Zedd ZdS )SplitImageToTileListc                 C  sh   t jddg dddt jdt jjddd	td
t jjddd	td
t jjddddd
gt jjddgdS )NrK  rJ   zsplit imagez
tile imagezslice imagezSplit Image into List of TileszFSplits an image into a batched list of tiles with a specified overlap.r   
tile_widthr   @   rH   tile_heightoverlap   r   rL   Tis_output_list)r   r   r   r   r   r   r    )r   r!   r"   r#   r$   r&   r'   r(   r*   r*   r+   r,     s   
z"SplitImageToTileList.define_schemac                 C  s   g }t t|d || }t t|d || }d}||k red}	t|| |}
td|
| }|	| k rVt|	| | }td|| }|||||
f || krNn|	|7 }	|	| k s2|
|kr]	 |S ||7 }||k s|S )Ng      ?r   )rH  r   r   r  )r   r   rM  rO  rP  coordsstride_xstride_yr   r   y_endy_startx_endx_startr*   r*   r+   get_grid_coords  s,   
z$SplitImageToTileList.get_grid_coordsc                 C  sj   |j \}}}}| |||||}	g }
|	D ]\}}}}|d d ||||d d f }|
| qt|
S r   )r0   r[  r  r   r1   )r)   r   rM  rO  rP  bhwr   rT  output_listrZ  rX  rY  rW  tiler*   r*   r+   r5     s    
zSplitImageToTileList.executeN)r7   r8   r9   r:   r,   staticmethodr[  r5   r*   r*   r*   r+   rK    s    

rK  c                   @  s$   e Zd Zedd Zedd ZdS )ImageMergeTileListc                 C  sh   t jdddg ddt jdt jjddd	d
dt jjddd	d
dt jjdddddgt jjddgdS )Nrb  zMerge List of Tiles to ImagerJ   rL  T
image_listfinal_widthr   rN  i   rH   final_heightrP  rQ  r   rL   FrR  )r   r   r   r   is_input_listr   r    rN   r(   r*   r*   r+   r,     s   
z ImageMergeTileList.define_schemac           '   
   C  sZ  |d }|d }|d }d}|d }	|	j \}
}}}|	j}|	j}t|||||}tj|
|||f||d}tj|
||df||d}|dkrttj	tj
dd|||d }ttj	tj
dd|||d }tj|dd}tj|dd}|d|d dd}t|}t|||}ntjd||df||d}t|D ]~\}\}}}}|t|kr no|| }|| }|| }t||j d } t||j d }!||  }"||! }#|d d d | d |!d d f }$|d d d | d |!d d f }%|d d ||"||#d d f  |$|% 7  < |d d ||"||#d d f  |%7  < qd||dk< || }&t|&S )	Nr   r_   )rd   r   r   gh㈵>)r   r   r/   )r0   rd   r   rK  r[  re   zerossinmathpilinspaceclamp	unsqueeze	ones_likelerpr   r   lenr   r   r1   )'r)   rc  rd  re  rP  r^  r]  ovlpfeather_str
first_tiler\  t_ht_wr   rd   r   rT  canvasweightsy_wx_w	sine_mask	flat_maskweight_maskr   rZ  rX  rY  rW  r`  region_hregion_wreal_hreal_wy_end_actualx_end_actual	tile_crop	mask_cropmerged_imager*   r*   r+   r5     sJ      
  ,*
zImageMergeTileList.executeNrF   r*   r*   r*   r+   rb    s
    
rb  c                   @  s   e Zd ZedddZdS )ImagesExtensionr-   list[type[IO.ComfyNode]]c                   s(   t ttttttttt	t
ttttttgS r   )r	   r=   rA   rI   rS   rY   rk   r   r   r   r   r+  r2  r@  rE  rK  rb  )selfr*   r*   r+   get_node_list;  s&   zImagesExtension.get_node_listN)r-   r  )r7   r8   r9   r   r  r*   r*   r*   r+   r  :  s    r  r-   c                     s   t  S r   )r  r*   r*   r*   r+   comfy_entrypointR  s   r  )r-   r  )*
__future__r   r%   r  r  r  r  ri  re   comfy.utilsr   serverr   comfy_api.latestr   r   r   typing_extensionsr   r   Typer&   	ComfyNoder	   r=   rA   rI   rS   rY   rk   r   r   r   r   r+  r2  r@  rE  rK  rb  r  r  r*   r*   r*   r+   <module>   sD      &  13H# )=M