File size: 3,860 Bytes
a5e4556
 
982271d
a5e4556
 
 
66c269b
a5e4556
 
 
5148b60
 
0083add
a5e4556
 
 
 
 
 
 
5148b60
 
 
0083add
a5e4556
5148b60
d4d5379
5148b60
 
 
 
 
 
 
 
 
 
 
 
 
66c269b
a5e4556
 
5148b60
 
a5e4556
 
 
 
5148b60
a5e4556
5148b60
a5e4556
982271d
 
a5e4556
982271d
 
a5e4556
982271d
 
 
5148b60
 
982271d
 
 
a5e4556
 
 
 
982271d
 
 
 
a5e4556
 
 
982271d
5148b60
982271d
5148b60
982271d
 
5148b60
982271d
 
5148b60
982271d
 
 
 
a5e4556
982271d
a5e4556
 
 
5148b60
 
0a4bf49
 
 
 
56d4930
5148b60
 
0a4bf49
56d4930
0a4bf49
5148b60
0a4bf49
5148b60
0a4bf49
 
 
 
5148b60
0a4bf49
5148b60
0a4bf49
56d4930
5148b60
 
0a4bf49
5148b60
0a4bf49
 
 
 
56d4930
5148b60
1aab22d
5148b60
66c269b
982271d
 
66c269b
982271d
 
1aab22d
5148b60
1aab22d
5148b60
 
 
 
 
66c269b
 
5148b60
56d4930
0a4bf49
5148b60
0a4bf49
5148b60
0a4bf49
982271d
 
0a4bf49
5148b60
0083add
 
5148b60
 
d4d5379
0a4bf49
 
 
a5e4556
5148b60
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0a4bf49
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
# =====================================================
# Apckeyl_RealESRGAN
# Version 7.0
# tile_processor.py
# =====================================================

from PIL import Image, ImageOps

from config import (
    TILE_SIZE,
    TILE_PAD,
    PRE_PAD,
    MODEL_SCALE,
)


class TileProcessor:

    def __init__(self):

        self.tile = TILE_SIZE
        self.tile_pad = TILE_PAD
        self.pre_pad = PRE_PAD
        self.scale = MODEL_SCALE

    # -------------------------------------------------

    def preprocess(self, image):

        if self.pre_pad > 0:

            image = ImageOps.expand(
                image,
                border=self.pre_pad,
                fill=0
            )

        return image

    # -------------------------------------------------

    def split(self, image):

        image = self.preprocess(image)

        width, height = image.size

        tiles = []

        for top in range(0, height, self.tile):

            for left in range(0, width, self.tile):

                tile_h = min(self.tile, height - top)
                tile_w = min(self.tile, width - left)

                input_left = max(0, left - self.tile_pad)
                input_top = max(0, top - self.tile_pad)

                input_right = min(
                    width,
                    left + tile_w + self.tile_pad
                )

                input_bottom = min(
                    height,
                    top + tile_h + self.tile_pad
                )

                tile = image.crop(
                    (
                        input_left,
                        input_top,
                        input_right,
                        input_bottom
                    )
                )

                tiles.append({

                    "tile": tile,

                    "x": left,
                    "y": top,

                    "w": tile_w,
                    "h": tile_h,

                    "input_left": input_left,
                    "input_top": input_top,
                    "input_right": input_right,
                    "input_bottom": input_bottom,

                })

        return tiles

    # -------------------------------------------------

    def create_output_canvas(
        self,
        image
    ):

        image = self.preprocess(image)

        width, height = image.size

        return Image.new(

            "RGBA",

            (
                width * self.scale,
                height * self.scale
            ),

            (0, 0, 0, 0)

        )

    # -------------------------------------------------

    def paste_tile(

        self,
        canvas,
        tile_info,
        upscaled_tile

    ):

        pad = self.tile_pad * self.scale

        crop_left = 0 if tile_info["input_left"] == 0 else pad
        crop_top = 0 if tile_info["input_top"] == 0 else pad

        crop_right = crop_left + tile_info["w"] * self.scale
        crop_bottom = crop_top + tile_info["h"] * self.scale

        upscaled_tile = upscaled_tile.crop(

            (
                crop_left,
                crop_top,
                crop_right,
                crop_bottom
            )

        )

        canvas.alpha_composite(

            upscaled_tile.convert("RGBA"),

            (
                tile_info["x"] * self.scale,
                tile_info["y"] * self.scale
            )

        )

    # -------------------------------------------------

    def finish(
        self,
        canvas
    ):

        if self.pre_pad > 0:

            pad = self.pre_pad * self.scale

            w, h = canvas.size

            canvas = canvas.crop(

                (
                    pad,
                    pad,
                    w - pad,
                    h - pad
                )

            )

        return canvas.convert("RGB")