- Dockerfile +19 -0
- package.json +16 -0
- server.js +37 -0
- static/index.html +57 -0
- static/jquery.js +0 -0
- txt2images.js +30 -0
Dockerfile
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
FROM node:18
|
2 |
+
|
3 |
+
# Create app directory
|
4 |
+
WORKDIR /usr/src/app
|
5 |
+
|
6 |
+
# Install app dependencies
|
7 |
+
# A wildcard is used to ensure both package.json AND package-lock.json are copied
|
8 |
+
# where available (npm@5+)
|
9 |
+
COPY package*.json ./
|
10 |
+
|
11 |
+
RUN npm install
|
12 |
+
# If you are building your code for production
|
13 |
+
# RUN npm ci --omit=dev
|
14 |
+
|
15 |
+
# Bundle app source
|
16 |
+
COPY . .
|
17 |
+
|
18 |
+
EXPOSE 7860
|
19 |
+
CMD [ "node", "server.js" ]
|
package.json
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"name": "docker_web_app",
|
3 |
+
"version": "1.0.0",
|
4 |
+
"description": "Node.js on Docker",
|
5 |
+
"author": "First Last <[email protected]>",
|
6 |
+
"main": "server.js",
|
7 |
+
"scripts": {
|
8 |
+
"start": "node server.js"
|
9 |
+
},
|
10 |
+
"dependencies": {
|
11 |
+
"express": "^4.18.2",
|
12 |
+
"fs": "^0.0.1-security",
|
13 |
+
"axios": "^1.4.0",
|
14 |
+
"body-parser": "^1.20.2"
|
15 |
+
}
|
16 |
+
}
|
server.js
ADDED
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
const express = require('express');
|
2 |
+
const bodyparser = require('body-parser');
|
3 |
+
const txt2image = require("./txt2images")
|
4 |
+
const fs = require('fs'); //引入fs模块
|
5 |
+
|
6 |
+
// Constants
|
7 |
+
const PORT = 7860;
|
8 |
+
const HOST = '0.0.0.0';
|
9 |
+
|
10 |
+
// App
|
11 |
+
const app = express();
|
12 |
+
app.use(bodyparser.urlencoded({ extended: true }))
|
13 |
+
app.post("/txt2pic", async (req, res) => {
|
14 |
+
var prompt = req.body.prompt;
|
15 |
+
var size = req.body.size;
|
16 |
+
var url = await txt2image.txt2img(prompt, size)
|
17 |
+
res.send(url)
|
18 |
+
})
|
19 |
+
app.get('/', (req, res) => {
|
20 |
+
res.writeHead(200, { 'Content-Type': 'text/html' })
|
21 |
+
var html = fs.readFileSync(__dirname + '/static/index.html', 'utf-8'); //读取html文件,__dirname表示当前文件所在的目录路径
|
22 |
+
res.end(html);
|
23 |
+
});
|
24 |
+
app.get('/jquery', (req, res) => {
|
25 |
+
res.writeHead(200, { "Content-Type": "application/javascript" })
|
26 |
+
var js = fs.readFileSync(__dirname + '/static/jquery.js', 'utf-8'); //读取jquery文件,__dirname表示当前文件所在的目录路径
|
27 |
+
res.end(js);
|
28 |
+
});
|
29 |
+
|
30 |
+
app.listen(PORT, HOST, () => {
|
31 |
+
if (HOST == '0.0.0.0') {
|
32 |
+
console.log(`Running on http://127.0.0.1:${PORT}`);
|
33 |
+
} else {
|
34 |
+
console.log(`Running on http://${HOST}:${PORT}`);
|
35 |
+
}
|
36 |
+
|
37 |
+
});
|
static/index.html
ADDED
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html>
|
2 |
+
<html>
|
3 |
+
|
4 |
+
<head>
|
5 |
+
<meta charset="utf-8">
|
6 |
+
<meta name="viewport" content="width=device-width,user-scalable=no,initial-scale=1">
|
7 |
+
<title></title>
|
8 |
+
<script src="./jquery">
|
9 |
+
|
10 |
+
</script>
|
11 |
+
<script>
|
12 |
+
function txt2images() {
|
13 |
+
var size = $("#size").val();
|
14 |
+
body = {
|
15 |
+
"prompt": $("#input").val(),
|
16 |
+
"size": size
|
17 |
+
}
|
18 |
+
var qq = "";
|
19 |
+
$.ajax({
|
20 |
+
url: './txt2pic',
|
21 |
+
data: body,
|
22 |
+
type: 'post',
|
23 |
+
async: false,
|
24 |
+
success: function(data, textStatus, jqXHR) {
|
25 |
+
$("#show").attr("src", data);
|
26 |
+
}
|
27 |
+
})
|
28 |
+
}
|
29 |
+
</script>
|
30 |
+
</head>
|
31 |
+
|
32 |
+
<body>
|
33 |
+
<table>
|
34 |
+
<tr>
|
35 |
+
<td>输入提示词:</td>
|
36 |
+
<td colspan="2"><textarea rows="5" cols="60" id="input">汽车</textarea></td>
|
37 |
+
</tr>
|
38 |
+
<tr>
|
39 |
+
<td>选择尺寸:</td>
|
40 |
+
<td><select id="size">
|
41 |
+
<option>2560x1440</option>
|
42 |
+
<option>1024x1024</option>
|
43 |
+
<option>512x512</option>
|
44 |
+
<option selected>256x256</option>
|
45 |
+
</select>提交之后等待几秒出图</td>
|
46 |
+
<td>
|
47 |
+
<button value="提交" onclick="txt2images()">提交</button>
|
48 |
+
</td>
|
49 |
+
</tr>
|
50 |
+
<tr>
|
51 |
+
<td colspan="4"><img id="show" height="512" width="512" /></td>
|
52 |
+
|
53 |
+
</tr>
|
54 |
+
</table>
|
55 |
+
</body>
|
56 |
+
|
57 |
+
</html>
|
static/jquery.js
ADDED
The diff for this file is too large to render.
See raw diff
|
|
txt2images.js
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
const axios = require('axios')
|
2 |
+
api_base = process.env.OPENAI_API_BASE;
|
3 |
+
api_key = process.env.OPENAI_API_KEY;
|
4 |
+
api_version = '2023-06-01-preview'
|
5 |
+
url = api_base + "openai/images/generations:submit?api-version=" + api_version
|
6 |
+
headers = { "api-key": api_key, "Content-Type": "application/json" }
|
7 |
+
|
8 |
+
function sleep(ms) {
|
9 |
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
10 |
+
}
|
11 |
+
async function txt2images(prompt,size) {
|
12 |
+
body = {
|
13 |
+
"prompt": prompt,
|
14 |
+
"size": size,
|
15 |
+
"n": 1
|
16 |
+
}
|
17 |
+
submission = await axios.post(url, body, { headers });
|
18 |
+
operation_location = submission.headers['operation-location'];
|
19 |
+
status = "";
|
20 |
+
while (status != "succeeded") {
|
21 |
+
await sleep(1000);
|
22 |
+
res = await axios.get(operation_location, { headers });
|
23 |
+
status = res.data.status;
|
24 |
+
console.log(status)
|
25 |
+
if (status == "succeeded") {
|
26 |
+
return res.data.result.data[0].url;
|
27 |
+
}
|
28 |
+
}
|
29 |
+
}
|
30 |
+
exports.txt2img = txt2images;
|