Compare commits

..

78 Commits

Author SHA1 Message Date
t 9c6c5524a8 Back to old model. 2023-11-28 00:08:28 +03:00
none 482d53af93 Fix 2023-11-27 21:01:07 +03:00
none 891f7fecf2 Change port 2023-11-27 20:40:06 +03:00
none 0f0b29e03e Merge branch 'main' of ssh://5.180.137.216:2222/justuser/pxl_oboard 2023-11-27 20:37:42 +03:00
justuser 0280863e74 Delete 'site/design.css' 2023-11-27 23:36:29 +03:00
justuser d3b74c80e0 Delete 'site/site.html' 2023-11-27 23:36:09 +03:00
none d1cf3552bf Update style, dark theme, change names, no css. 2023-11-27 20:37:33 +03:00
none 9b260c1975 Merge branch 'main' of ssh://5.180.137.216:2222/justuser/pxl_oboard 2023-11-27 20:24:25 +03:00
t 58a4545a40 Merge remote-tracking branch 'refs/remotes/origin/main' 2023-11-27 23:00:17 +03:00
t 4dc9452156 Speed up to 2x token. 2023-11-27 22:57:59 +03:00
t 6abc4c4691 Add token-system 2023-11-27 21:29:08 +03:00
none 5f1e1c88d7 Update 2023-11-27 20:13:30 +03:00
none 2801b14b05 Fix token-error. 2023-11-27 18:42:02 +03:00
none 3b73faa794 Customizeable limit and token-system. 2023-11-27 18:30:32 +03:00
none 83b43cdd5b Add Holinim's site auto-update version 2023-11-26 21:39:06 +03:00
none 276bcb7ff9 Fix wrong cords. 2023-11-26 18:37:29 +03:00
none 87938079b3 Add image-preview + cords of this image. 2023-11-26 18:04:43 +03:00
none cc3bc15ac8 Separate threads, now cords more faster. 2023-11-26 14:22:31 +03:00
justuser 77f0a2a19d Update 'map.py' 2023-11-26 16:48:39 +03:00
none 1b5a86b0a2 Back map.py (temp) 2023-11-25 22:04:53 +03:00
justuser 00c58c925d revert 35426ab931
revert Delete 'map.py'
2023-11-26 00:59:30 +03:00
none abc2025032 Little change example. 2023-11-25 21:26:18 +03:00
none 38e68ce92d Fix mirror-bug. 2023-11-25 20:53:37 +03:00
none 161e8cb728 Fix flip-bug, now convert normally image. 2023-11-25 17:57:05 +03:00
none a561b1a08b New image draw and optimizer 🎉 2023-11-25 15:24:47 +03:00
justuser 4373dab299 Delete 'im_convert.py' 2023-11-25 16:40:16 +03:00
justuser cb4b642a70 Rename botv2 to bot 2023-11-25 16:39:42 +03:00
justuser 4f6c2190d6 Delete 'bot.py' 2023-11-25 16:39:10 +03:00
none 41f70c6cf2 Stable version 2023-11-25 13:14:22 +03:00
t c3dad58e41 . 2023-11-25 16:08:57 +03:00
none edcaf98b42 New beta. Remove pack() in extras (no longer needed) 2023-11-25 00:48:05 +03:00
t 3bf33f9d30 Change resolution to 1280x720 - 16:9 2023-11-25 03:39:46 +03:00
t 05d983dae3 Add limit for post (draw pixels) 2023-11-25 02:15:16 +03:00
none 19eadd9d81 Fix cpu/speed, beta-version 2023-11-24 22:53:05 +03:00
none 1faf6301b6 New beta-version 2023-11-24 22:04:35 +03:00
none 60852d1ad0 New v2 with arrays post and get ( [[x,y], [x,y]] ) 2023-11-23 22:27:46 +03:00
justuser 955f383031 Delete 'server.py' 2023-11-24 01:25:25 +03:00
justuser d9a47dfd55 Delete 'post.py' 2023-11-24 01:25:10 +03:00
justuser 41756716e7 Delete 'map.png' 2023-11-23 19:17:36 +03:00
justuser 70207f351f Delete 'image.png' 2023-11-23 19:17:20 +03:00
justuser 35426ab931 Delete 'map.py' 2023-11-23 19:17:09 +03:00
justuser31 910dd6e62f Maked show image before move input 2023-05-26 22:29:21 +03:00
justuser31 56e5458814 Update adress 2023-05-12 17:53:39 +03:00
justuser31 d57189b086 Rename main.py to server.py 2023-04-26 17:39:39 +03:00
justuser 8b30ab0ec8 Rename to server.py 2023-04-26 17:37:04 +03:00
justuser 6203bf186f Delete 'im_create.py' 2023-04-24 17:43:14 +03:00
justuser b14283af8d Update 'README.md' 2023-04-24 17:40:47 +03:00
justuser31 5d6923aaf6 Optimize support 2023-04-23 21:07:56 +03:00
justuser31 0263b7bc6f Make it better 2023-04-23 19:35:26 +03:00
justuser31 2c81b71556 More colors and structuring color codes 2023-04-23 13:45:30 +03:00
justuser31 13afd1dfee dark_green -> green 2023-04-23 12:07:21 +03:00
justuser31 56fea85607 Add more colors 2023-04-23 12:03:19 +03:00
justuser31 60ca1f4bb3 Show percent of removed pixels 2023-04-22 20:04:06 +03:00
justuser31 e8f5b8dba9 Background remover 2023-04-22 19:59:30 +03:00
justuser31 44a6990a4c Fix bar 2023-04-22 15:39:48 +03:00
justuser31 b0db41c11a Icon for map.py 2023-04-22 15:38:29 +03:00
justuser31 fada354c74 Add icon and add cordinates 2023-04-22 15:31:49 +03:00
justuser31 faecbf0fc6 Init real-time map 2023-04-22 14:34:31 +03:00
justuser31 fac9ac8dcc Disable rotation 2023-04-22 13:49:32 +03:00
justuser31 83ef33480a Remove upscale: it's buggy 2023-04-22 13:47:07 +03:00
justuser31 ee2e6e96e4 Fix visual bug 2023-04-22 12:53:44 +03:00
justuser31 9145838701 Init image for im_converter.py 2023-04-22 12:41:32 +03:00
justuser31 3aff64a933 Enable online mode 2023-04-22 12:40:48 +03:00
justuser31 afbfa02566 Disable pixel check: it glitched 2023-04-22 12:40:09 +03:00
justuser31 1b87107d3c Init image converter 2023-04-22 12:39:01 +03:00
justuser31 1b415d50c5 Merge branch 'main' of ssh://ssh.dmcraft.online:2222/justuser/pxl_oboard 2023-04-21 20:48:40 +03:00
justuser31 4f5e14e131 Pass colored pixels 2023-04-21 20:48:27 +03:00
Your Name 380930e8e7 Fix colors 2023-04-21 20:40:58 +03:00
justuser31 df06ca94a3 Revert 2023-04-21 20:22:39 +03:00
justuser31 f5ed42c5e6 Revert 2023-04-21 20:22:17 +03:00
justuser31 74ad0ad523 Revert x y 2023-04-21 20:17:44 +03:00
justuser31 16930a2770 Init get_color 2023-04-21 20:14:38 +03:00
justuser31 3ad7d6f6fc Remove delay 2023-04-21 18:32:50 +03:00
justuser31 855e80f6e5 Remove borders 2023-04-21 18:32:25 +03:00
justuser31 f87c84db30 Add draw line 2023-04-21 17:19:58 +03:00
justuser31 10dab6a7f5 Merge branch 'main' of ssh://ssh.dmcraft.online:2222/justuser/pxl_oboard 2023-04-21 16:51:44 +03:00
justuser31 864a07cd89 Add move at X and Y 2023-04-21 16:50:46 +03:00
justuser 67762fda4a Update 'README.md' 2023-04-21 16:11:45 +03:00
16 changed files with 605 additions and 262 deletions
+29 -12
View File
@@ -9,22 +9,39 @@ Super simple, super stupid.
## -------------------------------- ## --------------------------------
## >>>Рисование<<<: ## >>>Рисование<<<:
## Уровень: ламер ## Уровень: ламер
1. Скачать im_creator.py 1. Скачать im_convert.py
2. Запустить через `python3 im_creator.py` 2. Запустить через `python3 im_creator.py`
3. Нарисовать что-то. 3. Загрузить/нарисовать изображение, файл - image.png где и скрипт. (желательно не больше 128 на 128 пикселей)
4. Нажать кнопку "Upload" для загрузки рисунка на сервер. 4. Задать смещение по координатам X и Y.
5. Ждать надписи в консоли "DONE" 5. Проверить результат - должно показать конвертированное изображение.
6. Включить/выключить оптимизацию. ( (Y/N), оно убирает фоновый цвет, чем уменьшеает время на отрисовку)
7. Загрузить изображение. (Y)
## Уровень: овнокодер ## Уровень: овнокодер (типо документация)
Вы можете написать свой скрипт на основе post.py или... Вы можете написать свой скрипт на основе post.py (почти ничего нету) или...
1. Скачать bot.py 1. Скачать bot.py
2. Запрогроммировать свои инструкции для бота: 2. Запрогроммировать свои инструкции для бота:
#### draw([0,1], [0,2], "blue") - Функция для рисования, использует массив списков. ### Функция gcolor(x, y)
( Поставить точки в координатах [0,1] и [0,2] формата [x,y] ) - Принимает на вход два параметра: x и y - координаты пикселя на сайте.
#### linex(y, x1, x2) - Функция для создания массива линии по координате Х - Возвращает цвет пикселя, например: "white" (белый).
( Y остаётся таким же, массив идёт из x1 в x2 )
#### liney(x, y1, y2) - Аналогично. ### Функция draw(cords, color = "black")
#### fill([x1,y1], [x2, y2]) - Генерация массива для заполнения, дальше передавать в draw() - Принимает на вход список cords - список координат для точек.
- Опциональный параметр color, для изменения цвета. ( полезно только для списков из fill()/linex()/liney() )
- Возвращает строку "DONE!" после отрисовки.
### Функция linex(y, x1, x2)
- Принимает на вход три параметра: y - координата Y, x1 - первая координата X, x2 - вторая кордината X.
- Создаёт массив координат: линия из [x1, y] в [x2, y].
- !! x2 должен быть больше x1 !!
- Возвращает массив координат, можно передать в draw()
### Функция liney(x, y1, y2)
- Аналогично, только по Y.
### Функция fill(xy1, xy2)
- Принимает на вход два параметра: xy1 и xy2 - координаты двух точек прямоугольника для заливки.
- Возвращает массив координат, можно передать в draw()
## -------------------------------- ## --------------------------------
## Установка своего сервера: ## Установка своего сервера:
+70 -38
View File
@@ -1,55 +1,87 @@
import requests import requests
from time import sleep from time import sleep
# Progress-bar
from tqdm import tqdm from tqdm import tqdm
# Work with list-like objects
from listwork import *
global xc, yc # Easy debug
xc = 0 ; yc = 0 from icecream import ic
ic.disable() # Disable debug
def draw(cords, color = "black"): global server
global xc, yc #server = 'http://127.0.0.1:3333'
for i in tqdm(range(len(cords))): server = 'http://pb.gulyaipole.fun'
payload = {'x': cords[i][1] + yc, 'y': cords[i][0] + xc, 'color': color }
response = requests.post('http://pb.dmcraft.online', data=payload) # fill(0,0, 10,10, [0,0,0])
def fill(x1,y1, x2,y2, color):
pxls = []
r = color[0] ; g = color[1] ; b = color[2]
for x in range(x1, x2+1):
for y in range(y1, y2+1):
pxls.append([x, y, r, g, b])
return pxls
while str(response) != "<Response [200]>": # draw( fill(...), limit=500, token="fdsfs" )
response = requests.post('http://pb.dmcraft.online', data=payload) def draw(pxls, limit=300, token="None"):
print("Error, retrying...") global server
sleep(0.1) ic(pxls)
print("DONE!")
def linex(y, x1, x2): push = [] # Push %limit% items
res = [] while len(pxls) > limit:
for i in range(x1, x2+1): packs = [] # Merge elements to %limit% size list
res.append( [i,y] ) for i in range(limit):
return res # Take first element
packs.append(pxls[0])
pxls.pop(0)
push.append({"main": pack(packs), "token": token})
push.append({"main": pack(pxls), "token": token}) # Pack last
def liney(x, y1, y2): ic(push)
res = [] for i in tqdm(push):
for i in range(y1, y2+1): response = requests.post(server, i)
res.append( [x,i] ) while not response.status_code == 200:
return res print("Error, retrying...")
response = requests.post(server, i)
sleep(0.1)
def fill(xy1, xy2): # cfill(0,0, 10,10) // Limit - 34x34
res = [] def cfill(x1,y1, x2,y2):
for x in range(xy1[0], xy2[0] + 1): pxls = []
for y in range(xy1[1], xy2[1] + 1): for x in range(x1, x2+1):
res.append( [x, y] ) for y in range(y1, y2+1):
return res pxls.append([x, y])
packed = pack(pxls)
return packed
# ccheck( packed([[0,0]]) ) or ccheck(cfill(...))
def ccheck(packed):
global server
response = requests.get(f'{server}/get_color={packed}')
ic(response.text)
out = unpack(response.text)
return out
### EXAMPLE
# Draw random square 100x100 on 0,0
from random import randint as ri
draw( fill(0,0, 100,100, [ri(0,255),ri(0,255),ri(0,255)]) )
xc = 200 # Check square 34x34 on 0,0
yc = 300 print(ccheck(cfill(0,0, 34,34)))
#Russian flag # Use extras, draw 1/2 random square 100x100 on 0,0
draw(fill([300,300], [330, 300])) from bot_extras import *
draw(fill([300,330], [330, 330])) draw(pas2( rand(0,0, 100,100) ))
draw(fill([300,300], [300, 330]))
draw(fill([330,300], [330, 330]))
draw(fill([301,321], [329, 329]), "white") # Draw image (flipped (BUG) )
draw(fill([301,310], [329, 320]), "blue") from im_convert import *
draw(fill([301,301], [329, 310]), "red") image = convert("example.png", [10,0])
from remove_back import *
draw( optimize(image, [255,255,255]) ) # Remove white background and draw
# Draw with premium-token, limit 600 (default token)
# Token is fake, >ERROR<
draw( fill(758,0, 1123,198, [255,255,255]), limit=600, token="3744138bd462cd8180e4w3534rfdsw4rwert" )
+23
View File
@@ -0,0 +1,23 @@
from listwork import *
from random import randint as ri
# pas2( fill(...) ) -> 1/2
def pas2(pxls):
new_pxls = []
pas = False
for i in pxls:
if not pas:
new_pxls.append(i)
pas = True
else:
pas = False
return new_pxls
# rand(x1,y1, x2,y2) -> draw() or pas2()
def rand(x1,y1, x2,y2):
pxls = []
for x in range(x1, x2 +1):
for y in range(y1, y2 +1):
pxls.append([x,y, ri(0,255), ri(0,255), ri(0,255)])
return pxls
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

+42
View File
@@ -0,0 +1,42 @@
import tkinter as tk
from time import sleep
def start_drag(event):
global current_coords
global dragged_item
dragged_item = label
current_coords = label.winfo_pointerx(), label.winfo_pointery()
def stop_drag(event):
dragged_item = None
def drag(event):
global current_coords
xc, yc = label.winfo_pointerx(), label.winfo_pointery()
dx, dy = xc - current_coords[0], yc - current_coords[1]
current_coords = xc, yc
label.place(x=label.winfo_x() + dx, y=label.winfo_y() + dy)
def nn(root,im):
global label
image = tk.PhotoImage(file=im) # Use self.image
label = tk.Label(root, image=image)
label.image = image # Keep a reference to the image
label.pack()
dragged_item = None
current_coords = 0, 0
label.bind('<ButtonPress-1>', start_drag)
label.bind('<ButtonRelease-1>', stop_drag)
label.bind('<B1-Motion>', drag)
# globals().update(locals())
while True:
tk.Misc.lift(label)
sleep(0.05)
print("Image cords: ", label.winfo_x(), 720 - label.winfo_y() - image.height())
#x1, y1 = image.coords(image)
# print(f'Image cords: {}')
+52
View File
@@ -0,0 +1,52 @@
from PIL import Image, ImageOps
# [[0,0, rgb1],... [1,1, rgb2]] -> [[1,1, rgb1],...[0,0, rgb2]]
def flip(cords):
fliped = []
flips = len(cords)//2
# El from start and el from end
fl0 = 0 ; fl1 = len(cords)-1
for i in range(flips):
# Copy element and change cords to cords of end element
new_st = list(cords[fl0])
new_st[0] = cords[fl1][0]
new_st[1] = cords[fl1][1]
fliped.append(new_st)
# Copy and change cords to cords of start element
new_end = list(cords[fl1])
new_end[0] = cords[fl0][0]
new_end[1] = cords[fl0][1]
fliped.append(new_end)
fl0 += 1 ; fl1 -= 1
return fliped
# convert("example.png") // png/jpg/gif
def convert(filename, move = [0,0]):
im = Image.open(filename).convert('RGB')
# Fix mirror
im = ImageOps.mirror(im)
pxls=im.load()
w=im.size[0]
h=im.size[1]
ll = []
for x in range(w):
for y in range(h):
# [x,y, [r, g, b]]
rgb = pxls[x,y]
ll.append( [x,y, rgb[0], rgb[1], rgb[2] ] )
# Fix flip
fliped = flip(ll)
# Move [x,y] + move
moved = []
for i in fliped:
moved.append([i[0] + move[0], i[1] + move[1], i[2],i[3],i[4]])
return moved
-116
View File
@@ -1,116 +0,0 @@
from tkinter import *
####DRAW BLOCK
import requests
from time import sleep
from tqdm import tqdm
def draw(cords):
for i in tqdm(range(len(cords))):
sleep(0.2)
try:
payload = {'x': cords[i][1], 'y': cords[i][0], 'color': cords[i][2]}
except:
payload = {'x': cords[i][1], 'y': cords[i][0], 'color': "b" }
response = requests.post('http://pb.dmcraft.online', data=payload)
#print(response)
while str(response) != "<Response [200]>":
response = requests.post('http://pb.dmcraft.online', data=payload)
print("Error, retrying...")
#print(response)
print("!!!DONE!!!")
class PixelArt:
def __init__(self, master):
self.master = master
self.master.title("Pixel Art")
self.canvas = Canvas(self.master, width=128*12, height=128*12, bg="white")
self.canvas.pack(side=LEFT, padx=5, pady=5)
self.colors = ["red", "green", "blue", "white","black"]
self.current_color = "red"
self.button_frame = Frame(self.master)
self.button_frame.pack(side=LEFT, padx=5, pady=5)
self.export_button = Button(self.button_frame, text="Export", command=self.export_image)
self.export_button.pack(side=TOP, padx=5, pady=5)
self.button_frame.pack(side=LEFT, padx=5, pady=5)
self.export_button = Button(self.button_frame, text="Clean", command=self.clean_image)
self.export_button.pack(side=TOP, padx=5, pady=5)
self.button_frame.pack(side=LEFT, padx=5, pady=5)
self.export_button = Button(self.button_frame, text="Upload", command=self.upload_image)
self.export_button.pack(side=TOP, padx=5, pady=5)
self.color_buttons = []
for color in self.colors:
button = Button(self.button_frame, bg=color, width=3, height=1, command=lambda c=color: self.set_color(c))
button.pack(side=TOP, padx=5, pady=5)
self.color_buttons.append(button)
for i in range(129):
self.canvas.create_line(i*12, 0, i*12, 128*12, fill="white")
self.canvas.create_line(0, i*12, 128*12, i*12, fill="white")
self.canvas.bind("<Button-1>", self.draw_pixel)
def draw_pixel(self, event):
x = int(event.x / 12)
y = int(event.y / 12)
self.canvas.create_rectangle(x*12, y*12, x*12 + 12, y*12 + 12, fill=self.current_color)
def set_color(self, color):
self.current_color = color
def clean_image(self):
items = self.canvas.find_all()
for item in items:
self.canvas.delete(item)
def upload_image(self):
pixel_data = []
for i in range(128):
for j in range(128):
color = self.canvas.itemcget(self.canvas.find_closest(i*12+6, j*12+6), "fill")
if color != "white":
tc = self.colors.index(color)
if tc == 0:
color = "red"
elif tc == 1:
color = "green"
elif tc == 2:
color = "blue"
elif tc == 3:
color = "black"
pixel_data.append([i, 127-j, color])
print("!!!START UPLOAD!!!")
draw(pixel_data)
def export_image(self):
pixel_data = []
for i in range(128):
for j in range(128):
color = self.canvas.itemcget(self.canvas.find_closest(i*12+6, j*12+6), "fill")
if color != "white":
tc = self.colors.index(color)
if tc == 0:
color = "red"
elif tc == 1:
color = "green"
elif tc == 2:
color = "blue"
elif tc == 3:
color = "black"
pixel_data.append([i, 127-j, color])
f = open('out.txt', 'w')
f.write(str(pixel_data))
f.close()
if __name__ == "__main__":
root = Tk()
pixel_art = PixelArt(root)
root.mainloop()
+24
View File
@@ -0,0 +1,24 @@
def unpack(string):
ll = string.split('-_')
ll.remove("") # Remove empty line
el_col = ll[0].count('-')
post_ll = []
for i in ll:
temp = i.split("-")
# Multi-add (2, 3 or 5 elements)
if el_col == 1:
post_ll.append([int(temp[0]), int(temp[1])])
elif el_col == 2:
post_ll.append([int(temp[0]), int(temp[1]), int(temp[2])])
elif el_col == 4:
post_ll.append([int(temp[0]), int(temp[1]), int(temp[2]), int(temp[3]), int(temp[4]) ])
return post_ll
def pack(ll):
string = ''
for el in ll:
for i in el:
string += str(i) + '-'
string += '_'
return string
-90
View File
@@ -1,90 +0,0 @@
from http.server import BaseHTTPRequestHandler, HTTPServer
from urllib.parse import parse_qs
from io import BytesIO
from PIL import Image
import numpy as np
import time
global LTIME
LTIME = cur_time = time.monotonic()
class RequestHandler(BaseHTTPRequestHandler):
MATRIX_SIZE = (800, 1024)
COLORS = {
'w': (255, 255, 255),
'b': (0, 0, 0),
'r': (255, 0, 0),
'g': (0, 255, 0),
}
def do_GET(self):
self.send_response(200)
self.send_header('Content-type', 'image/png')
self.end_headers()
matrix = self.get_matrix()
matrix = np.flip(matrix, axis=0)
self.send_image(matrix)
def do_POST(self):
global LTIME
cur_time = time.monotonic()
address = self.client_address[0]
print("IP: ", address)
if cur_time - LTIME <= 0.01:
self.send_error(429, 'Too Many Requests')
self.send_response(429)
return 0
else:
LTIME = time.monotonic()
content_length = int(self.headers['Content-Length'])
body = self.rfile.read(content_length)
params = parse_qs(body.decode('utf-8'))
y = int(params['y'][0])
x = int(params['x'][0])
color = params['color'][0]
matrix = self.get_matrix()
matrix[x][y] = self.COLORS[color]
self.save_matrix(matrix)
self.send_response(302)
self.send_header('Location', '/')
self.end_headers()
def get_matrix(self):
try:
with open('matrix.npy', 'rb') as f:
matrix = np.load(f)
except FileNotFoundError:
matrix = np.full(shape=(*self.MATRIX_SIZE, 3), fill_value=255, dtype=np.uint8)
self.save_matrix(matrix)
return matrix
def save_matrix(self, matrix):
with open('matrix.npy', 'wb') as f:
np.save(f, matrix)
def send_image(self, matrix):
image = Image.fromarray(matrix)
buffer = BytesIO()
image.save(buffer, format='PNG')
self.wfile.write(buffer.getvalue())
def run():
server = HTTPServer(('127.0.0.1', 3333), RequestHandler)
server.serve_forever()
if __name__ == '__main__':
run()
+88
View File
@@ -0,0 +1,88 @@
import urllib.request
import time
from PIL import Image, ImageTk
import io
import tkinter as tk
url = "https://pb.gulyaipole.fun/"
root = tk.Tk()
root.geometry("1280x720")
# Canvas for image
canvas = tk.Canvas(root)
canvas.pack()
# XY cords
ttext = tk.Canvas(root, width=100, height=20, bg="black")
ttext.place(x=1180, y=0)
text = ttext.create_text(50, 10, text="X: 1, Y: 1", fill="white")
# Run threads
from threading import Thread
from time import sleep
def cords_up():
while True:
x = root.winfo_pointerx() - root.winfo_rootx()
y = 720 - (root.winfo_pointery() - root.winfo_rooty())
ttext.itemconfig(text, text=f"X: {x}, Y: {y}")
sleep(0.05)
cords = Thread(target=cords_up)
cords.start()
#### WARN, GPT-BLOB ####
from gpt_blob import *
# Get file from args
from sys import argv
try:
im = argv[1]
n = Thread(target=nn, args=[root, im,])
n.start()
except:
print("None image")
#######################
def map_up():
global canvas_old, canvas, label
while True:
# Prepare image for tkiner
image_file = io.BytesIO(urllib.request.urlopen(url).read())
img = Image.open(image_file)
tk_img = ImageTk.PhotoImage(img)
# Create new canvas
canvas = tk.Canvas(root, width=img.size[0], height=img.size[1])
canvas.create_image(0, 0, anchor="nw", image=tk_img)
canvas.place(x=0, y=0)
try:
# New canvas and cords up
tk.Misc.lift(canvas)
tk.Misc.lift(ttext)
# Update
root.update()
sleep(2)
# Remove old
canvas_old.destroy()
except:
pass
# New canvas now is old
canvas_old = canvas
map = Thread(target=map_up)
map.start()
root.mainloop()
+17 -4
View File
@@ -1,6 +1,19 @@
import requests import requests
# Work with list-like objects
from listwork import *
server = 'http://127.0.0.1:3333'
# Draw some pixels
# [[x, y, color-1, color-2, color-3], ...]
fill = {"main": pack([[200, 100, 0, 0, 0], [15, 30, 255, 54, 43]]) }
response = requests.post(server, data=fill)
if response:
print("posted")
# Get color code of coords
# [[x,y], ...]
xys = pack([[200,100], [13,10], [50,50]])
response = requests.get(f'{server}/get_color={xys}')
print( unpack(response.text) )
payload = {'x': 52, 'y': 20, 'color': 'r'}
#response = requests.post('http://pb.dmcraft.online', data=payload)
response = requests.post('http://127.0.0.1:3333', data=payload)
print(response)
+16
View File
@@ -0,0 +1,16 @@
from tqdm import tqdm
def optimize(pxls, back):
old_len = len(pxls)
new_pxls = []
for i in tqdm(range(old_len)):
el = pxls[i]
now_back = [el[2], el[3], el[4]]
if now_back != back:
new_pxls.append(pxls[i])
print(f"Optimized {(old_len - len(new_pxls)) / old_len * 100 }%")
return new_pxls
+167
View File
@@ -0,0 +1,167 @@
from http.server import BaseHTTPRequestHandler, HTTPServer
from urllib.parse import parse_qs
from io import BytesIO
from PIL import Image
import numpy as np
import time
# Easy debug
from icecream import ic
ic.disable() # Turn off
# Limit for requests
LTIME = cur_time = time.monotonic()
globals().update(locals())
# Key by value
def kbv(dict_, value):
for i in dict_:
if dict_[i] == value:
return i
# Work with list-like objects
from listwork import *
# Work with tokens
import json
global tokens
def tokens_load():
with open('tokens.json', 'r') as openfile:
return json.load(openfile)
# (Re)generate tokens
def tokens_regen():
import hashlib
from random import randint as ri
tokens = tokens_load()
tokens["admin"] = hashlib.sha256(str.encode( str(ri(2443, 6543)) + tokens["secret"] )).hexdigest()
tokens["premium"] = []
for i in range(10):
tokens["premium"].append( hashlib.sha256(str.encode( str(ri(2443, 6543)) + tokens["secret"] )).hexdigest() )
js = json.dumps(tokens, indent=2)
with open("tokens.json", "w") as outfile:
outfile.write(js)
# Uncomment to regen
#tokens_regen()
class RequestHandler(BaseHTTPRequestHandler):
MATRIX_SIZE = (720, 1280)
def do_GET(self):
params = parse_qs(self.path[1:])
ic(params)
if 'get_color' in params:
params = params['get_color'][0]
ic(len(params))
xys = unpack(params)
ic.disable()
matrix = self.get_matrix()
colors = []
for i in xys:
ic(i)
x = i[0] ; y = i[1]
color = matrix[x][y]
ic(color)
colors.append(color)
colors = pack(colors)
ic(colors)
self.send_response(200)
self.send_header('Content-type', 'text/plain')
self.end_headers()
self.wfile.write(f'{colors}'.encode())
else:
self.send_response(200)
self.send_header('Content-type', 'image/png')
self.end_headers()
matrix = self.get_matrix()
matrix = np.flip(matrix, axis=0) #Fix flip on server side
self.send_image(matrix)
def do_POST(self):
global LTIME
cur_time = time.monotonic()
if cur_time - LTIME <= 0.0001:
self.send_error(429, 'Too Many Requests')
self.send_response(429)
return 0
else:
LTIME = time.monotonic()
content_length = int(self.headers['Content-Length'])
body = self.rfile.read(content_length)
params = parse_qs(body.decode('utf-8'))["main"][0]
ic(params)
# Parse token
ic( parse_qs(body.decode('utf-8')) )
token = parse_qs(body.decode('utf-8'))["token"][0]
#Set limit pixels for 1 response
ic(len(params))
if len(params) > 6700:
# Get tokens
tokens = tokens_load()
# Admin's token
if token[0] == tokens["admin"][0]:
pass
elif token[0] in tokens["premium"] and len(params) < 13400:
pass
else:
return 0
matrix = self.get_matrix()
ll = unpack(params)
for i in ll:
x = i[1] ; y = i[0] #Fix (y, x) -> (x, y) on server side
matrix[x, y] = [i[2], i[3], i[4]]
self.save_matrix(matrix)
self.send_response(302)
self.send_header('Location', '/')
self.end_headers()
def get_matrix(self):
try:
with open('matrix.npy', 'rb') as f:
matrix = np.load(f)
except FileNotFoundError:
matrix = np.full(shape=(*self.MATRIX_SIZE, 3), fill_value=255, dtype=np.uint8)
self.save_matrix(matrix)
return matrix
def save_matrix(self, matrix):
with open('matrix.npy', 'wb') as f:
np.save(f, matrix)
def send_image(self, matrix):
image = Image.fromarray(matrix)
buffer = BytesIO()
image.save(buffer, format='PNG')
self.wfile.write(buffer.getvalue())
def run():
server = HTTPServer(('127.0.0.1', 3333), RequestHandler)
server.serve_forever()
while True:
try:
run()
print(1)
except KeyboardInterrupt:
exit()
except:
pass
+1
View File
@@ -0,0 +1 @@
Special thanks to Holinim.
+37
View File
@@ -0,0 +1,37 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>PixelBoard</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;500&family=Nunito:wght@300&display=swap" rel="stylesheet">
<script>
setInterval(function() {
var image = document.getElementById('PBImage');
image.src = 'http://pb.gulyaipole.fun/' + new Date().getTime();
}, 2000);
</script>
</head>
<body bgcolor="#DAA06D"> <!--Old color - #1c5ca6-->
<button onclick="window.location.href='live_black.html';" style='background-color:#7e4a12; border-radius: 1000px'>
<img src="https://cdn.icon-icons.com/icons2/1674/PNG/32/moon_111148.png">
</button>
<p align = "center"><b><font face="Montserrat" size='5' width="500">Пиксельная доска</font></b></p>
<p align = "center">
<img id="PBImage" src="http://pb.gulyaipole.fun:3333" onclick="window.location.href='https://pb.gulyaipole.fun:3333'" height=640 style="border: 8px solid #dbac83">
<br>
<button onclick="window.location.href='https://gitea.gulyaipole.fun/justuser/pxl_oboard';" style="background-color: #c5792d; border-radius: 1000px">
<font face="Montserrat" width="400">Репозиторий проекта</font>
</button>
<button onclick="window.location.href='https://docs.google.com/document/d/1hEccpHxwDQrpTW7RMmf3lqYtJIDh1Fwb';" style="background-color: #c5792d; border-radius: 1000px">
<font face="Montserrat" width="400">Как рисовать на доске?</font>
</button>
<button onclick="window.location.href='https://t.me/pxl_oboard';" style="background-color: #c5792d; border-radius: 1000px">
<font face="Montserrat" width="400">Telegram проекта</font>
</button>
<br><br>
<b><font face="Montserrat" width="300">Правила проекта:</font></b>
<font face="Nunito"><br>1. Уважать других - не перекрывать/закрашивать чужие рисунки<br>2. Рисунки не должны представлять из себя 18+ контент или пропаганду LGBT.<br>3. Рисунки не должны нарушать законы Российской Федерации.</font>
</body>
</html>
+37
View File
@@ -0,0 +1,37 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>PixelBoard</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;500&family=Nunito:wght@300&display=swap" rel="stylesheet">
<script>
setInterval(function() {
var image = document.getElementById('PBImage');
image.src = 'http://pb.gulyaipole.fun/' + new Date().getTime();
}, 2000);
</script>
</head>
<body bgcolor="#06111f">
<button onclick="window.location.href='index.html';" style='background-color:#0484da; border-radius: 1000px'>
<img src="https://cdn.icon-icons.com/icons2/1325/PNG/32/fun4x_86984.png">
</button>
<p align = "center"><b><font face="Montserrat" size='5' width="500" color='white'>Пиксельная доска</font></b></p>
<p align = "center">
<img id="PBImage" src="http://pb.gulyaipole.fun:3333" onclick="window.location.href='https://pb.gulyaipole.fun:3333'" height=640 style="border: 8px solid #101655">
<br>
<button onclick="window.location.href='https://gitea.gulyaipole.fun/justuser/pxl_oboard';" style="background-color: #112f4d; border-radius: 1000px">
<font face="Montserrat" color='white' width="400">Репозиторий проекта</font>
</button>
<button onclick="window.location.href='https://docs.google.com/document/d/1hEccpHxwDQrpTW7RMmf3lqYtJIDh1Fwb';" style="background-color: #112f4d; border-radius: 1000px">
<font face="Montserrat" color='white' width="400">Как рисовать на доске?</font>
</button>
<button onclick="window.location.href='https://t.me/pxl_oboard';" style="background-color: #112f4d; border-radius: 1000px">
<font face="Montserrat" color='white' width="400">Telegram проекта</font>
</button>
<br><br>
<b><font face="Montserrat" color='white' width="300">Правила проекта:</font></b>
<font face="Nunito" color='white'><br>1. Уважать других - не перекрывать/закрашивать чужие рисунки<br>2. Рисунки не должны представлять из себя 18+ контент или пропаганду LGBT.<br>3. Рисунки не должны нарушать законы Российской Федерации.</font>
</body>
</html>