o yf@sHddlmZddlZddlZddlZddlZddlZddlZddlm Z ddl Z ddl Z ddl Z ddlZ ddlmZmZmZmZmZmZddlZddlZddlZddlZddlmZmZmZmZddlm Z ddl!m"Z"e#edruej$j%nej%Z%dSd d Z&dTddZ'Gddde dgdZ(dUdVddZ)ddZ*Gd d!d!Z+dWd"d#Z,dWd$d%Z-dXd&d'Z.ej/j0sd(Z1nd)Z1d*Z2d+Z3e 4d,ej5d-Z6e 4d.Z7e 4d/Z8ej/j9Z:e;Zd3d4Z?ej>d5d6Z@d7d8ZAGd9d:d:ZBd;d<ZCdZd>d?ZDd[dCdDZEhdEZFd\dGdHZGdIdJZHdKdLZIdMdNZJd]dOdPZKd]dQdRZLdS)^) annotationsN) namedtuple)Image ImageFont ImageDraw ImageColorPngImagePluginImageOps) sd_samplerssharedscript_callbackserrors)roboto_ttf_file)opts ResamplingfontsizeintcCs4z ttjpt|WStytt|YSwN)rtruetyperfontr Exception)rr_C:\Users\Luke\Documents\Stable diffusion\Automatic1111\stable-diffusion-webui\modules\images.pyget_fonts  rc Cs.|durBtjdkr tj}n5tjdkr|}n-tjr7ttt|}t||dkr6|d8}t||dks*n tt|}t|}|t|krLt|}tt||}t |||}t ||dj \}}t jd|j||j|fdd}t|jD]\}} |j| ||j|||j|fdq}|S)NrrRGBblack)sizecolorbox)rn_rowsgrid_prevent_empty_spotsmathfloorsqrtlenroundceilr ImageGridLoopParamsimage_grid_callbackrrnewcolsrows enumerateimgspaste) r/ batch_sizer-r,paramswhgridiimgrrr image_grid$s.     (r8c@seZdZedddZdS)GridreturnrcCstdd|jDS)z8 The total number of tiles in the grid. css|] }t|dVqdS)N)r&).0rowrrr Hsz"Grid.tile_count..)sumtilesselfrrr tile_countCszGrid.tile_countN)r:r)__name__ __module__ __qualname__propertyrCrrrrr9Bsr9Z_Grid)r@tile_wtile_himage_wimage_hoverlap@image Image.ImagerHrIrLr:c Cs(|j\}}||}||}t|||}t|||} |dkr+|||dnd} | dkr9||| dnd} tg|||||} t| D]I} g}t| | }|||kr\||}t|D]'}t|| }|||krr||}|||||||f}||||gq`| j|||gqH| SNrr) rr#r(r9rangercropappendr@)rOrHrIrLr3r4Znon_overlap_widthZnon_overlap_heightr,r-dxdyr5r=Z row_imagesycolxtilerrr split_gridKs*       r[c sxfdd}|tjjtjddjfjjdd}|tjjtjdjdfjjdd}t djj f}j D]x\}}}t dj|f}|D]5\} } } | dkra| | dqQ|j | ddj|f| df|d | | jd| |f| jdfqQ|dkr| |dqA|j | dd|jjfd|f|d | | dj|j|fd|jfqA|S) Ncs&|dj}|tj}t|dS)NL)rLastypenpuint8r fromarray)rr5rrmake_mask_imageps  z%combine_grid..make_mask_image)dtyperr)axisrrrmask)r_arangerLfloat32reshaperepeatrIrJrr+rKr@r0rSwidth) r5rdZmask_wZmask_hZcombined_imagerWr4r=Z combined_rowrYr3rZrrcr combine_gridos$ .. $( &*roc@seZdZdddZdS)GridAnnotationTcCs||_||_d|_dSr)text is_activer)rBrrrsrrr__init__s zGridAnnotation.__init__N)rqT)rDrErFrtrrrrrpsrpc sJttjdttjdttjd}dd}fdd}||d} | dt| } tdd |Dd kr.wrapc s|D]~}|}|}|j|j|dd|jkr2|dkr2|d8}t|}|j|j|dd|jkr2|dks|j|||jddf|j||jrFnddd|jsw|j||jdd||jdd||jdd||jddfdd ||jd7}qdS) Nrwrrr;mmcenter)rfillanchoralign)rrn)multiline_textsizerr allowed_widthrmultiline_textrrsr) r{Zdraw_xZdraw_yr}Z initial_fntZinitial_fontsizerfntr) color_activecolor_inactive line_spacingrr draw_textss""4Pz)draw_grid_annotations..draw_textsr;cSsg|] }tdd|DqS)cSsg|]}t|jqSr)r&rrr<rrrr 4draw_grid_annotations...r?r<r}rrrrz)draw_grid_annotations..rrz bad number of horizontal texts: z ; must be zbad number of vertical texts: )rrcsg|]}t|jqSr)rprsr<rY)rrrrrgrwrcs&g|]}tfdd|DqS)cg|] }|jdqSrrrrrrrrrrrrrrs&cs.g|]}tfdd|Dt|qS)crrrrrrrrrr)r?r&rrrrrs.)rgetcolorrgrid_text_active_colorgrid_text_inactive_colorgrid_background_colorrr?rnheightr&rr+rDrawzipclearrrmultiline_textbboxrrmaxrRrSr0)imrnr hor_texts ver_textsmarginZcolor_backgroundrrrrpad_leftr,r-Zcalc_imgZcalc_dtextsritemswrappedbboxZhor_text_heightsZver_text_heightspad_topresultr=rXcelldrYrWr)rrrrrdraw_grid_annotationssZ &  $$ ." 6  *,   $rc s|dd}tt|d}|d|||dfddtdt>D}fddtdt>D}t||||||S)Nrr;c"g|] fddtDqS)c(g|]\}}t|d|>@dkdqSrr)rsrpr<r6rYposrrr(1draw_prompt_matrix...r.r<) prompts_horizrrr"z&draw_prompt_matrix..cr)crrrrrrrrrrrr) prompts_vertrrrr)r#r(r&rRr) rrnr all_promptsrpromptsboundaryrrr)rrrdraw_prompt_matrixs   rcsRptjfdd}|dkr||||}|S|dkrf||}|j|j}||kr+|n|j||j} ||kr9|n|j||j} ||| | } td||f}|j| |d| d|d| dfd|S||}|j|j}||krv|n|j||j} ||kr|n|j||j} ||| | } td||f}|j| |d| d|d| dfd||kr|d| d} | dkr|j| j|| fdd|dfddd|j| j|| fd| j|| jfdd| | fd|S||kr'|d| d} | dkr'|j| j| |fddd|fddd|j| j| |f| jd| j|fd| | dfd|S) a; Resizes an image with the specified resize_mode, width, and height. Args: resize_mode: The mode to use when resizing the image. 0: Resize the image to the specified width and height. 1: Resize the image to fill the specified width and height, maintaining the aspect ratio, and then center the image within the dimensions, cropping the excess. 2: Resize the image to fit within the specified width and height, maintaining the aspect ratio, and then center the image within the dimensions, filling empty with data from image. im: The image to resize. width: The width to resize the image to. height: The height to resize the image to. upscaler_name: The name of the upscaler to use. If not provided, defaults to opts.upscaler_for_img2img. csdus dks |jdkr|j||ftdSt||j||j}|dkrVfddtjD}t|dkrItjd}t dp?d d |j d n|d}|j |||j }|j|ks`|j|kri|j||ftd}|S) NNoner])resampleg?csg|] }|jkr|qSr)namer upscaler_namerrrrz0resize_image..resize..rzcould not find upscaler named zz, using z as a fallback)moderesizeLANCZOSrrnrr sd_upscalersr&printrscalerupscale data_path)rr3r4scaleZ upscalersupscalerrrrr s  zresize_image..resizerrrr;rrg)rupscaler_for_img2imgrnrrr+r0r) resize_moderrnrrrresratio src_ratiosrc_wsrc_hresizedZ fill_heightZ fill_widthrrr resize_imagesB   #  *  *$0  $0rz #<>:"/\|?* /rvz .z[\sz]+z(.*?)(?:\[([^\[\]]+)\]|$)z(.*)<([^>]*)>$TcCsP|durdS|r|dd}|ddtD}|tdt}|t}|S)Nrv_cSsi|]}t|dqS)r)ordrrrr Zrz*sanitize_filename_part..)replace translateinvalid_filename_charslstripinvalid_filename_prefixmax_filename_part_lengthrstripinvalid_filename_postfix)rrreplace_spacesrrrsanitize_filename_partSs  rcCs(|dkrt|}|jdd}|S)zAReturns {Scheduler} if the scheduler is applicable to the sampler Automatic scheduler)r find_sampler_configoptionsget capitalize) sampler_namescheduler_nameconfigrrrget_scheduler_str`s rcCs|dt||S)zQReturns the '{Sampler} {Scheduler}' if the scheduler is applicable to the samplerrv)r)rrrrrget_sampler_scheduler_strisrcCsFt|dr!t|dr!|rt|j|j}nt|j|j}t|ddStS)zRReturns '{Sampler} {Scheduler}' / '{Scheduler}' / 'NOTHING_AND_SKIP_PREVIOUS_TEXT'rrFr)hasattrrrrrrNOTHING_AND_SKIP_PREVIOUS_TEXT)psamplersampler_schedulerrrrget_sampler_scheduleros  rc@seZdZiddddddddddd dd d dd d ddddddddddddddddddddddddddddd d!dd"d#did$d%dd&d'dd(d)dd*d+dd,d-dd.d/dd0d1dd2d3dd4d5dd6d7dd8d9dd:d;ddd?dd@dAddBdCdZdDZdYdFdGZdHdIZdJdKZdLdMZdNdOZ dPdQZ dRdSZ dTdUZ dVdWZ dXS)ZFilenameGeneratorseedcCs|jdur|jSdSNrq)rrArrr|zFilenameGenerator.Z seed_firstcCs|jjdkr |jS|jjdSrQ)rr1r all_seedsrArrrr}rZ seed_lastcCs|jjdkrtS|jjdS)Nrru)rr1rrrArrrr~sstepscC|jo|jjSr)rrrArrrrcfgcCrr)r cfg_scalerArrrrr rncC|jjSr)rOrnrArrrrrcCr r)rOrrArrrrr stylescCs*|jotddd|jjDpdddS)Nz, cSsg|]}|dks|qS)rr)r<stylerrrrrz.FilenameGenerator...rFr)rrjoinrrArrrrs*rcCs|jo t|jjddSNFr)rrrrArrrrrrcC|jot|jdS)NTrrrArrrrrcCr)NFrrArrrrr model_hashcCt|jdtjjS)N sd_model_hash)getattrrr sd_modelrrArrrrr model_namecCsttjjjddSr)rr rsd_checkpoint_infoname_for_extrarArrrrrdatecCstjdS)Nz%Y-%m-%d)datetimenowstrftimerArrrrsrcG |j|Sr)rrBargsrrrr job_timestampcCr)Nr%)rrr stater%rArrrrrZ prompt_hashcGs|j|jg|RSr) string_hashpromptr"rrrrrZnegative_prompt_hashcGs|j|jjg|RSr)r'rnegative_promptr"rrrrrZfull_prompt_hashcGs$|j|jjd|jjg|RS)Nrv)r'rr(r)r"rrrrs$r(cCs t|jSrrr(rArrrrr$Zprompt_no_stylescC|Sr)prompt_no_stylerArrrrr Z prompt_spacescCst|jddSrr*rArrrrr  prompt_wordscCr+r)r-rArrrrr  batch_numbercCs"|jjdks |jr tS|jjdSNr)rr1rr batch_indexrArrrrrr1cCr r)rr1rArrrrr Zgeneration_numbercCs>|jjdkr |jjdks|jrtS|jj|jj|jjdSr/)rn_iterr1rr iterationr0rArrrrs> haspromptcGr!r)r3r"rrrrr$ clip_skipcCs tjdS)NCLIP_stop_at_last_layers)rdatarArrrrr$ denoisingcCs|jr |jjr |jjStSr)rdenoising_strengthrrArrrrrusercCr r)rr9rArrrrr Z vae_filenamecCr+r)get_vae_filenamerArrrrr nonecCsdSrrrArrrrs image_hashcGr!r)r<r"rrrrr$z %Y%m%d%H%M%SFcCs"||_||_||_||_||_dSr)rrr(rOr)rBrrr(rOrrrrrts  zFilenameGenerator.__init__cCsZddlm}|jdur dStj|j}|d}t|dkr)|ddkr)|dS|dS)zGet the name of the VAE file.rNNoneType.rrq)modules.sd_vaesd_vaeZloaded_vae_fileospathbasenamerxr&)rBr@ file_namesplit_file_namerrrr:s   z"FilenameGenerator.get_vae_filenamecGs|j}|jdus|jdurdSd}|D]7}|dkrL|d}|d}t|dkr0|dnd}||dkr@||}q|dkrF|n||}qt|S)Nrq|rr)r(lowerrrxr&findr)rBr#rGZoutresargdivisionexpecteddefaultrrrr3s   zFilenameGenerator.haspromptcCs|jdus |jdur dS|j}tj|jjD](}|r?|dD]}||dddd}q ||dd}qt |ddS)Nz{prompt}rqz, ,,Fr) rr(r prompt_stylesget_style_promptsrrxrryr)rBr,rpartrrrr,s  z!FilenameGenerator.prompt_no_stylecCsHddt|jp dD}t|dkrdg}td|dtjddS) NcSsg|]}|r|qSrrrrrrrrz2FilenameGenerator.prompt_words..rqremptyrvFr) re_nonlettersrxr(r&rrrdirectories_max_prompt_words)rBwordsrrrr-s zFilenameGenerator.prompt_wordsc Gstj}|r|ddkr|dn|j}zt|dkr"t|dnd}Wn tjjy2d}Ynw||}z| |}Wnt t fyP| |j}Ynwt |ddS)NrrqrFr) rrdefault_time_formatr&pytztimezone exceptionsUnknownTimeZoneError astimezoner  ValueError TypeErrorr)rBr#Z time_datetime time_formatZ time_zoneZtime_zone_timeZformatted_timerrrrs "  zFilenameGenerator.datetimecGs<|r|ddkrt|dnd}t|jd|S)Nrrq)rhashlibsha256rOtobytes hexdigest)rBr#lengthrrrr<s zFilenameGenerator.image_hashcGs:|r|ddkrt|dnd}t|d|S)Nrrq)rr^r_encodera)rBrrr#rbrrrr's zFilenameGenerator.string_hashc Csd}t|D]t}|\}}|dur||7}qg} t|}|dur%n |\}}|d|q|j|}|durqz ||g|R} Wnt y^d} t j d|dddYnw| t krdq| durq||t | 7}q||d|d7}q|S) NrqTrzError adding [z ] to filenameexc_info[]) re_patternfinditergroupsre_pattern_argmatchinsert replacementsrrGrr reportrstr) rBrYrmrrpatternZ pattern_argsrIfun replacementrrrapplys:     zFilenameGenerator.applyN)F)rDrErFrorUrtr:r3r,r-rr<r'rvrrrrrzs      !#  rc Csd}|dkr |d}t|}t|D]+}||r?tj||ddd}z tt|d|}Wqt y>Yqwq|dS)z Determines and returns the next sequence number to use when saving an image in the specified directory. The sequence starts at 0. rurq-Nrr) r&rAlistdir startswithrBsplitextrxrrr[)rBrCrZ prefix_lengthrpartsrrrget_next_sequence_numbers   r| parametersc Cs|dur tj|d}t|}|dkrL|pi}tjr#|||<tjr>t }|p-i D] \}} | |t | q0nd}|j ||tj|ddS|dvr|jdkr]|d}n|jdkrt|d d |d krqdnd }|j ||tjtjd tjr|durtdtjjtjjj|pdddii} t| |dSdSdS|dkrtjr|durtdtjjtjjj|pdddii} |j ||| ddS|dkr|j |||ddS|j ||tjddS)a+ Saves image to filename, including geninfo as text information for generation info. For PNG images, geninfo is added to existing pnginfo dictionary using the pnginfo_section_name argument as key. For JPG images, there's no dictionary and geninfo just replaces the EXIF description. Nr.png)formatqualitypnginfo).jpgz.jpeg.webpRGBArzI;16cSs|dS)Ng=o?r)rrrrrNr z)save_image_with_geninfo..rr])rrlosslessExifrqunicodeencodingz.avif)rexifz.gif)rcomment)rr)rArBrzrregistered_extensionsrGrenable_pnginforPngInforadd_textrqsave jpeg_qualityrconvertpoint webp_losslesspiexifdumpExifIFD UserCommenthelperrn) rOgeninfofilename extensionexisting_pnginfopnginfo_section_nameZ image_formatZ pnginfo_datakvZ exif_bytesrrrsave_image_with_geninfo0sN      $  rpngFrqc" s*t| |||}|jdks|jdkr|dvs'|jdks!|jdkr-|dkr-tdd}|dur?| r6tjp>| o>tjo>| }|rV|tj pGd d  d }t j ||}t j|d d | dur|sg|durjd }ntjrstjpqd}ntjpwd}|||}tjp|d k}|d kr|rd|}|rt||}d}tdD],}|d kr||dn |d||d}t j |||d|}t j |snqnt j ||d|}n t j || d|}| pi}dur|<t|| ||tj}j}jdfdd}t j j\}}tt dr=t |j}|d|t dt!|}||_j}||||||_"|jtj#kpR|jtj#k}tj$r|sht %|j&tj'ddkr|j|j}d}|r|dkrt(tj#t(|jtj#|jf}n|rt(|jtj#|jt(tj#f}|durz|)|t*}Wnt+y|)|}Ynwz|||dWnt+y}z t,-|dWYd}~nd}~wwtj.r dur |d} t/| ddd }!|!0d!Wdn 1swYnd} t1|| fS)"a!Save an image. Args: image (`PIL.Image`): The image to be saved. path (`str`): The directory to save the image. Note, the option `save_to_dirs` will make the image to be saved into a sub directory. basename (`str`): The base filename which will be applied to `filename pattern`. seed, prompt, short_filename, extension (`str`): Image file extension, default is `png`. pngsectionname (`str`): Specify the name of the section which `info` will be saved in. info (`str` or `PngImagePlugin.iTXt`): PNG info chunks. existing_info (`dict`): Additional PNG info. `existing_info == {pngsectionname: info, ...}` no_prompt: TODO I don't know its meaning. p (`StableDiffusionProcessing`) forced_filename (`str`): If specified, `basename` and filename pattern will be ignored. save_to_dirs (bool): If true, the image will be saved into a subdirectory of `path`. Returns: (fullfn, txt_fullfn) fullfn (`str`): The full path of the saved imaged. txt_fullfn (`str` or None): If a text file is saved for this image, this will be its full path. Otherwise None. i)jpgjpegi?webpz)Image dimensions too large; saving as PNGr~Nz[prompt_words]rvz\ /T)exist_okrqz[seed]z[seed]-[prompt_spaces]rwiZ05Z04r>csz|d}t|||jd||}tjjdkr5d}tj|r5|d7}|d||}tj|s"t||dS)z save image with .tmp extension to avoid race condition when another process detects new image in the directory z.tmp)rrReplacerrrwN) rrr rsave_images_replace_actionrArBexistsr)Z image_to_saveZfilename_without_extensionrtemp_file_pathrninfor2rrr_atomically_save_images    z*save_image.._atomically_save_imagestatvfsrirrzsaving image as downscaled JPGz.txtr3utf8r )2rrrnrGrrgrid_save_to_dirs save_to_dirsrvdirectories_filename_patternrrrArBrmakedirssamples_filename_patternsave_images_add_numberr|rRrr ImageSaveParamsbefore_image_saved_callbackrOrrrrzrr f_namemaxrr&Zalready_saved_astarget_side_lengthexport_for_4chanstatst_sizeimg_downscale_thresholdr'rrrr displaysave_txtopenwriteimage_saved_callback)"rOrBrCrr(rrshort_filenameZ no_promptr5rr existing_infoforced_filenamesuffixrZnamegendirnameZfile_decorationZ add_numberZ basecountZfullfnr6fnrrZfullfn_without_extension max_name_lenZoversizer resize_toeZ txt_fullfnfilerrr save_imagejs!@       (      * "    r> jfif_density progressionr timestamploop chromaticity icc_profile jfif_version jfif_unitduration progressive photoshopdpi backgroundjfiftuple[str | None, dict]c Cs|jpi}|dd}d|vrU|d}zt|}Wn ty'd}Ynw|p+iditjjd}z tj j|}Wnt yO|j ddd}Ynw|rT|}n d|vrb|dj ddd}t D]}||dqd|d dd krz;t |d }tj|d d }|dd|dd|dd|d|dd|dd|jd|jd}W||fStytjdddY||fSw||fS)Nr}rrrignore)r rSoftwareZNovelAICommentrzEuler a Descriptionz Negative prompt: ucz Steps: rz , Sampler: z , CFG scale: rz, Seed: rz, Size: rYz, Clip skip: 2, ENSD: 31337z1Error parsing NovelAI image generation parametersTre)rcopypoprloadOSErrorrrrrr[decodeIGNORED_INFO_KEYSjsonloadsr samplers_maprnrrr rp) rOrrZ exif_datarZ exif_commentfieldZ json_inforrrrread_info_from_images^      rcCsddl}ztt|}t|\}}|dfWStyYnwz|d}t|dks.J|dfWSty;Ynw|dfS)Nrri') gradioreadioBytesIOrrrr&update)r6grrOtextinforrrrrr image_data+s        rcCs6|jdkrtd|j|}|j||d|}|dS)zireplaces transparency with bgcolor (example: "#ffffff"), returning an RGB mode image with no transparencyrrhr)rrr+rr0r)r7bgcolorrrrrflatten@s  rcKstj|fi|}t|}|Sr)rr fix_image)fpkwargsrOrrrrKsrcCs:|durdSz t|}t|}W|StyY|Swr)r exif_transposefix_png_transparencyrrOrrrrRs   rcCs.|jdvst|jdts|S|d}|S)N)rP transparencyr)r isinstancerrbytesrrrrrr_s r)rr)rN)rMrMrN) rOrPrHrrIrrLrr:r9)rr)T)NNr}) NNrNFFFr}NNNrqN)rOrPr:r)rOrP)M __future__rr functoolsrVrr#rA collectionsrrenumpyr_rZ piexif.helperPILrrrrrr Z pillow_avifstringrr^modulesr r r r modules.paths_internalrmodules.sharedrrrrrr8r9r[rorprrrcmd_optsunix_filenames_sanitizationrrrcompile punctuationrRrirlfilenames_max_lengthrobjectrrcacherrrrr|rrrrrrrrrrrrrsv        $  X M      !  : (