admin 发表于 2024-9-28 07:57:17

利用Cloudflare Workers每月免费额度,优化页面展示,实现1000次免费Stable Diffusion绘画。

利用借用佬的内容,改写了CF worker,现在可以直接在worker页面进行绘画。
// HTML content as a string
const htmlContent = `


   
   
    AI Art Generator
   
   
   
      body {
            font-family: 'Roboto', sans-serif;
            line-height: 1.6;
            color: #333;
            margin: 0;
            padding: 0;
            min-height: 100vh;
            background: linear-gradient(45deg, #6a11cb 0%, #2575fc 100%);
      }
      .container {
            max-width: 800px;
            margin: 1rem;
            padding: 1rem;
            background-color: rgba(255, 255, 255, 0.9);
            border-radius: 20px;
            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
      }
      h1 {
            font-family: 'Montserrat', sans-serif;
            color: #6a11cb;
            text-align: center;
            font-size: 2.5rem;
            margin-bottom: 2rem;
            text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.1);
      }
      form {
            display: grid;
      }
      label {
            font-weight: bold;
            color: #2575fc;
      }
      input,
      select,
      textarea {
            width: 100%;
            padding: 0.8rem;
            border: 2px solid #6a11cb;
            border-radius: 10px;
            font-size: 1rem;
            transition: all 0.3s ease;
      }
      textarea {
            width: calc(100% - 50px);
            padding-left: 35px;
            padding-right: 10px;
      }
      input:focus,
      select:focus,
      textarea:focus {
            outline: none;
            border-color: #2575fc;
            box-shadow: 0 0 0 2px rgba(37, 117, 252, 0.2);
      }
      button {
            background-color: #6a11cb;
            color: #fff;
            padding: 1rem 2rem;
            border: none;
            border-radius: 50px;
            cursor: pointer;
            font-size: 1.1rem;
            font-weight: bold;
            transition: all 0.3s ease;
            display: block;
            margin: 2rem auto 0;
      }
      button:hover {
            background-color: #2575fc;
            transform: translateY(-2px);
            box-shadow: 0 5px 15px rgba(37, 117, 252, 0.4);
      }
      #result {
            overflow: auto;
            width: 50%;
            height: 100vh;
            margin-top: 2rem;
            text-align: center;
      }
      #generatedImage {
            max-width: 100%;
            border-radius: 10px;
            box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
            transition: all 0.3s ease;
      }
      #generatedImage:hover {
            transform: scale(1.02);
      }
      @media (max-width: 600px) {
            .container {
                margin: 1rem;
                padding: 1rem;
            }
            h1 {
                font-size: 2rem;
            }
      }
      .input-icon {
            position: relative;
      }
      .input-icon i {
            position: absolute;
            left: 10px;
            top: 50%;
            transform: translateY(-50%);
            color: #6a11cb;
      }
      .input-icon input,
      .input-icon select {
            padding-left: 35px;
            box-sizing: border-box;
      }
      .content {
            display: flex;
            justify-content: space-between;
      }
      .content .input-icon {
            flex: 1;
      }
      .popup {
    display: none;
    position: fixed;
    z-index: 1;
    padding-top: 100px;
    padding-bottom: 10px;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    overflow: auto;
    background-color: rgb(0,0,0);
    background-color: rgba(0,0,0,0.9);
}

.popup-content {
    margin: auto;
    display: block;
}

.popup-content img {
    width: 100%;
    height: auto;
}

.close {
    position: absolute;
    top: 15px;
    right: 35px;
    color: #f1f1f1;
    font-size: 40px;
    font-weight: bold;
    transition: 0.3s;
}

.close:hover,
.close:focus {
    color: #bbb;
    text-decoration: none;
    cursor: pointer;
}
#imgList img {
      width: 100px;
      height: 100px;
      margin: 5px;
      cursor: pointer;
}
.img-btn {
      color: #ffffff;
      text-align: center;
      margin: 0px 5px 5px;
      cursor: pointer;
}
   


   
      
            
               
                  prompt
                  
               
               
                  negative_prompt
                  
               
               
                  model
                  
                        animagineXLV3_v30.safetensors
                        
                            devlishphotorealism_sdxl15.safetensors
                        dreamshaperXL10_alpha2.safetensors
                        
                        dynavisionXL_0411.safetensors
                        juggernautXL_v45.safetensors
                        realismEngineSDXL_v10.safetensors
                        
                        realvisxlV40.safetensors
                        sd_xl_base_1.0.safetensors
                        
                            sd_xl_base_1.0_inpainting_0.1.safetensors
                        turbovisionXL_v431.safetensors
                        
                  
               
               
                  style_preset
                  
                        3d-model 3D模型
                        analog-film 模拟电影
                        anime 日本动画片
                        cinematic 电影般的
                        comic-book 漫画书
                        digital-art 数字艺术
                        enhance 提高
                        fantasy-art 幻想艺术
                        isometric 等距
                        line-art 线条艺术
                        low-poly 低聚
                        neon-punk 霓虹朋克
                        origami 折纸
                        photographic 摄影的
                        pixel-art 像素艺术
                        texture 质地
                        craft-clay 工艺粘土
                  
               
                生成
            
      
      
            
      
   
   
      ×
      


      
   
   


`;
const PRODIA_API_KEY = 'xxxxx'
// The rest of the Worker script remains the same
addEventListener('fetch', event => {
    event.respondWith(handleRequest(event.request))
})
async function handleRequest(request) {
    const url = new URL(request.url);
    if (request.method === 'GET' && url.pathname === '/') {
      return new Response(htmlContent, {
            headers: {
                'Content-Type': 'text/html'
            },
      });
    } else if (request.method === 'POST' && url.pathname === '/generate-image') {
      return generateImageByText(request);
    } else if (request.method === 'POST' && url.pathname === '/get-image') {
      return getImage(request);
    } else {
      return new Response('Not Found', {
            status: 404
      });
    }
}
async function generateImageByText(request) {
    const {
      prompt,
      negative_prompt,
      model,
      style_preset
    } = await request.json();
    // First request to generate the image
    const generateResponse = await fetch('https://api.prodia.com/v1/sdxl/generate', {
      method: 'POST',
      headers: {
            accept: 'application/json',
            'content-type': 'application/json',
            'X-Prodia-Key': PRODIA_API_KEY
      },
      body: JSON.stringify({
            model: model,
            prompt: prompt,
            negative_prompt: negative_prompt,
            style_preset: style_preset,
            steps: 20,
            cfg_scale: 7,
            seed: -1,
            sampler: 'DPM++ 2M Karras',
            width: 1024,
            height: 1024
      })
    });
    const generateData = await generateResponse.json();
    const jobId = generateData.job;
    console.log(jobId)
    // Polling for the job status
    return new Response(JSON.stringify({jobId: jobId}), {
      headers: {
            'Content-Type': 'application/json'
      }
    });
}
async function getImage(request) {
    const {
      jobId
    } = await request.json();
    // Polling for the job status
    const statusResponse = await fetch(`https://api.prodia.com/v1/job/${jobId}`, {
      method: 'GET',
      headers: {
            accept: 'application/json',
            'X-Prodia-Key': PRODIA_API_KEY
      }
    });
    const statusData = await statusResponse.json();
    return new Response(JSON.stringify({image: statusData.imageUrl}), {
      headers: {
            'Content-Type': 'application/json'
      }
    });
}

https://linux.do/uploads/default/optimized/3X/2/c/2cdbd1462ba04ca616709ad4b69536a73837b91d_2_690x345.png
图片11176×588 55.1 KB"
页: [1]
查看完整版本: 利用Cloudflare Workers每月免费额度,优化页面展示,实现1000次免费Stable Diffusion绘画。