o
    iv                     @   s4  d dl mZ d dlZd dlZd dlm  mZ d dl	m
Z
 d dlZd dlmZ d dlmZmZ d dlZd dlZd dlmZ d dlZd dlmZmZ d dlmZ G d	d
 d
ejZdejfdede fdd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&eZ'dej(de)fddZ*dej(de)dej(fddZ+dej(de)dej(fd d!Z,dej(d"e d#e&dej(fd$d%Z-dRdej(d'ed(ed#e&d)e&dej(fd*d+Z.dej(d,ed#e&dej(fd-d.Z/dej(d/ed#e&dej(fd0d1Z0dej(d2e d#e&dej(fd3d4Z1dej(d5ej(d#e&d)e&dej(f
d6d7Z2dej(d8ed#e&dej(fd9d:Z3G d;d< d<ejZ4d=e5ej( dej(dB fd>d?Z6d@e5ej( dej(dB fdAdBZ7dCe5e8e&ej(f  de8e&ej(f dB fdDdEZ9G dFdG dGejZ:G dHdI dIejZ;G dJdK dKejZ<G dLdM dMejZ=G dNdO dOeZ>de>fdPdQZ?dS )S    )overrideN)Image)Enum)	TypedDictLiteral)reshape_latent_to)ComfyExtensionio)MAX_RESOLUTIONc                   @   sX   e Zd Zedd Zedejdejdedede	j
f
dd	Zed
d Zedd ZdS )Blendc                 C   sX   t jddddt jdt jdt jjddd	d
ddt jjdg ddgt j gdS )N
ImageBlendzImage Blendimage/postprocessingImage Toolsimage1image2blend_factor      ?              ?{Gz?defaultminmaxstep
blend_mode)normalmultiplyscreenoverlay
soft_light
differenceoptions)node_iddisplay_namecategoryessentials_categoryinputsoutputs)r	   Schemar   InputFloatComboOutputcls r1   @/mnt/c/Users/fbmor/ComfyUI/comfy_extras/nodes_post_processing.pydefine_schema   s   

zBlend.define_schemar   r   r   r   returnc                 C   s   t ||\}}||j}|j|jkr5|dddd}tjj||jd |jd ddd}|dddd}| 	|||}|d|  ||  }t
|dd}t|S )Nr            bicubiccenter)upscale_methodcrop)node_helpersimage_alpha_fixtodeviceshapepermutecomfyutilscommon_upscaler   torchclampr	   
NodeOutput)r0   r   r   r   r   blended_imager1   r1   r2   execute$   s   "
zBlend.executec              	   C   s   |dkr|S |dkr|| S |dkrdd| d|   S |dkr7t |dkd| | ddd|  d|   S |dkr]t |dk|dd|  | d|   |d| d | ||   S |d	kre|| S td
| )Nr   r   r   r6   r   r   r7   r    r!   zUnsupported blend mode: )rE   whereg
ValueError)r0   img1img2moder1   r1   r2   r   2   s   .DzBlend.blend_modec                 C   s,   t |dkd| d | d | t |S )Ng      ?         )rE   rJ   sqrt)r0   xr1   r1   r2   rK   B   s   ,zBlend.gN)__name__
__module____qualname__classmethodr3   rE   Tensorfloatstrr	   rG   rI   r   rK   r1   r1   r1   r2   r      s    
&
r   kernel_sizesigmac                 C   st   t jt jdd| |dt jdd| |ddd\}}t || ||  }t ||  d| |  }||  |S )Nr6   )r?   ij)indexingg       @)rE   meshgridlinspacerS   expsumr>   )r\   r]   r?   dtyperT   ydrK   r1   r1   r2   gaussian_kernelF   s   0rh   c                	   @   s:   e Zd Zedd Zedejdedede	j
fddZd	S )
Blurc                 C   sN   t jdddt jdt jjddddddt jjd	d
ddddgt j gdS )N	ImageBlurz
Image Blurr   imageblur_radiusr6      r   r]   r   皙?      $@)r$   r%   r&   r(   r)   r	   r*   r   r+   Intr,   r.   r/   r1   r1   r2   r3   M   s   
zBlur.define_schemark   rl   r]   r4   c                 C   s   |dkr	t |S |tj }|j\}}}}|d d }t|||j|j	d
|ddd}	|dddd}t|||||fd}
tj|
|	|d |dd d d d || || f }|dddd}t |tj S )Nr   r7   r6   r?   re   r5   reflectpaddinggroups)r	   rG   r>   rB   model_managementget_torch_devicer@   rh   r?   re   repeat	unsqueezerA   Fpadconv2dintermediate_device)r0   rk   rl   r]   
batch_sizeheightwidthchannelsr\   kernelpadded_imageblurredr1   r1   r2   rI   ]   s   
$6zBlur.executeNrU   rV   rW   rX   r3   rE   rY   intrZ   r	   rG   rI   r1   r1   r1   r2   ri   L   s
    
$ri   c                	   @   sF   e Zd Zedd Zedd Zedejde	de
dejfd	d
ZdS )Quantizec                 C   sJ   t jddt jdt jjddddddt jjdg d	d
gt j gdS )NImageQuantizer   rk   colors   r6   r   dither)nonefloyd-steinbergzbayer-2zbayer-4zbayer-8zbayer-16r"   r$   r&   r(   r)   )r	   r*   r   r+   rq   r-   r.   r/   r1   r1   r2   r3   q   s   
zQuantize.define_schemac                    s
   fdd t | d }d| }tt|}t| | d }tt| 	tj
}t|jd |jd  }t|jd |jd  }	|||	d}
||
d |jd d |jd f dd	 |jtjd
}t|  } | j|tjjd} | S )Nc                    sV   | dkr
t ddS d|  }| | d  }t |d |d f|d |d ff| S )Nr   )r6   r6   float32rR   r6   g      ?r   )npzerosbmat)nqmnormalized_bayer_matrixr1   r2   r      s
   *z/Quantize.bayer.<locals>.normalized_bayer_matrixr5      r   r   r6   r^      re   paletter   )len
getpaletter   mathlog2rE   
from_numpyr   arrayastyper   ceilr@   tilerz   add_clamp_r>   uint8r   	fromarraycpunumpyquantizeDitherNONE)impal_imorder
num_colorsspreadbayer_nbayer_matrixresulttwthtiled_matrixr1   r   r2   bayer   s   .zQuantize.bayerrk   r   r   r4   c                 C   s   |j \}}}}t|}t|D ]]}	tj||	 d tj dd}
|
j	|d}|dkr7|
j	|tj
jd}n#|dkrE|
j	|tj
jd}n|drZt|d	d
 }t|
||}tt|d d }|||	< qt|S )Nr   RGB)rO   )r   r   r   r   r   -r^   )r@   rE   
zeros_likeranger   r   r>   r   r   r   r   r   FLOYDSTEINBERG
startswithr   splitr   r   tensorr   r   convertrZ   r	   rG   )r0   rk   r   r   r   r   r   _r   br   r   quantized_imager   quantized_arrayr1   r1   r2   rI      s   
"


zQuantize.executeN)rU   rV   rW   rX   r3   staticmethodr   rE   rY   r   r[   r	   rG   rI   r1   r1   r1   r2   r   p   s    

$r   c                   @   s>   e Zd Zedd Zedejdededede	j
f
dd	Zd
S )Sharpenc                 C   sf   t jddt jdt jjdddddddt jjd	d
dddddt jjdd
dddddgt j gdS )NImageSharpenr   rk   sharpen_radiusr6   rm   T)r   r   r   r   advancedr]   r   rn   ro   r   alphar   g      @r   rp   r/   r1   r1   r2   r3      s   
zSharpen.define_schemark   r   r]   r   r4   c                 C   s0  |dkr	t |S |j\}}}}|tj }|d d }	t|	||j|j	d|d   }
|
j|j	d}
|	d }|
||f |

  d |
||f< |
|ddd}
|dddd}t|||||fd	}tj||
||d
d d d d || || f }|dddd}t|dd}t |tj S )Nr   r7   r6   rr   
   r   r   r5   rs   rt   )r	   rG   r@   r>   rB   rw   rx   rh   r?   re   rd   ry   rz   rA   r{   r|   r}   rE   rF   r~   )r0   rk   r   r]   r   r   r   r   r   r\   r   r9   tensor_image	sharpenedr   r1   r1   r2   rI      s    
 2zSharpen.executeNr   r1   r1   r1   r2   r      s
    
(r   c                   @   s<   e Zd Zg dZddgZedd ZedejfddZ	d	S )
ImageScaleToTotalPixelsznearest-exactbilineararear8   lanczosdisabledr9   c                 C   s\   t jddt jdt jjd| jdt jjdddd	dd
t jjddddddgt j gdS )Nr   zimage/upscalingrk   r:   r"   
megapixelsr   r         0@r   resolution_stepsr6   r   T)r   r   r   r   r   )	r	   r*   r   r+   r-   upscale_methodsr,   rq   r.   r/   r1   r1   r2   r3      s   
z%ImageScaleToTotalPixels.define_schemar4   c                 C   s   | dd}|d d }t||jd |jd   }t|jd | | | }t|jd | | | }	tj|t|t|	|d}
|
 dd}
t	
|
S )Nr^   r6      r5   r7   r   )movedimr   rS   r@   roundrB   rC   rD   r   r	   rG   )r0   rk   r:   r   r   samplestotalscale_byr   r   sr1   r1   r2   rI      s   
zImageScaleToTotalPixels.executeN)
rU   rV   rW   r   crop_methodsrX   r3   r	   rG   rI   r1   r1   r1   r2   r      s    
r   c                   @   s0   e Zd ZdZdZdZdZdZdZdZ	dZ
d	Zd
S )
ResizeTypezscale by multiplierzscale dimensionszscale longer dimensionzscale shorter dimensionzscale widthzscale heightzscale total pixelsz
match sizezscale to multipleN)rU   rV   rW   SCALE_BYSCALE_DIMENSIONSSCALE_LONGER_DIMENSIONSCALE_SHORTER_DIMENSIONSCALE_WIDTHSCALE_HEIGHTSCALE_TOTAL_PIXELS
MATCH_SIZESCALE_TO_MULTIPLEr1   r1   r1   r2   r      s    r   inputr4   c                 C   s   t | jdkS )NrR   )r   r@   )r   r1   r1   r2   is_image  s   r   is_type_imagec                 C   s"   |r
|  dd} | S | d} | S )Nr^   r6   )r   rz   r   r   r1   r1   r2   init_image_mask_input  
   
r   c                 C   s"   |r
|  dd} | S | d} | S )Nr6   r^   )r   squeezer   r1   r1   r2   finalize_image_mask_input  r   r   
multiplierscale_methodc                 C   sX   t | }t| |} t| jd | }t| jd | }tj| |||d} t| |} | S Nr^   r   )r   r   r   r@   rB   rC   rD   r   )r   r   r   r   r   r   r1   r1   r2   r     s   

r   r   r   r   r;   c                 C   s   |dkr
|dkr
| S t | }t| |} |dkr)tdt| jd | | jd  }n|dkr>tdt| jd | | jd  }tj| ||||} t| |} | S )Nr   r6   r^   r   )	r   r   r   r   r@   rB   rC   rD   r   )r   r   r   r   r;   r   r1   r1   r2   scale_dimensions#  s   
$"
r   longer_sizec                 C   s   t | }t| |} | jd }| jd }||kr"t|| | }|}n||kr1t|| | }|}n|}|}tj| |||d} t| |} | S r   r   r   r@   r   rB   rC   rD   r   )r   r   r   r   r   r   r1   r1   r2   scale_longer_dimension2     



r   shorter_sizec                 C   s   t | }t| |} | jd }| jd }||k r"t|| | }|}n||k r1t|| | }|}n|}|}tj| |||d} t| |} | S r   r   )r   r   r   r   r   r   r1   r1   r2   scale_shorter_dimensionF  r   r   r   c                 C   s   t | }t| |} t|d d }t|| jd | jd   }t| jd | }t| jd | }tj	| |||d} t
| |} | S )Nr   r^   r   r   )r   r   r   r   rS   r@   r   rB   rC   rD   r   )r   r   r   r   r   r   r   r   r1   r1   r2   scale_total_pixelsZ  s   

r  matchc                 C   sV   t | }t| |} t|t |}|jd }|jd }tj| ||||} t| |} | S )Nr^   r   )r   r   r@   rB   rC   rD   r   )r   r  r   r;   r   r   r   r1   r1   r2   scale_match_sizeg  s   



r  multiplec                 C   s`  |dkr| S t | }|r| j\}}}}n| j\}}}|| | }|| | }|dks.|dkr0| S ||kr:||kr:| S || }	|| }
|	|
krX|}tt||	 }||k rW|}n|}tt||
 }||k ri|}t| |} tj| |||d} t	| |} || d }|| d }|| }|| }|r| d d ||||d d f S | d d ||||f S )Nr6   r   r   r7   )
r   r@   r   r   r   r   rB   rC   rD   r   )r   r  r   r   r   r   r   target_wtarget_hs_ws_hscaled_wscaled_hx0y0x1y1r1   r1   r2   scale_to_multiple_coverr  sD   

 r  c                	   @   sh   e Zd Zg dZddgZG dd deZedd Zede	j
je	jjB d	e	jjd
ede	jfddZdS )ResizeImageMaskNoder   r   r9   c                   @   sf   e Zd ZU eed< ed ed< ed ed< eed< eed< eed< eed	< eed
< eed< eed< dS )z#ResizeImageMaskNode.ResizeTypedDictresize_typer   r   )r   r9   r;   r   r   r   r   r   r   r  N)rU   rV   rW   r   __annotations__r   rZ   r   r1   r1   r1   r2   ResizeTypedDict  s   
 r  c                 C   s  t jdt jt jg}t jjd| jddd}t jdddd	g d
t jjd|dt j	jddt j	
tjt jjdddtdddt jjdddtddd|gt j	
tjt jjdddddddgt j	
tjt jjdddtdddgt j	
tjt jjdddtdddgt j	
tjt jjdddtdd dgt j	
tjt jjdddtdd!dgt j	
tjt jjd"ddd#dd$dgt j	
tjt jjd%t jt jgd&d'|gt j	
tjt jjd(d)dtdd*dgg	d+t jjd,| jd-d.dgt jj|d/d0gd1S )2N
input_typer;   r9   zjHow to handle aspect ratio mismatch: 'disabled' stretches to fit, 'center' crops to maintain aspect ratio.)r#   r   tooltipr  zResize Image/Maskz6Resize an image or mask using various scaling methods.	transform)resizezresize imagezresize maskscalezscale imagez
scale maskzimage resizezchange size
dimensionsshrinkenlarger   templater  zUSelect how to resize: by exact dimensions, scale factor, matching another image, etc.r   r   r   r6   z]Target width in pixels. Set to 0 to auto-calculate from height while preserving aspect ratio.)r   r   r   r   r  r   z]Target height in pixels. Set to 0 to auto-calculate from width while preserving aspect ratio.r   r   r   g       @z7Scale factor (e.g., 2.0 doubles size, 0.5 halves size).r   zIThe longer edge will be resized to this value. Aspect ratio is preserved.r   zJThe shorter edge will be resized to this value. Aspect ratio is preserved.zETarget width in pixels. Height auto-adjusts to preserve aspect ratio.zETarget height in pixels. Width auto-adjusts to preserve aspect ratio.r   r   uN   Target total megapixels (e.g., 1.0 ≈ 1024×1024). Aspect ratio is preserved.r  zEResize input to match the dimensions of this reference image or mask.)r  r     zeResize so width and height are divisible by this number. Useful for latent alignment (e.g., 8 or 64).)r  r#   r   r   zpInterpolation algorithm. 'area' is best for downscaling, 'lanczos' for upscaling, 'nearest-exact' for pixel art.resized)r  r%   )r$   r%   descriptionr&   search_aliasesr(   r)   )r	   	MatchTypeTemplater   Maskr-   r+   r   r*   DynamicComboOptionr   r   rq   r
   r   r,   r   r   r   r   r   r   	MultiTyper   scale_methodsr.   )r0   r  
crop_combor1   r1   r2   r3     st   








$-z!ResizeImageMaskNode.define_schemar   r   r  r4   c              	   C   sL  |d }|t jkrtt||d |S |t jkr*tt||d |d ||d S |t jkr:tt||d |S |t j	krJtt
||d |S |t jkr[tt||d d|S |t jkrltt|d|d |S |t jkr|tt||d	 |S |t jkrtt||d
 ||d S |t jkrtt||d |S td| )Nr  r   r   r   r;   r   r   r   r   r  r  zUnsupported resize type: )r   r   r	   rG   r   r   r   r   r   r   r   r   r   r   r  r   r  r   r  rL   )r0   r   r   r  selected_typer1   r1   r2   rI     s(   

"






zResizeImageMaskNode.executeN)rU   rV   rW   r(  r   r   r  rX   r3   r	   r   Typer$  r-   rG   rI   r1   r1   r1   r2   r    s    
>2r  imagesc              
   C   s   t | dkrd S tdd | D }g }| D ]}|jd |k r-|tjjj|dddd q|| qg }|d j}|D ].}|jd	d  |d	d  kre|tj	
|dd	|d
 |d	 ddd	d q<|| q<tj|ddS )Nr   c                 s   s    | ]}|j d  V  qdS )r^   N)r@   ).0rk   r1   r1   r2   	<genexpr>  s    zbatch_images.<locals>.<genexpr>r^   )r   r6   constantr   )rO   valuer6   r7   r   r9   dim)r   r   r@   appendrE   nn
functionalr|   rB   rC   rD   r   cat)r,  max_channelspadded_imagesrk   resized_imagesfirst_image_shaper1   r1   r2   batch_images  s   
4r;  masksc                 C   s   t | dkrd S g }| d j}| D ]2}|jdd  |dd  kr>t|dd}tj||d |d dd}|t|dd q|| qtj	|ddS )	Nr   r6   F)r   r7   r   r9   r1  )
r   r@   r   rB   rC   rD   r3  r   rE   r6  )r<  resized_masksfirst_mask_shapemaskr1   r1   r2   batch_masks  s   
r@  latentsc                 C   s   t | dkrd S | d  }g |d< | d d }g }| D ]'}|t|j|d dd |d |ddd td|d jd D  qtj	|dd|d< |S )	Nr   batch_indexr   F)repeat_batchc                 S   s   g | ]}|qS r1   r1   )r-  rT   r1   r1   r2   
<listcomp>/  s    z!batch_latents.<locals>.<listcomp>r1  )
r   copyr3  r   r@   extendgetr   rE   r6  )rA  samples_outfirst_samplestensorslatentr1   r1   r2   batch_latents$  s   2rL  c                   @   4   e Zd Zedd ZedejjdejfddZ	dS )BatchImagesNodec              
   C   sN   t jjt jddddd}t jddddg dt jjd	|d
gt j gdS )Nrk   r7   2   prefixr   r   rN  zBatch Imagesr   )batchzimage batchzbatch imageszcombine imageszmerge imageszstack imagesr,  r  )r$   r%   r&   r'   r!  r(   r)   )r	   AutogrowTemplatePrefixr   r+   r*   r.   r0   autogrow_templater1   r1   r2   r3   4  s   zBatchImagesNode.define_schemar,  r4   c                 C      t tt| S N)r	   rG   r;  listvalues)r0   r,  r1   r1   r2   rI   E     zBatchImagesNode.executeN
rU   rV   rW   rX   r3   r	   rS  r+  rG   rI   r1   r1   r1   r2   rN  3  s
    
rN  c                   @   rM  )BatchMasksNodec              	   C   L   t jjt jddddd}t jdg dddt jjd|d	gt j gd
S )Nr?  r7   rO  rP  r]  )zcombine maskszstack maskszmerge maskszBatch Masksr<  r  r$   r!  r%   r&   r(   r)   )r	   rS  rT  r$  r+   r*   r.   rU  r1   r1   r2   r3   J     zBatchMasksNode.define_schemar<  r4   c                 C   rW  rX  )r	   rG   r@  rY  rZ  )r0   r<  r1   r1   r2   rI   Z  r[  zBatchMasksNode.executeNr\  r1   r1   r1   r2   r]  I  
    
r]  c                   @   rM  )BatchLatentsNodec              	   C   r^  )NrK  r7   rO  rP  rb  )zcombine latentszstack latentszmerge latentszBatch LatentsrA  r  r_  )r	   rS  rT  Latentr+   r*   r.   rU  r1   r1   r2   r3   _  r`  zBatchLatentsNode.define_schemarA  r4   c                 C   rW  rX  )r	   rG   rL  rY  rZ  )r0   rA  r1   r1   r2   rI   o  r[  zBatchLatentsNode.executeNr\  r1   r1   r1   r2   rb  ^  ra  rb  c                   @   rM  )BatchImagesMasksLatentsNodec              
   C   sp   t jjdt jt jt jgd}t jjt jd|dddd}t j	dg ddd	t jjd
|dgt jj
d |dgdS )Nr   )allowed_typesr6   rO  rP  rd  )zcombine batchzmerge batchzstack inputszBatch Images/Masks/Latentsutilr(   r  )idr  r_  )r	   r"  r#  r   r$  rc  rS  rT  r+   r*   r.   )r0   matchtype_templaterV  r1   r1   r2   r3   t  s   z)BatchImagesMasksLatentsNode.define_schemar(   r4   c                 C   sP   d }t | }t|d trt|}nt|d rt|}nt|}t	|S )Nr   )
rY  rZ  
isinstancedictrL  r   r;  r@  r	   rG   )r0   r(   batchedrZ  r1   r1   r2   rI     s   


z#BatchImagesMasksLatentsNode.executeNr\  r1   r1   r1   r2   rd  s  s
    
rd  c                   @   s(   e Zd Zedeeej  fddZdS )PostProcessingExtensionr4   c              	      s   t ttttttttg	S rX  )	r   ri   r   r   r   r  rN  r]  rb  )selfr1   r1   r2   get_node_list  s   z%PostProcessingExtension.get_node_listN)	rU   rV   rW   r   rY  typer	   	ComfyNodern  r1   r1   r1   r2   rl    s    rl  c                      s   t  S rX  )rl  r1   r1   r1   r2   comfy_entrypoint  s   rq  )r   )@typing_extensionsr   r   r   rE   torch.nn.functionalr4  r5  r{   PILr   r   enumr   typingr   r   comfy.utilsrB   comfy.model_managementcomfy_extras.nodes_latentr   r<   comfy_api.latestr   r	   nodesr
   rp  r   r   r   rZ   rh   ri   r   r   r   r[   r   rY   boolr   r   r   r   r   r   r   r  r  r  r  rY  r;  r@  rj  rL  rN  r]  rb  rd  rl  rq  r1   r1   r1   r2   <module>   sR    5$A)!(
$%f.$