用ChatGPT+Copilot一小时开发一套监控系统

套娃:我把下面的内容全部复制给了ChatGPT,让它帮我总结本文内容,它的回答如下:

本文介绍了人工智能ChatGPT在快速生成代码方面的应用,以及当前AI从专业客户走向大众、从特定领域走向通用领域、从后台走向前台和人的直接交互等趋势。文中展示了一些场景下AI助手的应用案例,包括辅助查找视频资料、整理出视频摘要、使用微软的new Bing快速获取高精度内容等。随后,介绍了通过ChatGPT生成程序的方法,包括编写截屏程序和编写fastapi服务。最后,文中针对问题进行了详细的解答。

背景

从去年ChatGPT上线开始就时不时的把玩,不经感叹划时代的通用AI真的就这么诞生了!它的功能实在是太强大了,配合一些工具、准确恰当的提问,真的可以帮你巨大的提升效率。

  • 这次通过ChatGPT,快速生成了适用于三个程序,虽然功能很简单,但是通过对话,它能很好的帮你生成需要的功能的代码
  • 有了代码,接着就是检查错误,修改参数
  • 配合Copilot,原本100行代码假设需要100分钟,现在一半以上的场景可能只需要按一下Tab键,效率简直炸裂!

介于下面都是问题和代码,先草草来两句总结:

  • 目前AI正在从专业客户走向大众,从特定领域走向通用领域,从后台走向前台和人的直接交互
  • 最近市面上涌现出了多个可用的、效果惊人的AI应用,举个例子:AI向我介绍了一些咨询,我根据咨询查找了一些视频资料,但是视频太长我没时间看,所以将链接发给了AI,AI帮我整理出了summary,summary太长,AI帮我精简出了要点,然后如果有问题的话,AI会根据里面的内容回答我。
  • 微软的new Bing是搜索进化后的新形态
  • 原本人们沉浸在海量内容中,但是有人会困惑于如何快速获取高精度内容,现在有了答案
  • 现在的场景是:顶级AI助手

效果图:

绿色的按钮是设备名称,点击按钮可以弹窗显示缩略图对应的原图

话不多说,先来看一下需求和设计的功能:

事前准备

问ChatGPT的问题

①写终端的截屏程序

问题:

帮我用python写一个程序。该程序可以每隔5分钟截取windows桌面的图片,并通过post方法传输出去。

补充问题:

  1. 根据这个生产截屏的python程序,再重写一下fastapi的服务
  2. 帮我根据上面的upload_image接口改造对应的一开始截屏程序的请求参数
import time
import requests
from PIL import ImageGrab
import socket
from datetime import datetime

hostname = socket.gethostname()

while True:
    # 截屏
    img = ImageGrab.grab()  # 截取屏幕截图
    img.save('screenshot.png')  # 将截图保存到本地

    data = {
            'name': hostname,
            'updateTime': datetime.now().strftime('-%m%d-%H%M')
            }
    files = {'image': (open('screenshot.png', 'rb'))}
    # 发送 POST 请求
    url = 'http://localhost:8000/upload_image'
    response = requests.post(url, data=data, files=files)

    # 处理响应
    if response.status_code == 200:
        print('Image uploaded successfully!')
    else:
        print('Failed to upload image.')
        # 休眠 5 分钟
    time.sleep(300)
②写服务端

问题:

然后再用fastapi写一个服务。首先我有一个配置文件,用来管理几十台设备,这个配置文件里含有每台设备的name。然后构建一个post接口,用来接收post请求,接收的内容是一张图片,接收成功后将图片保存到本地的capture文件夹中,并将图片再生成一张宽度为400的缩略图,保持宽高比不变。再构建一个get接口,当接收到get请求后,将capture文件夹下所有的缩略图返回。最后再构建一个get接口,请求参数是name,capture下图片文件名是name的原始图片返回。

补充问题:

  1. /get_images这个接口是返回所有的缩略图文件,帮忙改一下
  2. 请将/get_image/{name} 路由改为使用base64.b64encode将图片文件转换成Base64编码的字符串
  3. /get_images这个接口改为返回图片,而不是图片名称
  4. 帮我再补一段python代码,判断capture目录下是否有相同name的图片,如果有的话删除
import base64
from fastapi import FastAPI, File, Form, UploadFile
from fastapi.responses import FileResponse
import os
import time
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from pathlib import Path


app = FastAPI()

# 2、声明一个 源 列表;重点:要包含跨域的客户端 源
origins = ["*", "./*"]

# 3、配置 CORSMiddleware
app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,  # 允许访问的源
    allow_credentials=True,  # 支持 cookie
    allow_methods=["*"],  # 允许使用的请求方法
    allow_headers=["*"]  # 允许携带的 Headers
)


def delete_if_exist(name):
    folder_path = "./capture"
    for file_name in os.listdir(folder_path):
        if file_name.startswith(name):
            file_path = os.path.join(folder_path, file_name)
            os.remove(file_path)


@app.post("/upload_image")
async def upload_image(image: UploadFile = File(...), name: str = Form(...), updateTime: str = Form(...)):
    # save the original image to the capture folder
    file_path = f"./capture/{name}{updateTime}.png"
    delete_if_exist(name)
    with open(file_path, "wb") as f:
        f.write(await image.read())

    # generate thumbnail
    from PIL import Image
    img = Image.open(file_path)
    width, height = img.size
    thumbnail_size = (400, int(height * 400 / width))
    img.thumbnail(thumbnail_size)
    thumbnail_path = f"./capture/{name}{updateTime}_thumbnail.png"
    img.save(thumbnail_path)

    return {"message": "Image uploaded successfully!"}


@app.get("/get_images")
async def get_images():
    thumbnail_folder = Path("capture")
    thumbnail_files = thumbnail_folder.glob("*_thumbnail.png")
    images = []
    for thumbnail_file in thumbnail_files:
        with open(thumbnail_file, "rb") as f:
            thumbnail = base64.b64encode(f.read()).decode("utf-8")
            image_name = thumbnail_file.stem.replace("_thumbnail", "")
            images.append({"name": image_name, "thumbnail": thumbnail})
    return JSONResponse(content=images)


@app.get("/get_image/{name}")
def get_image(name: str):
    # print(f"capture/{name}.png")
    with open(f"capture/{name}.png", "rb") as f:
        image_bytes = f.read()
    base64_bytes = base64.b64encode(image_bytes)
    base64_string = base64_bytes.decode("utf-8")
    return {"image": base64_string}


③写用户端

问题:

接着我要用html写一个静态页面,该页面使用Materialize这个样式库。整个页面每隔5分钟请求上面的get_images接口获取所有的缩略图,和每个缩略图的名称,将这些图片放到页面上的grid里,整个grid每行有6格,每个格子里上面有一行标题代表缩略图的名称,下面显示缩略图。如果点击缩略图的话,请求上面的/get_image/{name}接口,获取原图,然后弹窗显示

补充问题:

  1. 再将JavaScript的showImage方法改一下
<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>j截屏展示窗</title>
    <!-- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css"> -->
    <link rel="stylesheet" href="materialize/css/materialize.min.css">
    <style>
        .modal {
            width: 95%;
            height: 100%;
        }
    </style>
</head>

<body>
    <div class="container">
        <!-- <h3>Image Gallery</h3> -->
        <div class="row" id="grid"></div>
    </div>

    <div id="modal" class="modal">
        <div class="modal-content" id="modal-content"></div>
        <!-- <div class="modal-footer">
        <a href="#!" class="modal-close waves-effect waves-green btn-flat">Close</a>
      </div> -->
    </div>

    <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
    <script src="materialize/js/materialize.min.js"></script>
    <!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script> -->
    <script>
        function showImage(name) {
            fetch(`http://localhost:8000/get_image/${name}`)
                .then(response => response.json())
                .then(data => {
                    var image = document.createElement('img');
                    image.src = "data:image/jpeg;base64," + data.image;
                    var modalContent = document.getElementById("modal-content");
                    modalContent.innerHTML = '';
                    modalContent.appendChild(image);
                    var modalInstance = M.Modal.getInstance(document.getElementById("modal"));
                    modalInstance.open();
                });
        }

        function updateGrid() {
            fetch('http://localhost:8000/get_images')
                .then(response => response.json())
                .then(data => {
                    var images = data;
                    var grid = document.getElementById('grid');
                    grid.innerHTML = '';

                    for (var i = 0; i < images.length; i++) {
                        var image = images[i];
                        var col = document.createElement('div');
                        col.classList.add('col', 's12', 'm6', 'l3');

                        var card = document.createElement('div');
                        card.classList.add('card', 'hoverable');

                        var cardImage = document.createElement('div');
                        cardImage.classList.add('card-image');
                        var title = document.createElement('span');
                        title.classList.add('card-title');
                        title.innerText = image.name;
                        var thumbnail = document.createElement('img');
                        thumbnail.classList.add('thumbnail');
                        thumbnail.src = "data:image/jpeg;base64," + image.thumbnail;
                        cardImage.appendChild(title);
                        cardImage.appendChild(thumbnail);
                        card.appendChild(cardImage);

                        var cardAction = document.createElement('div');
                        cardAction.classList.add('card-action');
                        cardAction.style.textAlign = 'center';
                        var link = document.createElement('a');
                        link.classList.add('waves-effect', 'waves-light', 'btn');
                        link.innerText = image.name;
                        link.onclick = (function (name) {
                            return function () {
                                showImage(name);
                            };
                        })(image.name);
                        cardAction.appendChild(link);
                        card.appendChild(cardAction);

                        col.appendChild(card);
                        grid.appendChild(col);
                    }
                });
        }

        $(document).ready(function () {
            $('.modal').modal();
            setInterval(updateGrid, 5000);
            updateGrid();
        });
    </script>
</body>

</html>

Done!

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
社会演员多的头像社会演员多普通用户
上一篇 2023年4月5日 下午8:53
下一篇 2023年4月5日

相关推荐