File size: 3,286 Bytes
8a4950c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
da0c7e5
8a4950c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# handler.py

from PIL import Image
from diffusers import (
    StableDiffusionControlNetImg2ImgPipeline,
    ControlNetModel,
    DDIMScheduler,
)
from diffusers.utils import load_image
import torch
import openai
from io import BytesIO
import base64
import qrcode


class EndpointHandler:
    def __init__(
        self,
        controlnet_path="DionTimmer/controlnet_qrcode-control_v11p_sd21",
        pipeline_path="stabilityai/stable-diffusion-2-1",
    ):
        self.controlnet = ControlNetModel.from_pretrained(
            controlnet_path, torch_dtype=torch.float16
        )

        self.pipe = StableDiffusionControlNetImg2ImgPipeline.from_pretrained(
            pipeline_path,
            controlnet=self.controlnet,
            safety_checker=None,
            torch_dtype=torch.float16,
        )

        self.pipe.enable_xformers_memory_efficient_attention()
        self.pipe.scheduler = DDIMScheduler.from_config(self.pipe.scheduler.config)
        self.pipe.enable_model_cpu_offload()

    @staticmethod
    def resize_for_condition_image(input_image: Image, resolution: int):
        input_image = input_image.convert("RGB")
        W, H = input_image.size
        k = float(resolution) / min(H, W)
        H *= k
        W *= k
        H = int(round(H / 64.0)) * 64
        W = int(round(W / 64.0)) * 64
        img = input_image.resize((W, H), resample=Image.LANCZOS)
        return img

    def __call__(
        self,
        prompt,
        negative_prompt,
        qrcode_data,
        guidance_scale,
        controlnet_conditioning_scale,
        strength,
        generator_seed,
        width,
        height,
        num_inference_steps,
    ):
        openai.api_key = "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"

        qr = qrcode.QRCode(
            version=1,
            error_correction=qrcode.constants.ERROR_CORRECT_H,
            box_size=10,
            border=4,
        )
        qr.add_data(qrcode_data)
        qr.make(fit=True)
        img = qr.make_image(fill_color="black", back_color="white")

        # Resize image
        basewidth = 768
        wpercent = basewidth / float(img.size[0])
        hsize = int((float(img.size[1]) * float(wpercent)))
        qrcode_image = img.resize((basewidth, hsize), Image.LANCZOS)

        response = openai.Image.create(prompt=prompt, n=1, size="1024x1024")
        image_url = response.data[0].url
        init_image = load_image(image_url)

        control_image = qrcode_image
        init_image = self.resize_for_condition_image(init_image, 768)

        generator = torch.manual_seed(generator_seed)

        image = self.pipe(
            prompt=prompt,
            negative_prompt=negative_prompt,
            image=init_image,
            control_image=control_image,
            width=width,
            height=height,
            guidance_scale=guidance_scale,
            controlnet_conditioning_scale=controlnet_conditioning_scale,
            generator=generator,
            strength=strength,
            num_inference_steps=num_inference_steps,
        )

        pil_image = image.images[0]
        buffered = BytesIO()
        pil_image.save(buffered, format="PNG")
        image_base64 = base64.b64encode(buffered.getvalue()).decode()

        return image_base64