1+ <!DOCTYPE html>
2+ < html lang ="en " xmlns ="http://www.w3.org/1999/xhtml ">
3+ <!--
4+ CODEPROJECT.AI SERVER MODULE EXPLORER
5+
6+ This page provides the means to test this module using the same infrastructure as
7+ the CodeProject.AI Server explorer. This page also provides the UI elements that
8+ the explorer will parse and use to build up the UI of the main explorer itself.
9+
10+ RULES AND CONVENTIONS
11+
12+ 1. This page should provide sufficient functionality to test and explore this
13+ module.
14+
15+ 2. This page should use the functionality in the explorer.js file so that when
16+ the elements of this page are inserted into the main explorer, it all works
17+ seamlessly. Specifically, you will probably use
18+
19+ - clearImagePreview: Clears the image preview area.
20+ - previewImage: Displays an image in the shared image preview area and takes a
21+ input[type=file] as parameter.
22+ - submitRequest: Sends a request to the AI server.
23+ - setResultsHtml: Sets the HTML in the shared 'results' element. Parameter is the HTML
24+ to display.
25+ - getProcessingMetadataHtml: Gets HTML representing the common data returned from a call to a
26+ module.
27+ - displayBaseResults: Displays the common data returned from a call to a module.
28+ - showPredictionSummary: Displays in the shared HTML results pane the list of predictions
29+ returned from an inference operation.
30+ - clearImageResult: Clears the image result area
31+ - showResultsImageData: Displays an image in the shared image results area using the data
32+ returned from a call to a module, and overlays bounding boxes if
33+ present in the data
34+ - showResultsBoundingBoxes: Displays bounding boxes on the shared image results area based on
35+ the boxes returned in the predictions parameter. The first param is
36+ an array of predictions returned from a computer vision operation.
37+
38+ 3. There are 3 parts of this page that will be pulled into the main explorer
39+ during runtime: The HTML, the script, and the CSS. These sections are bounded by
40+
41+ - HTML: START EXPLORER MARKUP / END EXPLORER MARKUP pair, each within HTML comment brackets
42+ - Script: START EXPLORER SCRIPT / END EXPLORER SCRIPT pair, each as a // comment on its own line
43+ - CSS: START EXPLORER STYLE / END EXPLORER STYLE pair, each inside /* ... */ comments
44+
45+ These delimiters should be on a line by themselves
46+
47+ 4. **Please provide output elements to display the results of operations** if
48+ you wish to use the standard HTML / Image results elements in the main explorer
49+
50+ - For HTML output, include a DIV with id 'results'
51+ - For Image preview, include an IMG element with id imgPreview
52+ - For image results, include an IMG with element imgPreview and a DIV with
53+ id 'imageMask'.
54+ - You can use a single image for both preview and results if you wish by only
55+ including a imgPreview image. Make sure you have the imageMask DIV though.
56+ - For Sound preview, include an AUDIO element with id 'snd' that contains a
57+ SOURCE tag
58+
59+ 5. When this file is parsed and injected into the larger explorer, the HTML is
60+ injected first, then the script, then the CSS.
61+
62+ 6. **To ensure uniqueness of elements** you can include the _MID_ macro in any
63+ name. This will be expanded to be [ModuleId]_ where [ModuleId] is the literal
64+ ID of this module. For instance <div id="_MID_TextBox"> becomes <div id="MyModuleId_TextBox">
65+ -->
66+ < head >
67+ < meta charset ="utf-8 " />
68+ < title > Text2Image Module Test</ title >
69+
70+ < link id ="bootstrapCss " rel ="stylesheet " type ="text/css " href ="http://localhost:32168/assets/bootstrap-dark.min.css ">
71+ <!--<link rel="stylesheet" type="text/css" href="http://localhost:32168/assets/server.css?v=2.5.0.0">-->
72+ < script type ="text/javascript " src ="http://localhost:32168/assets/server.js "> </ script >
73+ < script type ="text/javascript " src ="http://localhost:32168/assets/explorer.js "> </ script >
74+
75+ < style >
76+ /* START EXPLORER STYLE */
77+ /* END EXPLORER STYLE */
78+ </ style >
79+
80+ </ head >
81+ < body class ="dark-mode ">
82+ < div class ="mx-auto " style ="max-width: 800px; ">
83+ < h2 class ="mb-3 "> Text2Image Module Test</ h2 >
84+ < form method ="post " action ="" enctype ="multipart/form-data " id ="myform ">
85+
86+ <!-- START EXPLORER MARKUP -->
87+ < div class ="form-group row ">
88+ < div >
89+ < label for ="_MID_prompt " class ="col-form-label col-2 "> Prompt</ label >
90+ < textarea id ="_MID_prompt " class ="w-100 " style ="height:100px "
91+ title ="The prompt to be used by Stable Diffusion to create the image "> </ textarea >
92+ </ div >
93+ < div >
94+ < label for ="_MID_negative_prompt " class ="col-form-label "> Negative Prompt</ label >
95+ < textarea id ="_MID_negative_prompt " class ="w-100 " style ="height:100px "
96+ title ="The negative prompt to be used by Stable Diffusion to create the image "> </ textarea >
97+ </ div >
98+
99+ < div class ="row mb-3 ">
100+ < div class ="col-4 ">
101+ < label for "_MID_num_images" class="form-label "> Images</ label >
102+ < input type ="number " id ="_MID_num_images " class ="form-control "
103+ min ="1 " max ="4 " steps ="1 " value ="1 " title ="The number of images to generate. Defaults to 1. "/>
104+ </ div >
105+ < div class ="col-4 ">
106+ < label for ="_MID_seed " class ="form-label "> Seed</ label >
107+ < input id ="_MID_seed " class ="form-control " type ="number " value ="0 "
108+ title ="The seed to use for the diffusion random number generator. If Fixed is checked will use this value, otherwise uses random value. "/>
109+ < label for ="_MID_seed_fixed " class ="form-check-label " > Fixed</ label >
110+ < input id ="_MID_seed_fixed " class ="form-check-input ms-2 " type ="checkbox "
111+ title ="If checked, will use the value above rather than a random value. This allows for reproducible image generation. "/>
112+ </ div >
113+ < div class ="col-4 ">
114+ < label for ="_MID_num_steps " class ="form-label "> Steps</ label >
115+ < input type ="number " id ="_MID_num_steps " class ="form-control " min ="1 " max ="100 "
116+ steps ="1 " value ="40 " title ="The number of inference steps to run "/>
117+ </ div >
118+ </ div >
119+ < div class ="row mb-3 ">
120+ < div class ="col-4 ">
121+ < label for ="_MID_guidance " class ="form-label "> Guidance</ label >
122+ < input type ="number " id ="_MID_guidance " class ="form-control " min ="0.0 " max ="20.0 "
123+ steps ="0.1 " value ="7 " title ="How well the process aligns with the prompt for image generation (0.0 - 20.0). "/>
124+ </ div >
125+ < div class ="col-4 ">
126+ < label for ="_MID_width " class ="form-label "> Width</ label >
127+ < input type ="number " id ="_MID_width " class ="form-control " min ="128 " max ="1024 "
128+ steps ="8 " value ="512 " title ="The width of the image to be created. Defaults to 512. Must be a multiple of 8. "/>
129+ </ div >
130+ < div class ="col-4 ">
131+ < label for ="_MID_height " class ="form-label "> Height</ label >
132+ < input type ="number " id ="_MID_height " class ="form-control " min ="128 " max ="1024 "
133+ steps ="8 " value ="512 " title ="The height of the image to be created. Must be a multiple of 8. "/>
134+ </ div >
135+ </ div >
136+ < input id ="_MID_generte " class ="form-control btn-success " type ="button " value ="Generate Image "
137+ style ="width:11rem " onclick ="_MID_onGenerateImages() " />
138+ </ div >
139+ < hr >
140+ <!-- END EXPLORER MARKUP -->
141+
142+ < div class ="w-100 position-relative form-control my-4 p-0 ">
143+ < div id ="imgMask " class ="position-absolute "
144+ style ="left:0;top:0;pointer-events:none;z-index:10 "> </ div >
145+ < img src ="" id ="imgPreview " class ="w-100 " style ="height:250px;visibility:hidden ">
146+ </ div >
147+ < div >
148+ < h2 > Results</ h2 >
149+ < div id ="results " name ="results " class ="bg-light p-3 " style ="min-height: 100px; "> </ div >
150+ </ div >
151+
152+ </ form >
153+
154+ < script type ="text/javascript ">
155+ // START EXPLORER SCRIPT
156+
157+ async function _MID_onGenerateImages ( ) {
158+
159+ clearImagePreview ( ) ;
160+
161+ if ( ! _MID_prompt . value ) {
162+ alert ( "No image prompt specified" ) ;
163+ return ;
164+ }
165+
166+ setResultsHtml ( "Generating Images..." ) ;
167+ let params = [ [ 'prompt' , _MID_prompt . value ] ,
168+ [ 'num_images_per_prompt' , _MID_num_images . value ] ,
169+ [ 'seed' , _MID_seed_fixed . checked ? _MID_seed . value : null ] ,
170+ [ 'num_inference_steps' , _MID_num_steps . value ] ,
171+ [ 'guidance_scale' , _MID_guidance . value ] ,
172+ [ 'width' , _MID_width . value ] ,
173+ [ 'height' , _MID_height . value ] ] ;
174+
175+ if ( _MID_negative_prompt . value != "" ) {
176+ params . push ( [ 'negative_prompt' , _MID_negative_prompt . value ] ) ;
177+ }
178+
179+ let data = await submitRequest ( 'text2image' , 'create' , null , params ) ;
180+ if ( data ) {
181+ // get the commandId to so we can poll for the results
182+ _MID_commandId = data . commandId ;
183+ _MID_moduleId = data . moduleId ;
184+
185+ params = [ [ 'commandId' , _MID_commandId ] , [ 'moduleId' , _MID_moduleId ] ] ;
186+ done = false ;
187+ loopCount = 0 ;
188+ spinner = "|/-\\" ;
189+
190+ while ( ! done ) {
191+
192+ await delay ( 1000 ) ;
193+
194+ let results = await submitRequest ( 'text2image' , 'get_command_status' , null , params ) ;
195+ if ( results && results . success ) {
196+
197+ if ( results . commandStatus == "failed" ) {
198+ done = true ;
199+ setResultsHtml ( results ?. error || "Unknown error" ) ;
200+ }
201+ else {
202+ let message = results . message ;
203+ if ( results . commandStatus == "completed" ) {
204+ done = true ;
205+ _MID_seed . value = results ?. seed || 0 ;
206+ }
207+ else {
208+ spinChar = spinner . charAt ( loopCount ++ % spinner . length ) ;
209+ message = spinChar + " " + message ;
210+ }
211+
212+ setResultsHtml ( message ) ;
213+
214+ if ( results . images && results . images . length > 0 )
215+ showResultsImage ( results . images [ 0 ] , results . width , results . height ) ;
216+ }
217+ }
218+ else {
219+ // TODO: check for timeouts and other network errors.
220+ done = true ;
221+ // setResultsHtml(results?.error || "No response from server");
222+ }
223+ }
224+ } ;
225+ }
226+
227+ // =====================================================================
228+ // Startup
229+
230+
231+ // END EXPLORER SCRIPT
232+ </ script >
233+ </ div >
234+ </ body >
235+ </ html >
0 commit comments