1<!DOCTYPE html> 2<html> 3<head> 4
4<script src="lib/jquery.min.js"></script>
4 5
5<script src="lib/bootstrap.bundle.min.js"></script>
5 6
6<script src="lib/bootstrap-slider.min.js"></script>
6 7 <!-- css --> 8 <link rel="stylesheet" href="lib/font-awesome.min.css" crossorigin="anonymous"> 9 <link rel="stylesheet" href="lib/bootstrap.min.css" crossorigin="anonymous"> 10 <link rel="stylesheet" href="lib/cropper.min.css"> 11 <link rel="stylesheet" href="lib/bootstrap-slider.min.css"> 12 <!-- Required meta tags --> 13 <meta charset="utf-8"> 14 <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> 15 <!-- twitter tags--> 16 <meta name="twitter:card" content="summary_large_image"> 17 <meta name="twitter:site" content="@8bitworkshop"> 18 <meta name="twitter:creator" content="@8bitworkshop"> 19 <meta name="twitter:image" content="https://8bitworkshop.com/blog/images/ide/dithertron-compare.png"> 20 <meta name="twitter:title" content="Dithertron by 8bitworkshop"> 21 <meta name="twitter:description" content="Crop, reduce, and dither images to 8-bit retro formats."> 22 <title>Dithertron</title> 23 <!-- local CSS --> 24 <style type="text/css" media="screen"> 25 body { 26 background: #999; 27 } 28 /* Custom CSS to make the container full-screen on desktop */ 29 @media (min-width: 768px) { 30 .full-screen-container { 31 height: 100vh; 32 display: flex; 33 align-items: center; 34 } 35 .container-xl { 36 height: 100vh; 37 display: flex; 38 flex-direction: column; 39 } 40 .responsive-row { 41 display: flex; 42 height: 50vh; 43 } 44 .responsive-col { 45 display: flex; 46 flex-direction: column; 47 } 48 } 49 img.crop { 50 display: block; 51 max-width: 100%; 52 } 53 .emuvideo { 54 display: block; 55 width: 85%; 56 margin: auto; 57 background: #000; 58 pointer-events: auto; 59 } 60 #booksMenu { 61 background-color: #666; 62 border-radius: 0.5em; 63 } 64 #booksMenu > a { 65 color: #fff; 66 } 67 #examplesMenu { 68 font-size: 0.8em; 69 max-height: 65vh; 70 overflow-y: auto; 71 } 72 /* make the two top info panels equal height */ 73 .top-row { 74 align-items: stretch; 75 } 76 .top-row > .col-md-6 { 77 display: flex; 78 flex-direction: column; 79 } 80 .top-row > .col-md-6 > .alert { 81 flex: 1; 82 margin-bottom: 1rem; 83 } 84 /* source image panel */ 85 #sourcePanel { 86 padding: 0.5rem 0.75rem; 87 } 88 #sourcePanel .btn { 89 margin-bottom: 0.25rem; 90 } 91 #sourceName { 92 font-weight: bold; 93 } 94 /* drag & drop overlay */ 95 #sourcePane { 96 position: relative; 97 } 98 #dropOverlay { 99 display: none; 100 position: absolute; 101 inset: 0; 102 border: 4px dashed rgba(255, 255, 255, 0.9); 103 border-radius: 0.5em; 104 background: rgba(0, 0, 0, 0.55); 105 color: #fff; 106 align-items: center; 107 justify-content: center; 108 font-size: 1.5em; 109 font-weight: bold; 110 text-shadow: 0 1px 3px #000; 111 z-index: 1050; 112 pointer-events: none; 113 } 114 #dropOverlay.dragover { 115 display: flex; 116 } 117 /* mobile tweaks */ 118 @media (max-width: 767.98px) { 119 .container-xl { 120 padding-left: 0.5rem; 121 padding-right: 0.5rem; 122 } 123 .navbar-brand { 124 font-size: 1.1em; 125 } 126 .alert { 127 padding: 0.6rem; 128 margin-bottom: 0.5rem; 129 } 130 #targetFormatSelect { 131 max-width: 100%; 132 } 133 img.crop, 134 .emuvideo { 135 width: 100%; 136 } 137 label.col-form-label { 138 font-size: 0.85rem; 139 padding-left: 0; 140 } 141 #imageUpload { 142 max-width: 100%; 143 font-size: 0.85em; 144 } 145 } 146 </style> 147</head> 148<!-- body --> 149 150<body class="full-screen-container"> 151 <div class="container-xl"> 152 153 <nav class="navbar navbar-expand-lg navbar-dark bg-dark"> 154 <div class="navbar-collapse collapse w-100 order-1 order-md-0 dual-collapse2"> 155 <ul class="navbar-nav mr-auto"> 156 <li class="nav-item"> 157 <a class="nav-link" href="https://github.com/sehugg/dithertron#dithertron" 158 target="_github">README</a> 159 </li> 160 </ul> 161 </div> 162 <div class="mx-auto order-0"> 163 <a class="navbar-brand mx-auto" href="#">D I T H E R T R O N</a> 164 <button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".dual-collapse2">
165 <span class="navbar-toggler-icon"></span> 166 </button> 167 </div> 168 <div class="navbar-collapse collapse w-100 order-3 dual-collapse2"> 169 <ul class="navbar-nav ml-auto"> 170 <li class="nav-item dropdown" id="booksMenu"> 171 <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" 172 data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> 173 ð Books <span class="caret"></span> 174 </a> 175 <div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdown"> 176 <a class="dropdown-item dropdown-link book-vcs" target="_book_a2600" 177 href="https://www.amazon.com/gp/product/1541021304/ref=as_li_qf_sp_asin_il_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=B01N4DSRIZ"> 178 <img src="images/books/book_a2600.png" /> 179 <span class="book-title">Making Games For The Atari 2600</span> 180 </a> 181 <a class="dropdown-item dropdown-link book-arcade" target="_book_arcade" 182 href="https://www.amazon.com/gp/product/1545484759/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1545484759"> 183 <img src="images/books/book_arcade.png" /> 184 <span class="book-title">Making 8-bit Arcade Games in C</span> 185 </a> 186 <a class="dropdown-item dropdown-link book-verilog" target="_book_verilog" 187 href="https://www.amazon.com/gp/product/1728619440/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1728619440"> 188 <img src="images/books/book_verilog.png" /> 189 <span class="book-title">Designing Video Game Hardware in Verilog</span> 190 </a> 191 <a class="dropdown-item dropdown-link book-nes" target="_book_nes" 192 href="https://www.amazon.com/gp/product/1075952727/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1075952727"> 193 <img src="images/books/book_nes.png" /> 194 <span class="book-title">Making Games For The NES</span> 195 </a> 196 <a class="dropdown-item dropdown-link book-c64" target="_book_c64" 197 href="https://www.amazon.com/dp/B0DMKH8NGL"> 198 <img src="images/book_c64.png"/> 199 <span class="book-title">Making Games for the C-64</span> 200 </a> 201 </div> 202 </li> 203 </ul> 204 </div> 205 </nav> 206 207 <div class="responsive-row top-row"> 208 <div class="col-md-6"> 209 <div class="alert alert-info d-flex flex-wrap align-items-center" id="sourcePanel"> 210 <span class="mr-2"><i class="fa fa-image"></i> Image:</span> 211 <div class="dropdown mr-2"> 212 <button class="btn btn-secondary btn-sm dropdown-toggle" type="button" 213 id="dropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" 214 aria-expanded="false"> 215 Examples 216 </button> 217 <div class="dropdown-menu" aria-labelledby="dropdownMenuLink" id="examplesMenu"> 218 </div> 219 </div> 220 <button id="openImageBtn" type="button" class="btn btn-secondary btn-sm mr-2" 221 title="Open an image file"> 222 Open⦠<i class="fa fa-folder-open"></i> 223 </button> 224 <small class="text-muted">or drop / paste an image anywhere</small> 225 <input type="file" id="imageUpload" accept="image/*" style="display:none"> 226 <div class="w-100"><small>Loaded: <span id="sourceName">(none)</span></small></div> 227 </div> 228 </div> 229 <div class="col-md-6"> 230 <div class="alert alert-info"> 231 Convert to: 232 <select id="targetFormatSelect" title="Select the target format"></select> 233 <br> 234 <small><span id="targetFormatInfo"></span></small> 235 <br> 236 <div> 237 <button id="downloadImageBtn" type="button" class="btn btn-secondary btn-sm" 238 title="Download a PNG image">PNG <i class="fa fa-download"></i></button> 239 <button id="downloadNativeBtn" type="button" class="btn btn-secondary btn-sm" 240 title="Download a binary file in the target format">BIN <i 241 class="fa fa-download"></i></button> 242 <button id="gotoIDE" type="button" class="btn btn-secondary btn-sm" 243 title="Open in 8bitworkshop">Open in 8bitworkshop <i class="fa fa-share"></i></button> 244 </div> 245 </div> 246 </div> 247 </div> 248 <div class="responsive-row"> 249 <div class="col-md-6 responsive-col" id="sourcePane"> 250 <img class="crop" id="srcimage"> 251 <div id="dropOverlay">Drop image here</div> 252 </div> 253 <div class="col-md-6 responsive-col">
254 <canvas id="destcanvas" class="emuvideo"></canvas> 255 <div id="paletteSwatches" class="mt-3 d-flex justify-content-center flex-wrap"> 256 </div> 257 </div> 258 </div> 259 <div class="row"> 260 <div class="col-md-6"> 261 <div class="alert alert-secondary mt-3"> 262 <div class="row align-items-center" id="brightSection"> 263 <label for="brightSlider" class="col-sm-3 col-form-label">Bright:</label> 264 <div class="col-sm-5 col-md-5"> 265 <input type="range" id="brightSlider" data-provide="slider" data-slider-min="0" 266 data-slider-max="100" data-slider-value="50" /> 267 </div> 268 </div> 269 <div class="row align-items-center" id="contrastSection"> 270 <label for="contrastSlider" class="col-sm-3 col-form-label">Contrast:</label> 271 <div class="col-sm-5 col-md-5"> 272 <input type="range" id="contrastSlider" data-provide="slider" data-slider-min="0" 273 data-slider-max="100" data-slider-value="50" /> 274 </div> 275 </div> 276 <div class="row align-items-center" id="saturationSection"> 277 <label for="saturationSlider" class="col-sm-3 col-form-label">Color:</label> 278 <div class="col-sm-5 col-md-5"> 279 <input type="range" id="saturationSlider" data-provide="slider" data-slider-min="0" 280 data-slider-max="100" data-slider-value="50" /> 281 </div> 282 <div class="col-lg-5 col-xl-4"> 283 <small><select id="errorFuncSelect"></select></small> 284 </div> 285 </div> 286 </div> 287 </div> 288 <div class="col-md-6"> 289 <div class="alert alert-secondary mt-3"> 290 <div class="row align-items-center" id="diversitySection"> 291 <label for="diversitySlider" class="col-sm-3 col-form-label">Diversity:</label> 292 <div class="col-sm-5 col-md-5"> 293 <input type="range" id="diversitySlider" data-provide="slider" data-slider-min="0" 294 data-slider-max="100" data-slider-value="60" /> 295 </div> 296 </div> 297 <div class="row align-items-center" id="diffuseSection"> 298 <label for="diffuseSlider" class="col-sm-3 col-form-label">Diffusion:</label> 299 <div class="col-sm-5 col-md-5"> 300 <input type="range" id="diffuseSlider" data-provide="slider" data-slider-min="0" 301 data-slider-max="100" data-slider-value="75" /> 302 </div> 303 <div class="col-lg-5 col-xl-4"> 304 <small><select id="diffuseTypeSelect"></select></small> 305 </div> 306 </div> 307 <div class="row align-items-center" id="diffuseSection"> 308 <label for="orderedSlider" class="col-sm-3 col-form-label">Ordered:</label> 309 <div class="col-sm-5 col-md-5"> 310 <input type="range" id="orderedSlider" data-provide="slider" data-slider-min="0" 311 data-slider-max="100" data-slider-value="0" /> 312 </div> 313 </div> 314 <div class="row align-items-center" id="noiseSection"> 315 <label for="noiseSlider" class="col-sm-3 col-form-label">Noise:</label> 316 <div class="col-sm-5 col-md-5"> 317 <input type="range" id="noiseSlider" data-provide="slider" data-slider-min="0"
318 data-slider-max="10" data-slider-value="5" /> 319 </div> 320 </div> 321 </div> 322 </div> 323 </div> 324 <!-- hidden canvas--> 325 <canvas id="resizecanvas" style="display:none"> 326 <!-- hidden form --> 327 <FORM action="https://8bitworkshop.com/redir.html" method="GET" id="ideForm" target="_ide"> 328 </FORM> 329
329<script> 330 if (window.location.host == ('localhost:8000')) { 331 document.forms['ideForm'].action = '/'; 332 } 333 </script>
333 334 </div> 335 <!-- local scripts--> 336
336<script src="gen/ui.js" type="module"></script>
336 337 338</body> 339</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.