Initial commit

This commit is contained in:
cqql 2024-07-03 19:13:19 +02:00
commit d057c6bf02
10 changed files with 167 additions and 0 deletions

24
README.md Executable file
View file

@ -0,0 +1,24 @@
![an autogenerated 10print pattern in blue](examples/palette_1.png)
# Generative Banner
#### a little fun thing i made back in early 2023
A bit of code that generates a 10 print pattern in one on the specified color palettes and sets the result as the banner on a Pleroma account. I made it run as a cronjob every day at midnight.
You can see some generated examples in the [examples](examples) folder.
## Usage
In [generate_set_banner.py](generate_set_banner.py):
1. Set the OAuth token used to access the Pleroma API with privileges to edit your account. I used [this site](https://tinysubversions.com/notes/mastodon-bot/).
2. Set the base url of the Pleroma instance.
```py
OAUTH_TOKEN = 'OAUTH_TOKEN'
base_url = 'https://example.com'
```
Run
```
python3 generate_set_banner.py
```
This will generate a banner using a randomly picked color palette from a list in the code and set it as the banner on your fedi account.

BIN
examples/palette_0.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

BIN
examples/palette_1.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

BIN
examples/palette_2.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

BIN
examples/palette_3.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

BIN
examples/palette_4.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

BIN
examples/palette_5.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

63
generate_set_banner.py Executable file
View file

@ -0,0 +1,63 @@
import requests
import tenprint_gradient
from io import BytesIO
OAUTH_TOKEN = 'OAUTH_TOKEN' # OAuth token to access your account through the Pleroma API
base_url = 'https://example.com' # The base URL of the Pleroma instance
# The list of color palettes. It contains tuples, where the first two elements
# of each tuple are the colors for the background gradient and the last two are
# the foreground (slashes) gradient colors.
# I put them in separate lists grouped by the 4 colors they use so that there is an equal
# probability of getting each 4-color scheme. And only then the color tuple is picked,
# determining the orientations of the gradients.
palettes = [
[
(0xef5d60,0xec4067,0xa01a7d,0x311847),
],
[
(0x0a1128,0x001f54,0x034078,0x1282a2),
],
[
(0x212d40,0x11151c,0xb9314f,0xedddd4),
],
[
(0x191d32,0x282f44,0x453a49,0x6d3b47),
],
[
(0x0b3c49,0x731963,0xfffdfd,0xcbd2d0),
(0x0b3c49,0x731963,0xcbd2d0,0xfffdfd),
(0x731963,0x0b3c49,0xcbd2d0,0xfffdfd),
(0x731963,0x0b3c49,0xfffdfd,0xcbd2d0)
],
[
(0xfffdfd,0xcbd2d0,0x0b3c49,0x731963),
(0xcbd2d0,0xfffdfd,0x0b3c49,0x731963),
(0xcbd2d0,0xfffdfd,0x731963,0x0b3c49),
(0xfffdfd,0xcbd2d0,0x731963,0x0b3c49)
]
]
print('Picking palette')
palette_index, palette_orientation, palette = tenprint_gradient.get_random_palette(palettes)
print(f'Using palette {palette_index}/{palette_orientation} - {palette}')
print('Generating banner')
# This will generate a banner 31 cells wide, 11 cells tall, with each cell being 100 by 100 pixels, and with 0 margin
banner_image = tenprint_gradient.generate_gradiented_10print(31, 11, 100, 0, palette)
print('Getting banner bytes')
banner_bytes = None
with BytesIO() as output:
banner_image.save(output, 'PNG')
banner_bytes = output.getvalue()
print(f'Requesting banner update at {base_url}')
response = requests.patch(f'{base_url}/api/v1/accounts/update_credentials', files={
'header': banner_bytes
}, headers={'Authorization': f'Bearer {OAUTH_TOKEN}'})
print('Response')
print(response.text)

35
tenprint.py Executable file
View file

@ -0,0 +1,35 @@
from PIL import Image, ImageDraw
import random
bgcolor = (255,255,255)
fgcolor = (0,0,0)
def draw_slash(d, x, y, cellsize, flip, thickness=0.16):
if flip:
slash = [
(x+cellsize*(1-thickness), y),
(x+cellsize, y),
(x+cellsize, y+cellsize*thickness),
(x+cellsize*thickness, y+cellsize),
(x, y+cellsize),
(x, y+cellsize*(1-thickness))
]
else:
slash = [
(x, y),
(x+cellsize*thickness, y),
(x+cellsize, y+cellsize*(1-thickness)),
(x+cellsize, y+cellsize),
(x+cellsize*(1-thickness), y+cellsize),
(x, y+cellsize*thickness)
]
d.polygon(slash, fill=fgcolor)
def make_image(width, height, cellsize_px, margin=0):
image = Image.new("RGB", (int(cellsize_px*margin + width*(cellsize_px*(1+margin))), int(cellsize_px*margin + height*(cellsize_px*(1+margin)))), bgcolor)
draw = ImageDraw.Draw(image)
for x in range(width):
for y in range(height):
draw_slash(draw, cellsize_px*margin + x*(cellsize_px+margin*cellsize_px), cellsize_px*margin + y*(cellsize_px+margin*cellsize_px), cellsize_px, random.random() > 0.5)
return image

45
tenprint_gradient.py Executable file
View file

@ -0,0 +1,45 @@
import tenprint
import random
def get_rgb_from_int(color):
r = (color>>16) & 255
g = (color>>8) & 255
b = color & 255
return (r,g,b)
def get_gradient(color1, color2, between):
new_color = []
for p1, p2 in zip(color1, color2):
new_color.append(int(p1*between + p2*(1-between)))
return tuple(new_color)
def get_palette_rgb_from_palette_int(palette_raw):
return [
get_rgb_from_int(c) for c in
palette_raw
]
def generate_gradiented_10print(width, height, cellsize, margin, palette):
image = tenprint.make_image(width, height, cellsize, margin)
pixels = image.load()
width_px = image.size[0]
height_px = image.size[1]
bg_gradient = palette[0:2]
fg_gradient = palette[2:4]
for x in range(width_px):
for y in range(height_px):
if pixels[x,y] == tenprint.bgcolor:
pixels[x,y] = get_gradient(bg_gradient[0], bg_gradient[1], y/height_px)
if pixels[x,y] == tenprint.fgcolor:
pixels[x,y] = get_gradient(fg_gradient[0], fg_gradient[1], y/height_px)
return image
def get_random_palette(palettes):
palette_index, palette_rotations = random.choice(tuple(enumerate(palettes)))
palette_rotation, palette = random.choice(tuple(enumerate(palette_rotations)))
return palette_index, palette_rotation, get_palette_rgb_from_palette_int(palette)