PrusaSlicer
PrusaSlicer copied to clipboard
Feature Request: add mks-preview encoding for g-code thumbnails
Thumbnails embedded in g-code are not displayed on printers with Marlin firmware and interface from MKS or SHUI due to the fact that Prusa Slicer uses PNG format to compress them. If it was possible to choose the mks-preview image coding method, then the problem would be solved.
Script for converting prusa-preview to mks-preview:
import os
import struct
from sys import argv
import re
from PIL import Image
import base64
from io import BytesIO
data=None
file_in="/home/shubin/Downloads/Telegram Desktop/Doc_merged_idea_PLA_0.2mm_14h4m.gcode"
file_out="/home/shubin/Downloads/Telegram Desktop/Doc_merged_idea_PLA_0.2mm_14h4m_shui.gcode"
with open(file_in, "r") as g_gile:
data=g_gile.readlines()
g_gile.close()
thumbs=[]
current_thumb=None
meta={}
def check_key(data, key, value_key):
if (data.startswith(key)):
meta[value_key]=d[len(key):].strip()
return True
return False
index=0
for d in data:
index+=1
if current_thumb==None:
if (d.startswith("; thumbnail begin")):
current_thumb = {"base64":""}
current_thumb["start_row"] = index - 1
thumbs.append(current_thumb)
continue
if check_key(d, "; filament used [mm] = ", "filament used"):
continue
if check_key(d, "; estimated printing time (normal mode) = ", "printing time"):
continue
if check_key(d, "; layer_height = ", "layer_height"):
continue
if (d.startswith("; thumbnail end")) and (current_thumb!=None):
current_thumb["end_row"] = index - 1
current_thumb=None
continue
if current_thumb!=None:
str=d.strip()[2:]
current_thumb["base64"]+=str
large_preview=None
small_preview=None
for t in thumbs:
stream=BytesIO(base64.b64decode(t["base64"]))
image=Image.open(stream).convert("RGB")
stream.close()
if (image.height==image.width):
if image.height==200:
large_preview=image
if (image.height==100) or (image.height==50):
small_preview=image
def generate_preview(preview):
size=preview.width
res=""
index=0
row = bytearray()
for d in preview.getdata():
r=d[0]>>3
g=d[1]>>2
b=d[2]>>3
rgb = (r << 11) | (g << 5) | b
row.append((rgb >> 8) & 0xFF)
row.append(rgb & 0xFF)
index+=1
if (index==size):
index=0;
res += ";" + base64.b64encode(row).decode('utf-8') + "\n"
row = bytearray()
return res
def dummy_filter(idx):
return True
def thumb_filter(idx):
for t in thumbs:
if (t["start_row"]<=idx) and (t["end_row"]>=idx):
return False
return True
with open(file_out, "w") as out_gile:
filter_proc=dummy_filter
if (large_preview!=None) and (small_preview!=None):
filter_proc=thumb_filter
out_gile.write(";SHUI PREVIEW {}x{}\n".format(small_preview.width, small_preview.width))
out_gile.write(generate_preview(small_preview))
out_gile.write(generate_preview(large_preview))
out_gile.write(";POSTPROCESSING SHUI PRUSHA PLUGIN\r\n")
if meta["filament used"]!=None:
f_used=float(meta["filament used"])
out_gile.write(";Filament used: {:1.5f}\r\n".format(f_used/1000))
if meta["layer_height"]!=None:
layer_height=float(meta["layer_height"])
out_gile.write(";Layer height: {:1.2f}\r\n".format(layer_height))
if meta["printing time"]!=None:
match = re.match('((\d+)h\s)((\d+)m\s)((\d+)s\s*)?', meta["printing time"])
time=0
if (match[6]!=None):
time+=int(match[6])
if (match[4]!=None):
time+=int(match[4])*60
if (match[2]!=None):
time+=int(match[4])*60*60
out_gile.write(";TIME:{}\r\n".format(time))
index=0
for d in data:
if filter_proc(index):
out_gile.write(d)
index+=1
Examples: https://github.com/vyacheslav-shubin/shui/tree/master/misc/preview-test

I am leaving the issue open flagged with "volunteer needed', but a pull request will only be accepted if enough of interest will be voiced by others.
@RandoMan70 You may be interested to implement the MKS thumbnail format for PrusaSlicer 2.5 now that we have a framework for other thumbnail formats in place, see https://github.com/prusa3d/PrusaSlicer/commit/87cff55856ae14096cd57f8e2542f1f1caef7167
Support for this feature is needed
Please add this feature
add my vote for this feature