基于截图页面生成前端项目

news2024/11/14 20:47:44

前两天,在群里看见一个视频,视频中,作者截图twitter首页,然后使用截图直接生成与截图布局非常相近的前端项目,效果还是比较惊艳的。

今天陪老婆回老家,路上clone这个项目的代码到本地,学习了一下,整体还是很直观的。

项目github:https://github.com/abi/screenshot-to-code

进入项目,就可以看见它的README.md中给出的效果,因为视频号放视频很麻烦,就截图示意一下。

0c032b7453b539408fb04c1f6c4d4c60.png

本文主要是学习一下作者是怎么实现截图到相似布局这个核心功能的,当然看完后,我也学到一些其他编程技巧,一同记录一下。

截图到布局的核心逻辑

一句话总结:使用gpt-4-vision-preview识别图片并配合提示词,直接让GPT4生成相应的HTML代码。

项目分为frontend和backend,frontend最核心的就是将你的截图转成base64字符串然后通过websocket发送给backend接口。

frontend是react+tailwindcss来开发的,海外很多人都用这套(我现在也用这套为主),核心代码如下:

// src/generateCode.ts

// 生成代码
export function generateCode(
  params: CodeGenerationParams,
  onChange: (chunk: string) => void,
  onSetCode: (code: string) => void,
  onStatusUpdate: (status: string) => void,
  onComplete: () => void
) {
  const wsUrl = `${WS_BACKEND_URL}/generate-code`;
  console.log("Connecting to backend @ ", wsUrl);

  // 实例化 websocket 对象
  const ws = new WebSocket(wsUrl);

  // 建立 websocket 连接
  ws.addEventListener("open", () => {
    ws.send(JSON.stringify(params));
  });

  // 接受 websocket 信息
  ws.addEventListener("message", async (event: MessageEvent) => {
    const response = JSON.parse(event.data);
    if (response.type === "chunk") {
      onChange(response.value);
    } else if (response.type === "status") {
      onStatusUpdate(response.value);
    } else if (response.type === "setCode") {
      // 接受到后端生成的代码,设置到setCode变量中(setCode会被实时展示出来)
      onSetCode(response.value);
    } else if (response.type === "error") {
      console.error("Error generating code", response.value);
      toast.error(response.value);
    }
  });
  
 // websocket 关闭
  ws.addEventListener("close", (event) => {
    console.log("Connection closed", event.code, event.reason);
    if (event.code != 1000) {
      console.error("WebSocket error code", event);
      toast.error(ERROR_MESSAGE);
    } else {
      onComplete();
    }
  });

  ws.addEventListener("error", (error) => {
    console.error("WebSocket error", error);
    toast.error(ERROR_MESSAGE);
  });
}

backend使用fastapi构建的,通过@app.websocket("/generate-code")就可以构建出支持websocket的api接口了,非常方便。

当backend收到图片的base64后,会使用gpt-4-vision来进行代码生成,vision相关的用法请自行看文档:https://platform.openai.com/docs/guides/vision

在这个项目中,提示词如下:

def assemble_prompt(image_data_url):
    return [
        {"role": "system", "content": SYSTEM_PROMPT},
        {
            "role": "user",
            "content": [
                {
                    "type": "image_url",
                    "image_url": {"url": image_data_url, "detail": "high"},
                },
                {
                    "type": "text",
                    "text": USER_PROMPT,
                },
            ],
        },
    ]

其中,比较关键是SYSTEM_PROMPT,内容如下:

You are an expert Tailwind developer
You take screenshots of a reference web page from the user, and then build single page apps 
using Tailwind, HTML and JS.
You might also be given a screenshot of a web page that you have already built, and asked to
update it to look more like the reference image.

- Make sure the app looks exactly like the screenshot.
- Pay close attention to background color, text color, font size, font family, 
padding, margin, border, etc. Match the colors and sizes exactly.
- Use the exact text from the screenshot.
- Do not add comments in the code such as "<!-- Add other navigation links as needed -->" and "<!-- ... other news items ... -->" in place of writing the full code. WRITE THE FULL CODE.
- Repeat elements as needed to match the screenshot. For example, if there are 15 items, the code should have 15 items. DO NOT LEAVE comments like "<!-- Repeat for each news item -->" or bad things will happen.
- For images, use placeholder images from https://placehold.co and include a detailed description of the image in the alt text so that an image generation AI can generate the image later.

In terms of libraries,

- Use this script to include Tailwind: <script src="https://cdn.tailwindcss.com"></script>
- You can use Google Fonts
- Font Awesome for icons: <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css"></link>

Return only the full code in <html></html> tags.
Do not include markdown "```" or "```html" at the start or end.

这个提示词让GPT4成为Tailwind developer,然后通过用户提供的screenshots去生成代码,使用tailwind、HTML、JS来生成页面,然后强调了样式细节要尽量与图片相同,最后说了,如果要用Tailwind,需要引入的cdn url等。

就这个提示词,就可以生成图片了。

当然,这里还有一个技巧,就是页面中,需要有图片资源的地方,使用了https://placehold.co服务,我看这个服务,是专门用于展示默认图片的。

90c64122402760ff0f8a054b9a6cc78f.png

生成完code后,就通过BeautifulSoup将生成code中的img都提取出来,基于img中的alt作为新的提示词,使用DALL3去生成相关的图片,相关代码如下:

async def generate_image(prompt, api_key):
    client = AsyncOpenAI(api_key=api_key)
    image_params = {
        "model": "dall-e-3",
        "quality": "standard",
        "style": "natural",
        "n": 1,
        "size": "1024x1024",
        "prompt": prompt,
    }
    res = await client.images.generate(**image_params)
    return res.data[0].url

因为整个过程需要一定的时间,所以使用了websocket.send_json方法将进行在哪一步实时发送给frontend,从而让用户感知到程序还在正常执行。

await websocket.send_json({"type": "setCode", "value": updated_html})
await websocket.send_json(
    {"type": "status", "value": "Code generation complete."}
)

结尾

以上就是项目的核心了,只能说OPENAI的GPT4确实功能强大。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1228557.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

IDEA自动注解设置(中文版)

IDEA自动注解设置 1、添加类自动注释 文件 - 设置 - 编辑器 - 文件和代码模板 - Include - File Header /** *description&#xff1a;TODO *author&#xff1a; ${USER} *create&#xff1a; ${DATE} ${TIME} */2、添加类方法自动注释 文件 - 设置 - 编辑器 - 实时模版 - …

ARouter出现 there‘s no route matched in group问题排查

在使用ARouter时候会出现找不到映射路径的问题&#xff0c;这里给兄弟们总结下踩过的坑 所有用到的模块都要有填写依赖 android {defaultConfig {......javaCompileOptions {annotationProcessorOptions {arguments [AROUTER_MODULE_NAME: project.getName()]}}} } ... depe…

超详细~25考研规划~感恩现在努力的你!!!

25考研规划 俄语&#xff0c;翻译过来叫我爱你 考试时间 第一天 8.30-11.30政治——100分 2.00-5.00英语——100分 第二天 8.30-11.30数学——150分 2.00-5.00专业课——150分 1.什么是25考研 将在2024年12月参加考研&#xff0c;2025年本科毕业&#xff0c;9月读研究…

ANR问题分析的一般套路

目录 一.ANR初步了解1.发生原因2.ANR分类 二.ANR的Log解读1.Log获取2.案例一&#xff1a;sp耗时问题导致应用ANR 三.系统耗时分析方案1.binder_sample2.dvm_lock_sample3.binder starved4.案例二&#xff1a;疯狂Binder Call导致应用ANR5.案例三&#xff1a;广播超时导致App的A…

Django+Vue项目创建 跑通

参考链接&#xff1a; 【精选】DjangoVue项目构建_django vue-CSDN博客 一、背景 主要介绍如何使用后端Django 前端Vue 的技术栈快速地搭建起一套web项目的框架。 为什么使用Django和Vue? Django是Python体系下最成熟的web框架之一&#xff0c;由于Python语言的易用…

012 C++ AVL_tree

前言 本文将会向你介绍AVL平衡二叉搜索树的实现 引入AVL树 二叉搜索树虽可以缩短查找的效率&#xff0c;但如果数据有序或接近有序普通的二叉搜索树将退化为单支树&#xff0c;查找元素相当于在顺序表中搜索元素&#xff0c;效率低下。因此&#xff0c;两位俄罗斯的数学家G.M…

直流电机干扰的产生-EMC和EMI

直流电机干扰的产生-EMC和EMI 干扰的产生电路滤波处理EMC处理措施 干扰的产生 带电刷的电动机&#xff0c;由于在电刷切换时&#xff0c;电动机线圈中的电流不能突变&#xff0c;当一路线圈通电断开时&#xff0c;会在该线圈的两端产生较高的反电动势&#xff0c;这个电动势会…

2023.11.17使用flask将多个图片文件上传至服务器

2023.11.17使用flask将多个图片文件上传至服务器 实现功能&#xff1a; 1、同时上传多个图片文件 2、验证文件扩展名 3、显示上传文件的文件名 4、显示文件上传结果 程序结构 main.py from flask import Flask, request, jsonify, render_template import osapp Flask(__n…

vscode快捷键使用总结

&#xff09; 1、格式化选中的代码 1、格式化选中的代码 vscode中选中所要格式化的代码&#xff1a; ctrl k,ctrlf 其实可以查到该命令 ctrlshiftp打开命令窗口输入format

单片机实验(二)

前言 实验一&#xff1a;用AT89C51单片机控制LCD 1602&#xff0c;使其显示两行文字&#xff0c;分别显示自己的学号和姓名拼音。 实验二&#xff1a;设计一个中断嵌套程序。要求K1和K2都未按下时&#xff0c;单片机控制8只数码管&#xff0c;滚动输出完整的学号。当按一下K1…

中间件安全:Apache 目录穿透.(CVE-2021-41773)

中间件安全&#xff1a;Apache 目录穿透.&#xff08;CVE-2021-41773&#xff09; Apache 的 2.4.49、2.4.50 版本 对路径规范化所做的更改中存在一个路径穿越漏洞&#xff0c;攻击者可利用该漏洞读取到Web目录外的其他文件&#xff0c;如系统配置文件、网站源码等&#xff0c…

微服务调用链路追踪

概述 本文介绍微服务调用链路追踪&#xff0c;涉及技术有&#xff1a;sleuth和zipkin。sleuth负责追踪调用链路数据&#xff0c;zipkin负责调用链路数据可视化展现。 本文的操作是在 服务网关实践 的基础上进行。 环境说明 jdk1.8 maven3.6.3 mysql8 spring cloud2021.0.8 …

【开源】基于Vue.js的独居老人物资配送系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、系统展示四、核心代码4.1 查询社区4.2 新增物资4.3 查询物资4.4 查询物资配送4.5 新增物资配送 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpringBootMySQL的独居老人物资配送系统&#xff0c;包含了社区档案、…

Node.js之TCP(net)

Hi I’m Shendi Node.js之TCP&#xff08;net&#xff09; 最近使用Nodejs编写程序&#xff0c;需要用到自己编写的分布式工具&#xff0c;于是需要将Java版的用NodeJs重新写一遍&#xff0c;需要使用到TCP通信&#xff0c;于是在这里记录下Node.js TCP 的使用方法 依赖 需要使…

LRU最近最少使用算法

LRU(LeastRecentlyUsed)“最近最少使用”算法&#xff1a; 1.当缓存空间已满耗用时&#xff0c;淘汰最近最少使用数据的缓存对象以释放更多的缓存空间(用于历史缓存对象的维护)。 2. 哈希表:快速查找缓存对象&#xff1b;双向链表:维护 历史数据所在的节点顺序。 步骤&#xff…

T10 数据增强

文章目录 一、准备环境和数据1.环境2. 数据 二、数据增强&#xff08;增加数据集中样本的多样性&#xff09;三、将增强后的数据添加到模型中四、开始训练五、自定义增强函数六、一些增强函数 &#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f…

CSS的选择器(一篇文章齐全)

目录 Day26&#xff1a;CSS的选择器 1、CSS的引入方式 2、CSS的选择器 2.1 基本选择器​编辑 2.2 组合选择器 2.3 属性选择器 2.4 伪类选择器 2.5 样式继承 2.6 选择器优先级 3、CSS的属性操作 3.1 文本属性 3.2 背景属性 3.3 边框属性 3.4 列表属性 3.5 dispal…

Vue3+Vite实现工程化,事件绑定以及修饰符

我们可以使用v-on来监听DOM事件&#xff0c;并在事件触发时执行对应的Vue的Javascript代码。 用法&#xff1a;v-on:click "handler" 或简写为 click "handler"vue中的事件名原生事件名去掉 on 前缀 如:onClick --> clickhandler的值可以是方法事件…

Rust开发——切片(slice)类型

1、什么是切片 在 Rust 中&#xff0c;切片&#xff08;slice&#xff09;是一种基本类型和序列类型。在 Rust 官方文档中&#xff0c;切片被定义为“对连续序列的动态大小视图”。 但在rust的Github 源码中切片被定义如下&#xff1a; 切片是对一块内存的视图&#xff0c;表…

系列十一、你平时工作用过的JVM常用基本配置参数有哪些?

一、常用参数 1.1、-Xms 功能&#xff1a;初始内存大小&#xff0c;默认为物理内存的1/64&#xff0c;等价于 -XX:InitialHeapSize 1.2、-Xmx 功能&#xff1a;最大分配内存&#xff0c;默认为物理内存的1/4&#xff0c;等价于 -XX:MaxHeapSize 1.3、-Xss 功能&#xff1a;设置…