Skip to content

Instantly share code, notes, and snippets.

@X3msnake
Last active June 30, 2021 01:06
Show Gist options
  • Save X3msnake/df030169d715703b862f445d8b4ad8dc to your computer and use it in GitHub Desktop.
Save X3msnake/df030169d715703b862f445d8b4ad8dc to your computer and use it in GitHub Desktop.
Anycubic Photon UI - CBD boards - Gimp Builder Plugin references

Corel Draw get selected files position

Debugging

Oberon Forum

How to list sizes on a symbol library

How to set document units from ruler

Reseting VBA passwords via HEX editor:

# Load Gimp libraries
from gimpfu import *
# Load first image and display it (since files start with a number we need double slashes to escape the value)
image_5 = pdb.gimp_file_load("C:\Users\X3msnake\Desktop\UI_EPAX\\5.bmp", "5")
display = pdb.gimp_display_new(image_5)
# Load File as Layer and insert it into a open image
layer_77 = pdb.gimp_file_load_layer(image_5, "C:\Users\X3msnake\Desktop\UI_EPAX\\77.bmp")
pdb.gimp_image_insert_layer(image_5, layer_77, None , -1)
# Get layer current position and move it to a new place starting from 0,0
x_off, y_off = layer_77.offsets
pdb.gimp_layer_translate(layer_77, 22 - x_off, 165 - y_off)
# Import CSV into arrays > https://docs.python.org/2/library/csv.html
import csv
with open('C:\Users\X3msnake\Desktop\UI_EPAX\UItable.csv', 'rb') as csvfile:
spamreader = csv.reader(csvfile, delimiter=' ', quotechar='|')
for row in spamreader:
print ', '.join(row)
#,Image, UID,Offset,Xpos,Ypos,Xwidth,Yheight,Reserved
#,0,0,0,0,0,0,0
#,1,7148,0,0,480,320,0
# Load CSV as Dictionary, parse to List and read individual values
# > https://stackoverflow.com/questions/36153584/python-find-specific-row-attribute-with-dictreader
with open("C:\Users\LS\Desktop\extractor\PSHCNET\UItable.csv", mode='r') as csv_file:
csv_reader = csv.DictReader(csv_file)
data = list(csv_reader)
print data[1]
# {'Xpos': '0', 'Reserved': '0', 'Yheight': '240', 'Ypos': '0', 'Image UID': '1', 'Offset': '7148', 'Xwidth': '320'}
print data[2]
# {'Xpos': '0', 'Reserved': '0', 'Yheight': '240', 'Ypos': '0', 'Image UID': '2', 'Offset': '7234', 'Xwidth': '320'}
print data[2]["Xpos"]
# 0
print data[2]["Reserved"]
# 0
print data[2]["Image UID"]
# 2
print data[2]["Offset"]
# 7234
# Another way to load using reader
def pl():
with open("C:\Users\LS\Desktop\extractor\PSHCNET\UItable.csv") as csv_file:
csv_reader = csv.reader(csv_file, delimiter=',')
line_count = 0
for row in csv_reader:
if line_count == 0:
print(row)
line_count += 1
else:
print("UID:"+row[0]+" Xpos:"+row[3]+" Ypos:"+row[4])
line_count += 1
print({line_count})
pl()
# RETURNS THIS:
#['Image UID', 'Offset', 'Xpos', 'Ypos', 'Xwidth', 'Yheight', 'Reserved']
#UID:0 Xpos:0 Ypos:0
#UID:1 Xpos:0 Ypos:320
#UID:2 Xpos:0 Ypos:320
#UID:3 Xpos:0 Ypos:320
#UID:4 Xpos:0 Ypos:320
#UID:5 Xpos:0 Ypos:320
#UID:6 Xpos:0 Ypos:320
#UID:7 Xpos:0 Ypos:320
#!/usr/bin/env python
# GIMP Python plug-in to build edit and export CBD board printers UIs
# for printers like Anycubic Photon, Epax, Orbeat...
# Copyright 2019 X3msnake
#
# --------------------------------------------------------------------
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# If you want the plugin to be nested inside a folder on the gimp plugins folder, the nested folder name must be the same as the python file
import csv
import logging
import sys
from gimpfu import *
def ph_ui_builder(ph_dir, ph_csv, ph_ui_name):
pdb.gimp_message_set_handler(2) #Send messages to gimp debug window
pdb.gimp_message("DIR:"+ ph_dir +"\n"+ "CSV: "+ ph_csv )
try:
# Import CSV and pass the variable set by user on the UI
ph_load_csv(ph_dir, ph_csv,ph_ui_name)
except Exception as e:
# catch python errors and show them as popups to the user
e_msg(e)
return
def ph_load_csv(ph_directory, ph_csv_table, ph_project_name):
# Debug check if the passed variable is a string
pdb.gimp_message(type(ph_csv_table))
# CSV columns should be like this
#[0]'Image UID', [1]'Offset', [2]'Xpos', [3]'Ypos', [4]'Xwidth', [5]'Yheight', [6]'Reserved']
with open(ph_csv_table) as csv_file:
csv_reader = csv.reader(csv_file, delimiter=',')
line_count = 0
debug_table = ""
for row in csv_reader:
# Ignore first line since this is the header
if line_count == 0:
pdb.gimp_message(row)
line_count += 1
else:
UID = int(row[0] ,0)
Offset = int(row[1] ,0)
Xpos = int(row[2] ,0)
Ypos = int(row[3] ,0)
Xwidth = int(row[4] ,0)
Yheight = int(row[5] ,0)
Reserved = int(row[6] ,0)
# Extract the UI base size from the first image [ 2.8"(320x240) | 3.5"(480x320) | 5.0"(480x272) ]
if UID == 1 and line_count < 3:
debug_ui_size = str(Xwidth)+"x"+str(Yheight)
ph_build_basefile(ph_project_name, Xwidth, Yheight)
pdb.gimp_message(type(ph_new_image))
#Define layer groups
ph_layers_main = [["ui_print", "PRINT"], ["ui_system", "SYSTEM"], ["ui_tool","TOOLS"]]
ph_layers_ui_print = [["ui_fileinfo", "FileInfo"], ["ui_printing", "Printing..."], ["ui_printingcfg", "PrintConfig"], ["ui_numpadkeys", "Numpad"]]
ph_layers_ui_system = [["ui_sysinfo", "SystemInfo"], ["ui_network","Network"], ["ui_service", "Support"]]
ph_layers_ui_tool =[["ui_move", "ManualMove"], ["ui_calibrate", "Calibrate"], ["ui_test","Test"]]
pdb.gimp_message(ph_layers_main[0])
pdb.gimp_message(ph_layers_main[0][1])
#Create Layer Group and add layer to image
ui_main_menu = pdb.gimp_layer_group_new(ph_new_image)
pdb.gimp_image_insert_layer(ph_new_image, ui_main_menu, None , -1)
ui_main_menu.name = "MAIN-MENU"
#Create Main Layers
ph_layers_main[0][0] = pdb.gimp_layer_group_new(ph_new_image)
pdb.gimp_image_insert_layer(ph_new_image, ph_layers_main[0][0], ui_main_menu , 1)
ph_layers_main[0][0].name = ph_layers_main[0][1]
ph_layers_main[1][0] = pdb.gimp_layer_group_new(ph_new_image)
pdb.gimp_image_insert_layer(ph_new_image, ph_layers_main[1][0], ui_main_menu , 1)
ph_layers_main[1][0].name = ph_layers_main[1][1]
ph_layers_main[2][0] = pdb.gimp_layer_group_new(ph_new_image)
pdb.gimp_image_insert_layer(ph_new_image, ph_layers_main[2][0], ui_main_menu , 1)
ph_layers_main[2][0].name = ph_layers_main[2][1]
if UID != 0 :
# Concatenate a debug_table
debug_table = debug_table+"UID:" +str(UID)+ "| Off7:" +str(Offset)
debug_table = debug_table+"| Xpos:" +str(Xpos)+ "| Ypos:" +str(Ypos)
debug_table = debug_table+"| Xwidth:" +str(Xwidth)+ "| Yheight:" +str(Yheight)
debug_table = debug_table+"| Res:" +str(Reserved)+ "\n"
# Define target Layer
target_layer = None
if (UID == 1) or (UID == 151):
target_layer = pdb.gimp_image_get_layer_by_name(ph_new_image, "MAIN-MENU")
if (UID == 5) or (UID == 155):
target_layer = pdb.gimp_image_get_layer_by_name(ph_new_image, "PRINT")
if UID == 154 or UID == 4:
target_layer = pdb.gimp_image_get_layer_by_name(ph_new_image, "FileInfo")
if UID == 163 or UID == 13:
target_layer = pdb.gimp_image_get_layer_by_name(ph_new_image, "Printing...")
if UID == 162 or UID == 12:
target_layer = pdb.gimp_image_get_layer_by_name(ph_new_image, "PrintConfig")
if UID == 161 or UID == 11:
target_layer = pdb.gimp_image_get_layer_by_name(ph_new_image, "Numpad")
if UID == 2 or UID == 152:
target_layer = pdb.gimp_image_get_layer_by_name(ph_new_image, "SYSTEM")
if UID == 157 or UID == 7:
target_layer = pdb.gimp_image_get_layer_by_name(ph_new_image, "SystemInfo")
if UID == 215 or UID == 214:
target_layer = pdb.gimp_image_get_layer_by_name(ph_new_image, "Network")
if UID == 290 or UID == 289:
target_layer = pdb.gimp_image_get_layer_by_name(ph_new_image, "Support")
if UID == 3 or UID == 153:
target_layer = pdb.gimp_image_get_layer_by_name(ph_new_image, "TOOLS")
if UID == 156 or UID == 6:
target_layer = pdb.gimp_image_get_layer_by_name(ph_new_image, "ManualMove")
if UID == 352:
target_layer = pdb.gimp_image_get_layer_by_name(ph_new_image, "Calibrate")
if UID == 355:
target_layer = pdb.gimp_image_get_layer_by_name(ph_new_image, "Test")
# Load File as Layer and insert it into a open image
UID = pdb.gimp_file_load_layer(ph_new_image, ph_directory+"\\"+str(UID)+".bmp")
pdb.gimp_image_insert_layer(ph_new_image, UID, target_layer , 0)
# Get layer current position and move it to a new place starting from 0,0
x_off, y_off = UID.offsets
pdb.gimp_layer_translate(UID, Xpos - x_off, Ypos - y_off)
line_count += 1
#Print debug_table and other infos on console
pdb.gimp_message(debug_table)
pdb.gimp_message({line_count})
pdb.gimp_message(type(UID))
pdb.gimp_message(debug_ui_size)
# Render image on screen > depends on sucess of ph_buil_basefile()
display = pdb.gimp_display_new(ph_new_image)
return
# Function creates a new base file to hold the layers based on user input
def ph_build_basefile(ph_basefile_name, ph_basefile_width, ph_basefile_height, ph_image_depth = 0):
# Debug basefile pass
pdb.gimp_message("Building " + ph_basefile_name + " basefile...")
# Set image holder variable as global so we can access it from outside this function
global ph_new_image
# Create a new image based on the first value of the user passed table
ph_new_image = pdb.gimp_image_new(ph_basefile_width, ph_basefile_height, ph_image_depth)
# Set name of the new file from user input form
pdb.gimp_image_set_filename(ph_new_image, ph_basefile_name)
# Error message function, sets errors as popups and prints a passed message
def e_msg(ph_message):
pdb.gimp_message_set_handler(0)
pdb.gimp_message(ph_message)
register(
"python_fu_photon_ui_builder",
"Photon ui builder",
"rebuilds CBD board ui from sprites and csv table",
"X3msnake",
"Photonsters",
"2010",
"Photon Ui Builder...",
"", # Alternately use RGB, RGB*, GRAY*, INDEXED etc.
[
(PF_DIRNAME, "ph_dir", "IMAGE FOLDER", "/tmp"),
(PF_FILE, "ph_csv", "CSV FILE", "nofile"),
(PF_STRING, "ph_ui_name", "UI new name", "Untitled"),
#(PF_INT, "number", "Number?", 50),
#(PF_FLOAT, "angle", "Angle", 3.14159),
# you can also use PF_INT8, PF_INT16, PF_INT32
#(PF_STRING, "word", "Word", "Zebrafish!"),
# PF_VALUE is another term for PF_STRING
#(PF_TEXT, "text", "Some Text",
# "The quick red fox jumped over the lazy dog"),
#(PF_COLOR, "bg-color", "Background", (1.0, 1.0, 1.0)),
# or you can spell it PF_COLOUR
#(PF_IMAGE, "image", "Input image", None),
#(PF_LAYER, "layer", "Input layer", None),
#(PF_CHANNEL, "channel", "Which channel", None),
#(PF_DRAWABLE, "drawable", "Input drawable", None),
#(PF_TOGGLE, "shadow", "Shadow?", 1),
#(PF_BOOL, "ascending", "_Ascending", True),
#(PF_RADIO, "imagefmt", "Image format", "jpg",
# (("png", "png"), ("jpg", "jpg"))),
#(PF_OPTION, "option", "Option", 2, ("Mouse", "Cat", "Dog", "Horse")),
#(PF_SPINNER, "size", "Pixel Size", 50, (1, 8000, 1)),
#(PF_SLIDER, "opacity", "Op_acity", 100, (0, 100, 1)),
#(PF_ADJUSTMENT is the same as PF_SPINNER
#(PF_FONT, "font", "Font", "Sans"),
#(PF_BRUSH, "brush", "Brush", None),
#(PF_PATTERN, "pattern", "Pattern", None),
#(PF_GRADIENT, "gradient", "Gradient", None),
#(PF_PALETTE, "palette", "Palette", ""),
# New items that don't quite work yet:
#(PF_VECTORS, "vectors", "Vectors", None),
#(PF_DISPLAY, "display", "Display", None),
],
[],
ph_ui_builder, menu="<Image>/PhotonTools" )
main()
@echo off
set /p folder=IMAGE FOLDER:
set /p file=UI NEW UI FILENAME:
echo.
echo Compiling... %folder% sprites to %file%
echo.
UIgenerator.exe %folder% %file%
echo.
echo done.
echo.
pause
@echo off
set /p file=UI FILENAME:
set /p folder=EXTRACT FOLDER:
echo.
echo extracting... %file% to %folder%
echo.
UIextractor.exe %file% %folder%
echo.
echo done.
echo.
pause

// English screens 151:MainMenu;19,223,224 152:System;231,226,250,227,230 153:Tools;237,238,232,342,235 154:PrintConfirm;139,252,251,253 155:PrintSelect;77,78,79,254,255,256 156:Move;45,46,49,50,51,52,53,142 157:Firmware;104,105,106,107,108 162:PrintingOverrides;123,126,124,125,89 163:Printing;121,120,340,140,83,80,82 215:Network;220,221,216,217,218,219,222,301,302 290:SupportInfo; 352:ExposureTest;343,344,345,347,348,349

// Chinese screens 1:MainMenu;20,21,22 2:System;25,36,24,29,28 3:Tools;35,87,33,341,30 5:PrintSelect;(77,78,79,254,255,256) 6:Move;(45,46,49,50,51,52,53,142) 7:Firmware;(104,105,106,107,108) 12:PrintingOverrides;(123,126,124,125,89) 13:Printing;(121,120,340,140,83,80,82) (154:PrintConfirm;139,252,251,253) 214:Network;(220,221,216,217,218,219,222,301,302) 289:SupportInfo; (352:ExposureTest);346(,343,344,345,348,349)

// Common screens 161:Numpad;62,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76 355:TestingExposure;351,354

@X3msnake
Copy link
Author

X3msnake commented Jun 6, 2019

Examples

https://gimpbook.com/scripting/

Basics

https://www.neuraldump.net/2017/01/program-python-plug-ins-for-gimp-hello-gimp-world/

Debugging

https://stackoverflow.com/questions/20763448/writing-gimp-plugins-in-python-on-windows-how-do-i-debug-where-is-the-output

Video Tutorials on scripting with pythong for Gimp

https://www.youtube.com/watch?v=cPQRxZo9BJE&list=PLyRItRv4aHfOuUC8a1SMeTLV08wxdnWt-

Web tutorials

https://www.tablix.org/~avian/blog/articles/talks/extending_gimp_python.pdf (Plugin Basics)
https://www.gimp.org/docs/python/index.html (python on gimp)
https://realpython.com/python-csv/ (parsing csv with python)
https://realpython.com/iterate-through-dictionary-python/ (iterate dictionaries)
https://www.geeksforgeeks.org/python-check-values-list-greater-given-value/ (Comparing sigle values to a array - Transversing a list)
https://stackoverflow.com/questions/10221926/get-sublayers-from-group-layer-with-python-in-gimp/10314140 (Manipulate Layers)
https://gitlab.gnome.org/GNOME/gimp/issues/1119 (some scripts about layers)
https://stackoverflow.com/questions/3620943/measuring-elapsed-time-with-the-time-module/47637891#47637891

Important Tips

dir() shows a list of all the available constants, classes and instances
dir(pdb.something).... shows the list of properties of a given class
dir(pdb.something.something) list properties of properties...

Potential Usefull Plugins

https://github.com/crapola/PixInflate (inflate pixels cradinally - maybe usable for erode?)
https://github.com/avian2/gimp-plugin-onion-layers (Onion Skin Layers - Maybe usefull if we implement a Photon2xfc plugin)

@X3msnake
Copy link
Author

X3msnake commented Jun 11, 2019

TODO PHOTON:

  • Create AA based Resin Exposure finder (césar tool)
  • UI Fimrware Hacked colours tool
  • Test UI SDcard Icons Extras

-RCOMPARE
-- https://www.smashingmagazine.com/2017/08/designing-perfect-feature-comparison-table/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment