OrganiLAB 1.6.1: organizador, actualizador, interfaz 1.6 y publicación
Primer commit del proyecto. Incluye el rediseño 1.6 (riel de pasos en la barra lateral), el actualizador con reintentos y respaldo, publicar.sh y la nueva opción de desconectar carpetas (1.6.1). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Este commit está contenido en:
71
hacer_icono.py
Archivo normal
71
hacer_icono.py
Archivo normal
@@ -0,0 +1,71 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Genera static/organilab.png (256 px) y static/organilab.ico (256/48/32/16) sin dependencias:
|
||||
el logo OrganiLAB, cuadrado azul redondeado con tres barras blancas."""
|
||||
import os
|
||||
import zlib
|
||||
import struct
|
||||
|
||||
AQUI = os.path.dirname(os.path.abspath(__file__))
|
||||
AZUL = (0x1F, 0x57, 0xD6)
|
||||
|
||||
|
||||
def pinta(n):
|
||||
"""devuelve filas RGBA del logo a n×n"""
|
||||
r = n * 7 / 32 # radio de las esquinas (7/32 como el SVG)
|
||||
barras = [(8, 18, 1.0), (14, 13, .85), (20, 8, .65)] # (y, ancho, opacidad) en unidades de 32
|
||||
filas = []
|
||||
for y in range(n):
|
||||
fila = bytearray()
|
||||
for x in range(n):
|
||||
# cuadrado redondeado con antialias sencillo (4 muestras)
|
||||
dentro = 0
|
||||
for sx, sy in ((.25, .25), (.75, .25), (.25, .75), (.75, .75)):
|
||||
px, py = x + sx, y + sy
|
||||
cx = min(max(px, r), n - r)
|
||||
cy = min(max(py, r), n - r)
|
||||
if (px - cx) ** 2 + (py - cy) ** 2 <= r * r:
|
||||
dentro += 1
|
||||
a = dentro / 4
|
||||
if a == 0:
|
||||
fila += bytes((0, 0, 0, 0))
|
||||
continue
|
||||
col = list(AZUL)
|
||||
for by, bw, op in barras:
|
||||
y0, y1 = by * n / 32, (by + 4) * n / 32
|
||||
x0, x1 = 7 * n / 32, (7 + bw) * n / 32
|
||||
rb = 2 * n / 32
|
||||
if y0 <= y + .5 < y1 and x0 <= x + .5 < x1:
|
||||
# esquinas de la barra redondeadas
|
||||
cx = min(max(x + .5, x0 + rb), x1 - rb)
|
||||
cy = min(max(y + .5, y0 + rb), y1 - rb)
|
||||
if (x + .5 - cx) ** 2 + (y + .5 - cy) ** 2 <= rb * rb:
|
||||
col = [int(c + (255 - c) * op) for c in AZUL]
|
||||
fila += bytes((col[0], col[1], col[2], int(255 * a)))
|
||||
filas.append(bytes(fila))
|
||||
return filas
|
||||
|
||||
|
||||
def png(n):
|
||||
filas = pinta(n)
|
||||
raw = b"".join(b"\x00" + f for f in filas)
|
||||
|
||||
def chunk(t, d):
|
||||
return struct.pack(">I", len(d)) + t + d + struct.pack(">I", zlib.crc32(t + d) & 0xffffffff)
|
||||
return (b"\x89PNG\r\n\x1a\n" + chunk(b"IHDR", struct.pack(">IIBBBBB", n, n, 8, 6, 0, 0, 0))
|
||||
+ chunk(b"IDAT", zlib.compress(raw, 9)) + chunk(b"IEND", b""))
|
||||
|
||||
|
||||
tamanos = (256, 48, 32, 16)
|
||||
imgs = [png(t) for t in tamanos]
|
||||
with open(os.path.join(AQUI, "static", "organilab.png"), "wb") as fh:
|
||||
fh.write(imgs[0])
|
||||
# ICO con PNG incrustados (válido desde Windows Vista)
|
||||
cab = struct.pack("<HHH", 0, 1, len(tamanos))
|
||||
off = 6 + 16 * len(tamanos)
|
||||
entradas = b""
|
||||
for t, im in zip(tamanos, imgs):
|
||||
entradas += struct.pack("<BBBBHHII", t % 256, t % 256, 0, 0, 1, 32, len(im), off)
|
||||
off += len(im)
|
||||
with open(os.path.join(AQUI, "static", "organilab.ico"), "wb") as fh:
|
||||
fh.write(cab + entradas + b"".join(imgs))
|
||||
print("icono listo:", [len(i) for i in imgs])
|
||||
Referencia en una nueva incidencia
Block a user