我已经多年没有从事开发工作了,现在重新开始,我的技能有些生疏,提前为任何不当的语法和格式问题道歉。
我目前正在开发一个小型网络应用项目,该项目通过文本提示使用谷歌的aivertex和gemini生成图像。
以下是一些代码片段供审阅。
HTML模板
<body> <h1>将你的文字变成艺术!</h1> <p>输入你想要生成的图像的描述。</p> <form target="_blank" id="text-form" action="/my_prompt" onsubmit="dontredict('myindex.html')" method="post"> <label for="text-input">文本提示:</label> <textarea id="text-input" name="text" rows="5" placeholder="例如:一只猫在火星上骑自行车"></textarea> <button type="submit">生成图像</button> </form> <div id="image-container"> {% if img_data %} <h1>你的生成图像将在这里显示。</h1> <img id="picture" style="height: 300px;" src="{{url_for('static',filename='my-output.png')}}"> {% else %} <h1>图像将在这里渲染...</h1> {% endif %} </div> <!--Jquery Cdn --> <script src="https://code.jquery.com/jquery-3.5.1.js" integrity="sha256-QWo7LDvxbWT2tbbQ97B53yJnYU3WhH/C8ycbRAkjPDc=" crossorigin="anonymous"></script> <script type="text/javascript"> function dontredict(dynamicUrl){ $(document).on('submit', '#text-form', function (e) { e.preventDefault(); console.log('button smashed'); $.ajax({ type: 'POST', url: '/my_prompt', data: { text: $("#text-input").val() }, success: function () { alert('saved'); } }) }); } </script></body>
Python text-to-image.py
def disp_image(): if os.path.exists(output_file): im = Image.open("static/my-output.png") data = io.BytesIO() im.save(data, "PNG") encoded_img_data = base64.b64encode(data.getvalue()) img_data=encoded_img_data.decode('utf-8') return render_template("myindex.html", img_data=img_data) #if os.path.exists(output_file): #return redirect(url_for('static/my-output.png'))@app.route('/my_prompt', methods = ['POST'])@cross_origin()def imggen(): print("inside gen") if request.method == 'POST': prompt = request.form.get("text") logger.info('%s This is the prompt: ', prompt) print(prompt); print("after prompt") model = ImageGenerationModel.from_pretrained("imagegeneration@006") images = model.generate_images( prompt=prompt, # Optional parameters number_of_images=1, language="en", # You can't use a seed value and watermark at the same time. # add_watermark=False, # seed=100, aspect_ratio="1:1", safety_filter_level="block_some", person_generation="allow_adult", ) images[0].save(location=output_file, include_generation_parameters=False) print(f"Created output image using {len(images[0]._image_bytes)} bytes") print(disp_image()) return disp_image() else: print("error")
我遇到的问题是,当文本被提交并返回生成的图像时,图像会正确保存到静态图像文件夹中(使用flask和python),但是它不会显示或渲染到HTML页面上。我也知道一些代码可能是多余的。请告诉我我在显示图像到实际HTML页面方面做错了什么,谢谢。
回答:
当你使用 $.ajax
(或内置的现代 fetch()
或旧的 XMLHttpRequest()
)时,浏览器不会更新HTML。这是你的工作。你可以决定何时以及如何更新页面内容。
在 success()
中,你需要从 flask
获取响应,并添加或替换 HTML
内容
但首先:你不需要发送整个页面,只需发送部分内容 – 如 <h1>
和 <img>
。你可以使用 render_template_string()
来实现这一点。
def disp_image(): # ... 代码 ... return render_template_string(''' <h1>你的生成图像将在这里显示。</h1><img id="picture" style="height: 300px;" src="{{url_for('static',filename='my-output.png')}}">''')
然后你可以只替换 <div id="image-container">
内的内容
$.ajax( // ... 代码 ... success: function(response_data) { $('#image-container').html(response_data); alert('saved'); })
因为浏览器可能不会重新加载图像,如果图像始终使用相同的名称 – 因为它不知道你是否保存了新图像但使用了相同的名称 – 所以你可以将图像作为 base64
发送到 src="..."
def disp_image(): # ... 代码 ... img_data = encoded_img_data.decode('utf-8') return render_template_string(''' <h1>你的生成图像将在这里显示。</h1><img id="picture" style="height: 300px;" src="data:image/png;base64, {{base64_image}}">''', base64_image=img_data)
顺便说一下:在 data:image/png;base64,
之后有一个空格
当然,你也可以只发送 base64_image
– 例如作为 JSON
– 然后JavaScript可以获取它并只替换 src="..."
(如果它已经存在于页面上)
from flask import jsonify def disp_image(): # ... 代码 ... img_data = encoded_img_data.decode('utf-8') return jsonify({'base64_image': img_data})
success: function(response_data) { var json = $.parseJSON(response_data); var image = json.base64_image; $('#picture').attr('src', 'data:image/png;base64, ' + image); alert('saved');}
完整的工作代码 – 包含两个版本:
- 一个发送包含
h1
和img
的HTML - 另一个发送包含base64的JSON,并在JavaScript中创建
img
两者都使用 PIL.Image
生成带文本的图像
import osfrom flask import Flask, request, render_template_stringfrom PIL import Image, ImageDraw, ImageFontimport ioimport base64os.makedirs('static', exist_ok=True)app = Flask(__name__)@app.route('/')def index(): return render_template_string('''<!DOCTYPE html><html><head> <meta charset="utf-8"> <script src="https://code.jquery.com/jquery-3.5.1.js" integrity="sha256-QWo7LDvxbWT2tbbQ97B53yJnYU3WhH/C8ycbRAkjPDc=" crossorigin="anonymous"></script> </head><body><form target="_blank" id="text-form" action="/my_prompt" method="POST"> <textarea id="text-input" name="text" rows="5" placeholder="例如:一只猫在火星上骑自行车"></textarea></br> <button type="submit">生成图像</button></form><form target="_blank" id="text-form-json" action="/my_prompt_json" method="POST"> <textarea id="text-input-json" name="text" rows="5" placeholder="例如:一只猫在火星上骑自行车"></textarea></br> <button type="submit">生成图像</button></form><div id="image-container"><h1>无图像</h1></div><script type="text/javascript">$(document).on('submit', '#text-form', function (e) { e.preventDefault(); console.log('button smashed'); $.ajax({ type: 'POST', url: '/my_prompt', data: { text: $("#text-input").val() }, success: function(response_data) { $('#image-container').html(response_data); } })});$(document).on('submit', '#text-form-json', function (e) { e.preventDefault(); console.log('button smashed JSON'); $.ajax({ type: 'POST', url: '/my_prompt_json', data: { text: $("#text-input-json").val() }, success: function(response_data) { picture = $('#picture'); if(picture.length === 0) { picture = $('<img id="picture" style="height: 300px;">'); } picture.attr('src', 'data:image/png;base64, ' + response_data.base64_image); $('#image-container').html(picture); } })});</script></body></html>''')def disp_image(): img = Image.open("static/my-output.png") data = io.BytesIO() img.save(data, 'PNG') encoded_img_data = base64.b64encode(data.getvalue()) img_data=encoded_img_data.decode('utf-8') return render_template_string(''' <h1>你的生成图像将在这里显示。</h1><img id="picture" style="height: 300px;" src="data:image/png;base64, {{base64_image}}">''', base64_image=img_data)from flask import jsonify def disp_image_json(): img = Image.open("static/my-output.png") data = io.BytesIO() img.save(data, 'PNG') encoded_img_data = base64.b64encode(data.getvalue()) img_data=encoded_img_data.decode('utf-8') return jsonify({'base64_image': img_data})@app.route('/my_prompt', methods=['POST'])def image(): if request.method == "POST": text = request.form.get('text', '???') print('text:', text) img = Image.new('RGB', (600, 300)) draw = ImageDraw.Draw(img) font = ImageFont.truetype("arial.ttf", size=40) draw.text((10, 10), text, font=font, fill=(255, 255, 255)) img.save('static/my-output.png') return disp_image()@app.route('/my_prompt_json', methods=['POST'])def image_json(): if request.method == "POST": text = request.form.get('text', '???') print('text:', text) img = Image.new('RGB', (600, 300)) draw = ImageDraw.Draw(img) font = ImageFont.truetype("arial.ttf", size=40) draw.text((10, 10), text, font=font, fill=(255, 255, 255)) img.save('static/my-output.png') return disp_image_json()if __name__ == '__main__': app.debug = True app.run()