小白用Claude3.5出海赚美金!| AI写代码建AI工具出海网站进阶教程
点击查看油管视频教程
常见踩坑点
- 如果卡在npx create-next-app@latest的朋友,你可以去你的代理工具里找下你的http:XXX(比如10809) 是多少。
- Windows电脑的话VSCode命名行输入,注意那个10809替换成你实际的数字!
$env:http_proxy = "http://127.0.0.1:10809"
回车后再输入
$env:https_proxy = "http://127.0.0.1:10809"
- mac电脑VSCode命令行输入,注意那个10809替换成你实际的数字!
export http_proxy=http://127.0.0.1:10809
回车后再输入
export https_proxy=http://127.0.0.1:10809
- windows系统安装node完成之后,可能报错no such file or directory,这时候你需要在日志提示的目录新建一个npm文件夹即可(是在类似C:\Users\andy\AppData\Roaming下创建npm文件夹)
- 无法提交代码到GitHub,注意那个10809替换成你实际的数字!
git config --global http.proxy http://127.0.0.1:10809
git config --global https.proxy http://127.0.0.1:10809
- 苹果电脑可能会遇到当前账户权限不足,出现类似npm error code EACCES npm error syscall rename npm error path /usr/local/lib/node_modules/npm npm error dest /usr/local/lib/node_modules/.npm-i9nnxROI npm error errno -13的报错。
解决方案:命令行输入下面命名,然后输入密码(密码看不见的),输入完成后回车即可对这个目录进行读取、写入和执行操作
sudo chown -R $(whoami) /usr/local/lib/node_modules
前言
大家好,我是想要教不会写代码的小白用AI做AI工具出海赚美金的Andy!这是这个系列的第3个视频。
第1个视频是30分钟建个AI工具网站,带大家快速感受下AI写代码的流程,我们用Claude3.5做了一个游戏道具生成器的网站 放个截图感受下(主要功能是输入道具名称、选择道具等级等。让AI给你输出一个游戏道具贴图)
有观众看了我的视频之后给我分享感受,按照视频操作自己也做了个,欢迎大家感兴趣的可以去看看~
第2个视频是分享如何注册claude3.5账号以及如何防封号,感兴趣可以去看看。
这里也分享下我的AI出海工具网站的进展,目前已经有几笔订阅订单(连续包月),虽然不是很多,但是在慢慢变好。
看完这个视频你的收获
希望你已经看了第1个视频,里面讲了如何安装必要的软件。这个视频就不再赘述了。
- 学会用Claude3.5搭建一个AI壁纸生成网站
- 调用SD3接口
- 生成前后端代码
- 部署上线分享给你的朋友去体验
教程开始
- 产品设计
这期我们要来做一个AI壁纸生成器,顾名思义就用户可以输入自己想要的内容,然后选择不同的风格。选择好后,进行图片生成,最终展示给用户。
- 用户输入想要的内容,比如雪山、湖泊、草原、星空
- 用户选择想要的风格,比如写实、动漫
- 用户选择想要的分辨率,比如9:16适合手机、16:9适合电脑
- 点击按钮后进行生成,生成后的图片支持下载
- 交互原理
- 使用next.js框架让AI写前后端代码
- 后端构造好prompt, 请求SD3接口
- 返回图片供用户进行下载
- 给AI提需求
打开Claude网站网站地址,先不急着提需求。
如果没claude账户可以看我这个视频
- 先下载前端框架
进入VSCode后,新建一个文件夹,然后打开终端输入(这步卡住了请看本文章置顶内容)
npx create-next-app@latest
继续进入对应的文件夹
cd wallpaper
然后启动项目
npm run dev
- 提需求的prompt
我有一个nextjs项目,是app路由、tailwindcss、typescript语法。我现在想要做一个AI壁纸生成器,调用stable diffusion3的接口,我现在在本地windows电脑进行调试,之后会部署到vercel上。
1、前端页面可以输入内容框、选择对应的风格(动漫、写实风格等,你需要提前写好每种风格的prompt和用户输入内容构造一个完整的prompt)、生成之后可以看到对应图片
2、我的前端代码路径是wallpaper/app/page.tsx,后端路径是wallpaper/app/api/wallpaper/route.ts
3、SD3的官方接口规范是:
import fs from "node:fs";
import axios from "axios";
import FormData from "form-data";
const payload = {
prompt: "Lighthouse on a cliff overlooking the ocean",
output_format: "jpeg"
};
const response = await axios.postForm(
`https://api.stability.ai/v2beta/stable-image/generate/sd3`,
axios.toFormData(payload, new FormData()),
{
validateStatus: undefined,
responseType: "arraybuffer",
headers: {
Authorization: `Bearer sk-MYAPIKEY`,
Accept: "image/*"
},
},
);
if(response.status === 200) {
fs.writeFileSync("./lighthouse.jpeg", Buffer.from(response.data));
} else {
throw new Error(`${response.status}: ${response.data.toString()}`);
}
现在给我完整代码
stability官网地址,访问后查看接口示例代码
app\page.tsx代码
'use client';
import { useState } from 'react';
import axios from 'axios';
const styles = [
{ name: '动漫', prompt: 'anime style, vibrant colors, detailed' },
{ name: '写实', prompt: 'photorealistic, highly detailed, natural lighting' },
{ name: '油画', prompt: 'oil painting style, textured, rich colors' },
{ name: '水彩', prompt: 'watercolor style, soft edges, pastel colors' },
];
export default function Home() {
const [content, setContent] = useState('');
const [style, setStyle] = useState(styles[0]);
const [image, setImage] = useState('');
const [loading, setLoading] = useState(false);
const generateWallpaper = async () => {
setLoading(true);
try {
const response = await axios.post('/api/wallpaper', {
content,
style: style.prompt,
}, {
responseType: 'arraybuffer',
});
const base64 = Buffer.from(response.data, 'binary').toString('base64');
setImage(`data:image/jpeg;base64,${base64}`);
} catch (error) {
console.error('Error generating wallpaper:', error);
alert('生成壁纸时出错,请重试。');
}
setLoading(false);
};
return (
<div className="min-h-screen bg-gray-100 py-6 flex flex-col justify-center sm:py-12">
<div className="relative py-3 sm:max-w-xl sm:mx-auto">
<div className="absolute inset-0 bg-gradient-to-r from-cyan-400 to-light-blue-500 shadow-lg transform -skew-y-6 sm:skew-y-0 sm:-rotate-6 sm:rounded-3xl"></div>
<div className="relative px-4 py-10 bg-white shadow-lg sm:rounded-3xl sm:p-20">
<div className="max-w-md mx-auto">
<h1 className="text-2xl font-semibold mb-6">AI壁纸生成器</h1>
<input
type="text"
value={content}
onChange={(e) => setContent(e.target.value)}
placeholder="输入壁纸描述"
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-cyan-500"
/>
<select
value={style.name}
onChange={(e) => setStyle(styles.find(s => s.name === e.target.value) || styles[0])}
className="w-full mt-4 px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-cyan-500"
>
{styles.map((s) => (
<option key={s.name} value={s.name}>{s.name}</option>
))}
</select>
<button
onClick={generateWallpaper}
disabled={loading}
className="w-full mt-4 bg-cyan-500 text-white py-2 px-4 rounded-md hover:bg-cyan-600 focus:outline-none focus:ring-2 focus:ring-cyan-500 focus:ring-opacity-50"
>
{loading ? '生成中...' : '生成壁纸'}
</button>
{image && (
<div className="mt-6">
<img src={image} alt="Generated Wallpaper" className="w-full rounded-md shadow-lg" />
</div>
)}
</div>
</div>
</div>
</div>
);
}
route.ts代码
import { NextRequest, NextResponse } from 'next/server';
import axios from 'axios';
import FormData from 'form-data';
import https from 'https';
export async function POST(req: NextRequest) {
try {
const { content, style } = await req.json();
const payload = {
prompt: `${content}, ${style}`,
output_format: 'jpeg',
};
const httpsAgent = new https.Agent({
rejectUnauthorized: false // 注意:这可能会降低安全性,仅用于调试
});
const response = await axios.postForm(
`https://api.stability.ai/v2beta/stable-image/generate/sd3`,
axios.toFormData(payload, new FormData()),
{
validateStatus: undefined,
responseType: 'arraybuffer',
headers: {
Authorization: `Bearer ${process.env.STABILITY_API_KEY}`,
Accept: 'image/*',
},
httpsAgent: httpsAgent,
proxy: false,
}
);
if (response.status === 200) {
return new NextResponse(response.data, {
status: 200,
headers: {
'Content-Type': 'image/jpeg',
},
});
} else {
console.error('API response:', response.status, response.data.toString());
throw new Error(`${response.status}: ${response.data.toString()}`);
}
} catch (error) {
console.error('Error generating wallpaper:', error);
if (axios.isAxiosError(error)) {
console.error('Axios error details:', {
response: error.response?.data,
status: error.response?.status,
headers: error.response?.headers,
});
}
return NextResponse.json({ error: 'Failed to generate wallpaper' }, { status: 500 });
}
}
- 注册GitHub 安装视频流程注册后,VSCode配置邮箱和用户名
# 设置全局用户名
git config --global user.name "你的名字"
# 设置全局邮箱
git config --global user.email "你的邮箱@example.com"
- Vercel部署
记得添加环境变量