### 生成AI图像后,图像未在响应完成后渲染

我已经多年没有从事开发工作了,现在重新开始,我的技能有些生疏,提前为任何不当的语法和格式问题道歉。

我目前正在开发一个小型网络应用项目,该项目通过文本提示使用谷歌的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');}    

完整的工作代码 – 包含两个版本:

  • 一个发送包含 h1img 的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()

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注