o
    iG                     @  st  d dl m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Zd dl	Z
d dlZzd dlZdZW n   dZY d dlmZ d dlmZ d dlZd dlmZ d	d
lmZmZmZmZ G dd deZG dd deZG dd deZd(ddZG dd dZG dd dZ G dd deZ!G dd de!Z"G dd  d eZ#G d!d" d"eZ$G d#d$ d$eZ%G d%d& d&eZ&g d'Z'dS ))    )annotationsN)BytesIOTF)Image)PngInfo)args   )	ComfyNode
FolderTyper   	_UIOutputc                      sH   e Zd Zd fddZedd	d
ZedddZedddZ  ZS )SavedResultfilenamestr	subfoldertyper	   c                   s   t  j|||jd d S )N)r   r   r   )super__init__value)selfr   r   r   	__class__ 2/mnt/c/Users/fbmor/ComfyUI/comfy_api/latest/_ui.pyr      s   zSavedResult.__init__returnc                 C     | d S )Nr   r   r   r   r   r   r         zSavedResult.filenamec                 C  r   )Nr   r   r   r   r   r   r   #   r   zSavedResult.subfolderc                 C  s   t | d S )Nr   )r	   r   r   r   r   r   '   s   zSavedResult.type)r   r   r   r   r   r	   )r   r   )r   r	   )	__name__
__module____qualname__r   propertyr   r   r   __classcell__r   r   r   r   r      s    r   c                      s.   e Zd ZdZdd fddZdddZ  ZS )SavedImageszNA UI output class to represent one or more saved images, potentially animated.Fresultslist[SavedResult]is_animatedboolc                   s   t    || _|| _d S N)r   r   r"   r$   )r   r"   r$   r   r   r   r   .   s   

zSavedImages.__init__r   dictc                 C  s   d| j i}| jrd|d< |S )NimagesTanimated)r"   r$   )r   datar   r   r   as_dict3   s   
zSavedImages.as_dict)F)r"   r#   r$   r%   r   r'   r   r   r   __doc__r   r,   r    r   r   r   r   r!   ,   s    r!   c                      s,   e Zd ZdZd
 fddZddd	Z  ZS )SavedAudioszFUI wrapper around one or more audio files on disk (FLAC / MP3 / Opus).r"   r#   c                   s   t    || _d S r&   )r   r   r"   )r   r"   r   r   r   r   <   s   

zSavedAudios.__init__r   r'   c                 C  
   d| j iS Naudio)r"   r   r   r   r   r,   @      
zSavedAudios.as_dict)r"   r#   r-   r.   r   r   r   r   r0   :   s    r0   folder_typer	   r   r   c                 C  s,   | t jkr	t S | t jkrt S t S r&   )r	   inputfolder_pathsget_input_directoryoutputget_output_directoryget_temp_directory)r5   r   r   r   _get_directory_by_folder_typeD   s
   

r<   c                   @  s   e Zd ZdZed0ddZed1ddZed1ddZed2ddZe	d3d4ddZ	ed3d5ddZ
ed6d#d$Zed7d%d&Zed8d+d,Zed9d-d.Zd/S ):ImageSaveHelperzGA helper class with static methods to handle image saving and metadata.image_tensortorch.Tensorr   PILImage.Imagec                 C  s(   t td|    ddtjS )z.Converts a single torch tensor to a PIL Image.g     o@r      )PILImage	fromarraynpclipcpunumpyastypeuint8)r>   r   r   r   _convert_tensor_to_pilO   s   (z&ImageSaveHelper._convert_tensor_to_pilclstype[ComfyNode] | NonePngInfo | Nonec                 C  sp   t js
| du s
| jsdS t }| jjr|dt| jj | jjr6| jjD ]}||t| jj|  q&|S )z7Creates a PngInfo object with prompt and extra_pnginfo.Nprompt)	r   disable_metadatahiddenr   rN   add_textjsondumpsextra_pnginforK   metadataxr   r   r   _create_png_metadataT   s   z$ImageSaveHelper._create_png_metadatac                 C  s   t js
| du s
| jsdS t }| jjr,|jddddd t| jjdd dd | jj	rR| jj	D ]}|jd|ddd t| jj	| dd dd q4|S )	zPCreates a PngInfo object with prompt and extra_pnginfo for animated PNGs (APNG).Ns   comfrN   zlatin-1strict    T)
after_idat)
r   rO   rP   r   rN   addencoderR   rS   rT   rU   r   r   r   _create_animated_png_metadataa   s2   

z-ImageSaveHelper._create_animated_png_metadata	pil_imagePILImage.Exifc                 C  s   |   }tjs|du s|jdu r|S |jjdur$dt|jj|d< |jjdurFd}|jj	 D ]\}}d|t|||< |d8 }q2|S )z,Creates EXIF metadata bytes for WebP images.Nz	prompt:{}i  i  z{}:{}r   )
getexifr   rO   rP   rN   formatrR   rS   rT   items)r_   rK   	exif_datainital_exif_tagkeyr   r   r   r   _create_webp_metadataz   s   
z%ImageSaveHelper._create_webp_metadata   filename_prefixr   r5   r	   r#   c                 C  s   t |t|| d jd | d jd \}}}}}	g }
t|}t| D ]4\}}t|}|dt	|}| d|dd}|j
tj||||d |
t||| |d7 }q$|
S )z0Saves a batch of images as individual PNG files.r   r   %batch_num%_05_.png)pnginfocompress_level)r7   get_save_image_pathr<   shaper=   rX   	enumeraterJ   replacer   saveospathjoinappendr   )r(   ri   r5   rK   ro   full_output_folderr   counterr   rk   r"   rV   batch_numberr>   imgfilename_with_batch_numfiler   r   r   save_images   s    


zImageSaveHelper.save_imagesr!   c                 C  s   t tj| |tj||dS )zDSaves a batch of images and returns a UI object for the node output.ri   r5   rK   ro   )r!   r=   r   r	   r9   )r(   ri   rK   ro   r   r   r   get_save_images_ui   s   z"ImageSaveHelper.get_save_images_uifpsfloatro   intr   c              	   C  s   t |t|| d jd | d jd \}}}}	}
dd | D }t|}| d|dd}tj||}|d j	|||dt
d	| |dd
 d t||	|S )z1Saves a batch of images as a single animated PNG.r   r   c                 S     g | ]}t |qS r   r=   rJ   .0r|   r   r   r   
<listcomp>       z5ImageSaveHelper.save_animated_png.<locals>.<listcomp>rk   rl   rm   T     @@N)rn   ro   save_alldurationappend_images)r7   rp   r<   rq   r=   r^   ru   rv   rw   rt   r   r   )r(   ri   r5   rK   r   ro   ry   r   rz   r   rk   
pil_imagesrV   r~   	save_pathr   r   r   save_animated_png   s     


z!ImageSaveHelper.save_animated_pngc                 C  s.   t j| |tj|||d}t|gt| dkdS )zBSaves an animated PNG and returns a UI object for the node output.)ri   r5   rK   r   ro   r   r$   )r=   r   r	   r9   r!   len)r(   ri   rK   r   ro   resultr   r   r   get_save_animated_png_ui   s   z(ImageSaveHelper.get_save_animated_png_uilosslessr%   qualitymethodc              
   C  s   t |t|| d jd | d jd \}}	}
}}dd | D }t|d |}|	 d|
dd}|d jtj	||dt
d	| |dd
 ||||d t|||S )z2Saves a batch of images as a single animated WebP.r   r   c                 S  r   r   r   r   r   r   r   r      r   z6ImageSaveHelper.save_animated_webp.<locals>.<listcomp>rk   rl   z_.webpTr   N)r   r   r   exifr   r   r   )r7   rp   r<   rq   r=   rg   rt   ru   rv   rw   r   r   )r(   ri   r5   rK   r   r   r   r   ry   r   rz   r   rk   r   pil_exifr~   r   r   r   save_animated_webp   s"    


z"ImageSaveHelper.save_animated_webpc              
   C  s2   t j| |tj|||||d}t|gt| dkdS )zCSaves an animated WebP and returns a UI object for the node output.)ri   r5   rK   r   r   r   r   r   r   )r=   r   r	   r9   r!   r   )r(   ri   rK   r   r   r   r   r   r   r   r   get_save_animated_webp_ui   s   
z)ImageSaveHelper.get_save_animated_webp_uiN)r>   r?   r   r@   )rK   rL   r   rM   )r_   r@   rK   rL   r   r`   )rh   )ri   r   r5   r	   rK   rL   r   r#   )ri   r   rK   rL   r   r!   )ri   r   r5   r	   rK   rL   r   r   ro   r   r   r   )
ri   r   rK   rL   r   r   ro   r   r   r!   )ri   r   r5   r	   rK   rL   r   r   r   r%   r   r   r   r   r   r   )ri   r   rK   rL   r   r   r   r%   r   r   r   r   r   r!   )r   r   r   r/   staticmethodrJ   rX   r^   rg   r   r   r   r   r   r   r   r   r   r   r=   L   s.    r=   c                   @  s>   e Zd ZdZg dZe		ddddZe	ddddZdS )AudioSaveHelperzGA helper class with static methods to handle audio saving and metadata.)i@  i.  i>  i]  逻  flac128kr3   r'   ri   r   r5   r	   rK   rL   rb   r   r   r#   c              	   C  s"  t |t|\}}}}	}
i }tjs=|d ur=|jjd ur%t|jj|d< |jj	d ur=|jj	D ]}t|jj	| ||< q/g }t
| d  D ]F\}}|dt|}| d|dd| }tj||}| d }|dkr|d	krud	}n|tjvrttjD ]
}||kr|} nq|tjvrd	}|| d krtstd
tj|| d |}t }tj|d|d}| D ]	\}}||j|< q|jd dkrdnd}|dkr|jd||d}|dkrd|_ nQ|dkrd|_ nI|dkrd|_ nA|dkrd|_ n9|dkrd|_ n1|dkr(|jd||d}|dkrd|j!_"n|dkrd|_ n|dkr'd|_ n|jd ||d}tj#j$|%dd&dd!' ( d"|d#}||_)d|_*|+|,| |+|,d  |-  |.d t|d$}|/|0  W d    n	1 s|w   Y  |1t2||	| |d7 }qG|S )%NrN   waveformrj   rk   rl   z_.sample_rateopusr   z3torchaudio is not available; cannot resample audio.w)moderb   r   r   monostereolibopus)ratelayout64ki   96ki w r   i  192ki  320ki  mp3
libmp3lameV0r   flt)rb   r   wb)3r7   rp   r<   r   rO   rP   rN   rR   rS   rT   rr   rF   rs   r   ru   rv   rw   r   _OPUS_RATESsortedTORCH_AUDIO_AVAILABLE	Exception
torchaudio
functionalresampler   avopenrc   rV   rq   
add_streambit_ratecodec_contextqscale
AudioFramefrom_ndarraymovedimreshaper   rG   r   ptsmuxr]   closeseekwrite	getbufferrx   r   )r3   ri   r5   rK   rb   r   ry   r   rz   r   rk   rV   rW   r"   r{   r   r}   r~   output_pathr   r   output_bufferoutput_containerrf   r   r   
out_streamframefr   r   r   
save_audio  s   	








zAudioSaveHelper.save_audior0   c              	   C  s   t tj| |tj|||dS )zSave and instantly wrap for UI.ri   r5   rK   rb   r   )r0   r   r   r	   r9   )r3   ri   rK   rb   r   r   r   r   get_save_audio_uit  s   z!AudioSaveHelper.get_save_audio_uiN)r   r   )r3   r'   ri   r   r5   r	   rK   rL   rb   r   r   r   r   r#   )
ri   r   rK   rL   rb   r   r   r   r   r0   )r   r   r   r/   r   r   r   r   r   r   r   r   r     s    kr   c                   @  s    e Zd Zddd	d
Zdd ZdS )PreviewImageFNimage
Image.Typer*   r%   rK   type[ComfyNode]c                 K  s:   t j|dddd tdD  tj|dd| _|| _d S )NComfyUI_temp_ c                 s      | ]}t d V  qdS )abcdefghijklmnopqrstupvxyzNrandomchoicer   rk   r   r   r   	<genexpr>      z(PreviewImage.__init__.<locals>.<genexpr>   r   r   )r=   r   rw   ranger	   tempvaluesr*   )r   r   r*   rK   kwargsr   r   r   r     s   
zPreviewImage.__init__c                 C  s   | j | jfdS )Nr(   r*   )r   r*   r   r   r   r   r,     s   zPreviewImage.as_dictFN)r   r   r*   r%   rK   r   r   r   r   r   r,   r   r   r   r   r     s    
r   c                      s    e Zd Zdd fd	d
Z  ZS )PreviewMaskFNmaskPreviewMask.Typer*   r%   rK   r   c                   sN   | dd|jd |jd fdddddd}t j|||fi | d S )Nr   r      )r   rq   r   expandr   r   )r   r   r*   rK   r   previewr   r   r   r     s   2zPreviewMask.__init__r   )r   r   r*   r%   rK   r   )r   r   r   r   r    r   r   r   r   r     s    r   c                   @  s"   e Zd ZddddZdd	d
ZdS )PreviewAudioNr3   r'   rK   r   c                 K  s6   t j|dddd tdD  tj|ddd| _d S )	Nr   r   c                 s  r   )abcdefghijklmnopqrstuvwxyzNr   r   r   r   r   r     r   z(PreviewAudio.__init__.<locals>.<genexpr>r   r   r   r   )r   r   rw   r   r	   r   r   )r   r3   rK   r   r   r   r   r     s   zPreviewAudio.__init__r   c                 C  r1   r2   r   r   r   r   r   r,     r4   zPreviewAudio.as_dictr&   )r3   r'   rK   r   r-   r   r   r   r   r   r     s    
r   c                   @     e Zd ZdddZdd ZdS )	PreviewVideor   list[SavedResult | dict]c                 K  
   || _ d S r&   r   )r   r   r   r   r   r   r     r4   zPreviewVideo.__init__c                 C  s   | j ddS )Nr)   r   r   r   r   r   r   r,        zPreviewVideo.as_dictN)r   r   r   r   r   r   r   r         
r   c                   @  s   e Zd Zdd Zdd ZdS )PreviewUI3Dc           
      K  s   || _ || _d | _|dd }|d urI|d   d tj}t	
|}t }dt j d}tj||}	|j|	dd d| | _d S d S )	Nbg_imager   rA   bg_z.pngr   )ro   ztemp/)
model_filecamera_infobg_image_pathgetrF   rG   rH   rD   rI   rB   rC   r7   r;   uuiduuid4hexru   rv   rw   rt   )
r   r   r   r   r   	img_arrayr|   temp_dirr   r  r   r   r   r     s   
zPreviewUI3D.__init__c                 C  s   d| j | j| jgiS )Nr   )r   r   r  r   r   r   r   r,     s   zPreviewUI3D.as_dictNr   r   r   r   r   r     s    r   c                   @  r   )	PreviewTextr   r   c                 K  r   r&   r   )r   r   r   r   r   r   r     r4   zPreviewText.__init__c                 C  s   d| j fiS )Ntextr	  r   r   r   r   r,     r   zPreviewText.as_dictN)r   r   r   r   r   r   r   r    r   r  )r   r!   r0   r=   r   r   r   r   r   r   r  )r5   r	   r   r   )(
__future__r   rR   ru   r   r  ior   r   rG   rD   torchr   r   PILr   rB   PIL.PngImagePluginr   r7   comfy.cli_argsr   _ior   r	   r
   r'   r   r!   r0   r<   r=   r   r   r   r   r   r   r  __all__r   r   r   r   <module>   sD    

 9 