1
1
<!DOCTYPE html>
2
2
< html lang ="en ">
3
- < head >
4
- < meta charset ="UTF-8 " />
5
- < meta http-equiv ="X-UA-Compatible " content ="IE=edge " />
6
- < meta name ="viewport " content ="width=device-width, initial-scale=1.0 " />
7
- < script src ="https://cdn.tailwindcss.com "> </ script >
8
- < script src ="api.js "> </ script >
9
- < title > Image Gererator using OpenAI API</ title >
10
- < style >
11
- .min-height {
12
- min-height : 100vh ;
13
- }
14
- </ style >
15
- </ head >
16
- < body class ="max-w-4xl mx-auto ">
17
- < div
18
- class ="min-height flex flex-col justify-center px-4 py-12 sm:px-6 lg:px-8 -mt-20 "
19
- >
20
- < div class ="text-center ">
21
- < h1 class ="text-4xl font-bold mb-10 "> Image Generator</ h1 >
22
- < p class ="text-md lg:text-xl mb-10 ">
23
- This is a simple image generator using
24
- < a href ="https://openai.com/api/ " class ="font-semibold "
25
- > OpenAI API.</ a
26
- >
27
- you can generate images by entering short description of the image or
28
- by entering a keyword.
29
- </ p >
3
+
4
+ < head >
5
+ < meta charset ="UTF-8 " />
6
+ < meta http-equiv ="X-UA-Compatible " content ="IE=edge " />
7
+ < meta name ="viewport " content ="width=device-width, initial-scale=1.0 " />
8
+ < script src ="https://cdn.tailwindcss.com "> </ script >
9
+ < script src ="api.js "> </ script >
10
+ < link rel ="stylesheet " href ="style.css " />
11
+ < title > Image Gererator using OpenAI API</ title >
12
+ </ head >
13
+
14
+ < body class ="max-w-4xl mx-auto ">
15
+ < div class ="flex flex-col justify-center px-4 pt-12 sm:px-6 lg:px-8 ">
16
+ < div class ="text-center ">
17
+ < h1 class ="text-4xl font-bold mb-10 "> Image Generator</ h1 >
18
+ < p class ="text-md lg:text-xl mb-10 ">
19
+ This is a simple image generator using
20
+ < a href ="https://openai.com/api/ " class ="font-semibold "> OpenAI API.</ a >
21
+ You can generate images by entering a short description of the image or by entering a keyword.
22
+ </ p >
23
+ </ div >
24
+ < div class ="bg-white shadow-md rounded-lg px-8 pt-6 pb-8 mb-4 flex flex-col my-2 ">
25
+ < div class ="mb-4 flex flex-col gap-2 ">
26
+ < label for ="api " class ="text-gray-600 apiDiv "> OpenAI API Key</ label >
27
+ < input type ="text " id ="api " class ="input-style apiDiv " placeholder ="Enter your OpenAI API key here " />
28
+ < label for ="text " class ="text-gray-600 "> Description or Keyword</ label >
29
+ < textarea id ="text " class ="input-style "
30
+ placeholder ="Enter a short description of the image or a keyword "> </ textarea >
31
+ < label for ="sizeSelect " class ="text-gray-600 "> Image Size</ label >
32
+ < select id ="sizeSelect " class ="input-style "> </ select >
33
+ < label for ="numImagesSelect " class ="text-gray-600 "> Number of Images</ label >
34
+ < select id ="numImagesSelect " class ="input-style "> </ select >
30
35
</ div >
31
- < div class ="flex flex-row justify-center ">
32
- < input
33
- type ="text "
34
- id ="text "
35
- class ="shadow-lg outline-none w-full rounded-l-lg px-4 py-4 text-gray-600 border-r-2 border-gray-200 "
36
- placeholder ="An Impressionist oil painting of sunflowers in a purple vase… "
37
- />
38
- < button
39
- id ="btn "
40
- class ="font-bold py-4 px-8 rounded-r-lg shadow-lg "
41
- onclick ="generateImage() "
42
- >
43
- Generate
44
- </ button >
36
+ < div class ="mt-2 text-right ">
37
+ < button id ="btn " class ="button-style "> Generate</ button >
45
38
</ div >
46
- < div id ="image " class ="grid grid-cols-2 lg:grid-cols-3 gap-1 mt-4 "> </ div >
47
- < footer
48
- class ="text-center mt-10 border-t-2 border-gray-200 pt-4 "
49
- id ="checkAuthor "
50
- >
51
- < p class ="text-sm ">
52
- Made with ❤️ by
53
- < a href ="https://github.com/sauravhathi " class ="font-semibold "
54
- > @sauravhathi</ a
55
- >
56
- </ p >
57
- </ footer >
39
+ < div id ="loading " class ="hidden flex justify-center items-center mt-10 ">
40
+ < svg class ="animate-spin h-10 w-10 text-gray-500 " viewBox ="0 0 24 24 ">
41
+ < circle class ="opacity-25 " cx ="12 " cy ="12 " r ="10 " stroke ="currentColor " stroke-width ="4 "> </ circle >
42
+ < path class ="opacity-75 " fill ="currentColor "
43
+ d ="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647zm11-2.647A7.962 7.962 0 0120 12h-4c0 3.042-1.135 5.824-3 7.938l-3-2.647z ">
44
+ </ path >
45
+ </ svg >
46
+
47
+ </ div >
48
+ < div id ="image " class ="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4 mt-10 "> </ div >
58
49
</ div >
59
- </ body >
60
- < script >
61
-
62
- if ( api === "" ) {
63
- alert ( "Use your openAI API key" ) ;
64
- }
65
- const url = "https://api.openai.com/v1/images/generations" ;
66
- const text = document . getElementById ( "text" ) ;
67
- const image = document . getElementById ( "image" ) ;
68
- const btn = document . getElementById ( "btn" ) ;
69
-
70
- function generateImage ( ) {
71
- if ( text . value === "" ) {
72
- alert ( "Please enter a value" ) ;
73
- } else {
74
- const data = {
75
- prompt : text . value ,
76
- n : 3 ,
77
- size : "1024x1024" ,
78
- } ;
79
- fetch ( url , {
80
- method : "POST" ,
81
- headers : {
82
- "Content-Type" : "application/json" ,
83
- Authorization : `Bearer ${ api } ` ,
84
- } ,
85
- body : JSON . stringify ( data ) ,
86
- } )
87
- . then ( ( res ) => res . json ( ) )
88
- . then ( ( data ) => {
89
- console . log ( data ) ;
90
- const arraySize = data . data . length ;
91
- for ( let i = 0 ; i < arraySize ; i ++ ) {
92
- image . innerHTML += `<img src="${ data . data [ i ] . url } " alt="image" class="w-100 p-2">` ;
93
- }
94
- } ) ;
50
+ </ div >
51
+ < footer class ="text-center mt-10 border-t-2 border-gray-200 py-4 " id ="checkAuthor ">
52
+ < p class ="text-sm ">
53
+ Made with ❤️ by
54
+ < a href ="https://github.com/sauravhathi " class ="font-semibold "> @sauravhathi</ a >
55
+ </ p >
56
+ </ footer >
57
+ </ body >
58
+
59
+ < script >
60
+ const url = "https://api.openai.com/v1/images/generations" ;
61
+ const text = document . getElementById ( "text" ) ;
62
+ const image = document . getElementById ( "image" ) ;
63
+ const btn = document . getElementById ( "btn" ) ;
64
+ const sizeSelect = document . getElementById ( "sizeSelect" ) ;
65
+ const numImagesSelect = document . getElementById ( "numImagesSelect" ) ;
66
+ const loadingSpinner = document . getElementById ( "loading" ) ;
67
+ const apiDiv = document . getElementsByClassName ( "apiDiv" ) ;
68
+ const apiInput = document . getElementById ( "api" ) ;
69
+
70
+ const sizeOptions = [ "256" , "512" , "1024" , "1280" , "2560" , "3840" , "5120" , "7680" ] ;
71
+ const optionsFragment = document . createDocumentFragment ( ) ;
72
+
73
+ sizeOptions . forEach ( ( size ) => {
74
+ const option = document . createElement ( "option" ) ;
75
+ option . value = size ;
76
+ option . textContent = size ;
77
+ optionsFragment . appendChild ( option ) ;
78
+ } ) ;
79
+
80
+ sizeSelect . appendChild ( optionsFragment ) ;
81
+
82
+ for ( let i = 1 ; i <= 10 ; i ++ ) {
83
+ const option = document . createElement ( "option" ) ;
84
+ option . value = i ;
85
+ option . textContent = i ;
86
+ numImagesSelect . appendChild ( option ) ;
87
+ }
88
+
89
+ let imageSizes = sizeSelect . value ;
90
+ let numImages = parseInt ( numImagesSelect . value ) ;
91
+ let apiKey = "" ;
92
+
93
+ function generateImage ( ) {
94
+ if ( apiKey === "" ) {
95
+ apiKey = apiInput . value . trim ( ) || api ;
96
+ if ( apiKey === "" ) {
97
+ alert ( "Please enter your OpenAI API key" ) ;
98
+ return ;
95
99
}
100
+ apiDiv [ 0 ] . classList . add ( "hidden" ) ;
101
+ apiDiv [ 1 ] . classList . add ( "hidden" ) ;
102
+ }
103
+ if ( text . value === "" ) {
104
+ alert ( "Please enter a value" ) ;
105
+ return ;
96
106
}
97
107
98
- const checkAuthor = document . getElementById ( "checkAuthor" ) ;
99
- if ( checkAuthor . children [ 0 ] . children [ 0 ] . textContent === "@sauravhathi" ) {
108
+ loadingSpinner . classList . remove ( "hidden" ) ;
109
+ btn . disabled = true ;
110
+
111
+ const data = {
112
+ prompt : text . value ,
113
+ n : numImages ,
114
+ size : `${ imageSizes } x${ imageSizes } ` ,
115
+ } ;
116
+
117
+ fetch ( url , {
118
+ method : "POST" ,
119
+ headers : {
120
+ "Content-Type" : "application/json" ,
121
+ Authorization : "Bearer " + apiKey ,
122
+ } ,
123
+ body : JSON . stringify ( data ) ,
124
+ } )
125
+ . then ( ( res ) => res . json ( ) )
126
+ . then ( ( data ) => {
127
+ console . log ( data ) ;
128
+ loadingSpinner . classList . add ( "hidden" ) ;
129
+ btn . disabled = false ;
130
+
131
+ data . data . forEach ( ( item ) => {
132
+ const img = document . createElement ( "img" ) ;
133
+ img . src = item . url ;
134
+ img . alt = "image" ;
135
+ img . classList . add (
136
+ "w-full" ,
137
+ "h-auto" ,
138
+ "rounded-lg" ,
139
+ "shadow-lg" ,
140
+ "hover:shadow-2xl" ,
141
+ "transition" ,
142
+ "duration-500" ,
143
+ "ease-in-out" ,
144
+ "transform" ,
145
+ "hover:-translate-y-1" ,
146
+ "hover:scale-103"
147
+ ) ;
148
+
149
+ image . appendChild ( img ) ;
150
+
151
+ // Double-click event listener
152
+ img . addEventListener ( "dblclick" , ( ) => {
153
+ downloadImage ( item . url ) ;
154
+ } ) ;
155
+ } ) ;
156
+ } )
157
+ . catch ( ( err ) => {
158
+ console . log ( err ) ;
159
+ loadingSpinner . classList . add ( "hidden" ) ;
160
+ btn . disabled = false ;
161
+ alert ( "Something went wrong. Please try again." ) ;
162
+ } ) ;
163
+ }
164
+
165
+ const checkAuthor = document . getElementById ( "checkAuthor" ) ;
166
+ if ( checkAuthor . children [ 0 ] . children [ 0 ] . textContent !== "@sauravhathi" ) {
167
+ window . location . href = "https://github.com/sauravhathi" ;
168
+ }
169
+
170
+ text . addEventListener ( "input" , function ( ) {
171
+ if ( text . value === "" ) {
172
+ btn . classList . remove ( "bg-slate-900" , "text-slate-50" ) ;
173
+ text . classList . add ( "border-r-2" , "border-gray-200" ) ;
100
174
} else {
101
- window . location . href = "https://github.com/sauravhathi" ;
175
+ text . classList . remove ( "border-r-2" , "border-gray-200" ) ;
176
+ btn . classList . add ( "bg-slate-900" , "text-slate-50" ) ;
102
177
}
178
+ } ) ;
103
179
104
- text . addEventListener ( "input" , function ( ) {
105
- if ( text . value === "" ) {
106
- btn . classList . remove ( "bg-slate-900" , "text-slate-50" ) ;
107
- text . classList . add ( "border-r-2" , "border-gray-200" ) ;
108
- } else {
109
- text . classList . remove ( "border-r-2" , "border-gray-200" ) ;
110
- btn . classList . add ( "bg-slate-900" , "text-slate-50" ) ;
111
- }
112
- } ) ;
113
- </ script >
114
- </ html >
180
+ sizeSelect . addEventListener ( "change" , function ( ) {
181
+ imageSizes = sizeSelect . value ;
182
+ } ) ;
183
+
184
+ numImagesSelect . addEventListener ( "change" , function ( ) {
185
+ numImages = parseInt ( numImagesSelect . value ) ;
186
+ } ) ;
187
+
188
+ btn . addEventListener ( "click" , generateImage ) ;
189
+
190
+ function downloadImage ( url ) {
191
+ const link = document . createElement ( "a" ) ;
192
+ link . href = url ;
193
+ link . download = document . getElementById ( "text" ) . value . split ( " " ) . join ( "_" ) + ".png" ;
194
+ link . target = "_blank" ;
195
+ link . click ( ) ;
196
+ }
197
+ </ script >
0 commit comments