236 lines
9.8 KiB
HTML
236 lines
9.8 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
|
|
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
|
|
<meta http-equiv="Pragma" content="no-cache">
|
|
<meta http-equiv="Expires" content="0">
|
|
<title>Led Matrix Pixel Art Convertor</title>
|
|
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
|
|
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
|
|
<link rel="manifest" href="/site.webmanifest">
|
|
</head>
|
|
|
|
<body>
|
|
<div class = top-part>
|
|
<h1>Led Matrix Pixel Art Converter</h1>
|
|
<h2>Convert image to WLED JSON (pixel art on WLED matrix)</h2>
|
|
<p>
|
|
<table id="fieldTable" style="width: 100%; table-layout: fixed; align-content: center;">
|
|
<tr>
|
|
<td style="vertical-align: middle;">
|
|
<label for="ledSetupSelector">Led setup:</label>
|
|
</td>
|
|
<td style="vertical-align: middle;">
|
|
<select id="ledSetupSelector">
|
|
<option value="matrix" selected>2D Matrix</option>
|
|
<option value="r2l">Serpentine, first row right to left <-</option>
|
|
<option value="l2r">Serpentine, first row left to right -></option>
|
|
</select>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="vertical-align: middle;">
|
|
<label for="formatSelector">Output format:</label>
|
|
</td>
|
|
<td style="vertical-align: middle;">
|
|
<select id="formatSelector">
|
|
<option value="wled" selected>WLED JSON</option>
|
|
<option value="curl">CURL</option>
|
|
<option value="ha">Home Assistant YAML</option>
|
|
</select>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="vertical-align: middle;">
|
|
<label for="colorFormatSelector">Color code format:</label>
|
|
</td>
|
|
<td style="vertical-align: middle;">
|
|
<select id="colorFormatSelector">
|
|
<option value="hex" selected>HEX (#f4f4f4)</option>
|
|
<option value="dec">DEC (244,244,244)</option>
|
|
</select>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="vertical-align: middle;">
|
|
<label for="addressingSelector">Addressing:</label>
|
|
</td>
|
|
<td style="vertical-align: middle;">
|
|
<select id="addressingSelector">
|
|
<option value="range" selected>Range (10, 17, #f4f4f4)</option>
|
|
<option value="single">Single (#f4f4f4)</option>
|
|
</select>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="vertical-align: middle;">
|
|
<label for="brightnessNumber">Brightness:</label>
|
|
</td>
|
|
<td style="vertical-align: middle; display: flex; align-items: center;">
|
|
<input type="range" id="brightnessNumber" min="1" max="255" value="127">
|
|
<span id="brightnessValue">100</span>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="vertical-align: middle;">
|
|
<label for="colorLimitNumber">Max no of colors/JSON:</label>
|
|
</td>
|
|
<td style="vertical-align: middle; display: flex; align-items: center;">
|
|
<input type="range" id="colorLimitNumber" min="1" max="512" value="256">
|
|
<span id="colorLimitValue" >256</span>
|
|
</td>
|
|
</tr>
|
|
<tr class="ha-hide">
|
|
<td style="vertical-align: middle;">
|
|
<label for="haID">HA Device ID:</label>
|
|
</td>
|
|
<td style="vertical-align: middle;">
|
|
<input type="text" id="haID" value="pixel_art_controller_001">
|
|
</td>
|
|
</tr>
|
|
<tr class="ha-hide">
|
|
<td style="vertical-align: middle;">
|
|
<label for="haUID">HA Device Unique ID:</label>
|
|
</td>
|
|
<td style="vertical-align: middle;">
|
|
<input type="text" id="haUID" value="pixel_art_controller_001a">
|
|
</td>
|
|
</tr>
|
|
<tr class="ha-hide">
|
|
<td style="vertical-align: middle;">
|
|
<label for="haName">HA Device Name:</label>
|
|
</td>
|
|
<td style="vertical-align: middle;">
|
|
<input type="text" id="haName" value="Pixel Art Kitchen">
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="vertical-align: middle;">
|
|
<label for="curlUrl">Device IP/host name:</label>
|
|
</td>
|
|
<td style="vertical-align: middle;">
|
|
<input type="text" id="curlUrl" value="">
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="vertical-align: middle;">
|
|
<label for="renderCheckbox">Show pixel rendering</label>
|
|
</td>
|
|
<td style="vertical-align: middle;">
|
|
<input type="checkbox" id="renderCheckbox" checked>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="vertical-align: middle;">
|
|
<label for="helpCheckbox">Show help/about</label>
|
|
</td>
|
|
<td style="vertical-align: middle;">
|
|
<input type="checkbox" id="helpCheckbox">
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
|
|
</p>
|
|
</p>
|
|
|
|
<div id="help-container" style="display: none">>
|
|
<p>
|
|
1a. Create a GIF or PNG ( <a href="https://www.pixilart.com/" target="_blank">www.pixilart.com</a> ) <br>
|
|
1b. Download some image that fits your led matrix ( <a href="https://www.spriters-resource.com/" target="_blank">www.spriters-resource.com</a>) <br>
|
|
2. Upload the image using the file picker or drag-and-drop it <br>
|
|
3. Select the led setup that matches your WLED. ( <a href="https://kno.wled.ge/advanced/mapping/" target="_blank">https://kno.wled.ge</a>) <br>
|
|
4. Select Otput format. <br>
|
|
- WLED is pure JSON in the way the documentation descripbes it.<br> Use in WLED (presets?)<br>
|
|
- CURL is formated as a curl command you can past into a command <br> window and test yor led matrix<br>
|
|
- Home Assistant is teh full YAML you can past into your <br> configuration.yaml in Home Assistant<br>
|
|
5. Select Color format. Select HEX if possible (more efficiant)<br>
|
|
6. Select Addressing scheme. Send all pixels individually or try to <br> send ranges of the same color.<br>
|
|
7. Select brighness value<br>
|
|
8. According to docs WLED can handle max 256 colors/command. So the JSON is <br> split if you have larger images. <br> Lower this value if you have issues.<br>
|
|
9. Set Home Assistant Device values if you are going to use HA<br>
|
|
10. Set the device IP/host for HA and CURL to work<br>
|
|
11. Press the convert button <br>
|
|
12. Copy the generated JSON and put it somewhere in WLED<br> , Run CURL or paste to Home Assistant
|
|
</p>
|
|
<p>
|
|
This tool is a proof of concept and work in progress. As you might expect, there is absolutely no warranty, what so ever.
|
|
</p>
|
|
<p>
|
|
The Arcade font is copyright (c) Jakob Fischer at www.pizzadude.dk, all rights reserved. Do not distribute without the author's permission.
|
|
</p>
|
|
<p>
|
|
It should be said that I don‘t acctually own a setup for this. I basically did it to play around over new years. But I have ordered a matrix now, and a small controller chip... let's see how that works out.
|
|
</p>
|
|
</div>
|
|
|
|
<p>
|
|
<label for="file-picker">
|
|
<div id="drop-zone">
|
|
Drop image here <br>or <br>
|
|
Click to select a file
|
|
</div>
|
|
</label>
|
|
</p>
|
|
|
|
<p>
|
|
<input type="file" id="file-picker" style="display: none;">
|
|
<div style="width: 100%; text-align: center;" >
|
|
<img id="preview" style="display: block; margin: 0 auto;"><br>
|
|
</div>
|
|
|
|
<form id="form">
|
|
<input id="submitConvert" type="submit" value="Convert to JSON for WLED" style="display: none">
|
|
</form>
|
|
|
|
<div id="raw-image-container" style="display: none">
|
|
<img id="image" src="" alt="RawImage image">
|
|
</div>
|
|
</p>
|
|
|
|
<div id="image-container" style="display: none">
|
|
<div id="image-info" style="display: none"></div>
|
|
<p>
|
|
<div>
|
|
<textarea id="JSONled"></textarea>
|
|
<br>
|
|
<button id="copyJSONledbutton" >Copy led-JSON to Clipboard</button>
|
|
<br>
|
|
<button id="sendJSONledbutton" >Send to Device</button>
|
|
<br>
|
|
</div>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id=bottom-part style="display: none" class=bottom-part></div>
|
|
<canvas id="pixelCanvas"></canvas>
|
|
</div>
|
|
|
|
|
|
<script>
|
|
//Code for dynamically loading the scripts as to prevent caching. Remove in production.
|
|
function loadFiles(fileNames) {
|
|
fileNames.forEach(function(fileName) {
|
|
var fileExt = fileName.split('.').pop();
|
|
var element;
|
|
if (fileExt === 'js') {
|
|
element = document.createElement('script');
|
|
element.type = 'text/javascript';
|
|
element.src = fileName + '?time=' + new Date().getTime();
|
|
} else if (fileExt === 'css') {
|
|
element = document.createElement('link');
|
|
element.rel = 'stylesheet';
|
|
element.href = fileName + '?time=' + new Date().getTime();
|
|
}
|
|
document.getElementsByTagName('head')[0].appendChild(element);
|
|
});
|
|
}
|
|
|
|
var files = ["statics.js", "getPixelValues.js", "boxdraw.js", "index.js", "styles.css"];
|
|
loadFiles(files);
|
|
|
|
</script>
|
|
</body>
|
|
</html> |