commit:4cb956c53cd696d6bb2071c23f2e57b269ba0497
author:Chip Black
committer:Chip Black
date:Sun Oct 18 20:00:04 2015 -0500
parents:411534db84bca553c35962646fda83ad4388cd4a
Add load capability
diff --git a/src/Palette.js b/src/Palette.js
line changes: +17/-0
index 670faf2..6ec4287
--- a/src/Palette.js
+++ b/src/Palette.js
@@ -83,4 +83,21 @@ export default class Palette extends Controller {
         let c = palettes[this.palette][i];
         return 'rgb(' + c[0] + ',' + c[1] + ',' + c[2] + ')';
     }
+    findClosestColor(rgbdata) {
+        let closest = 0;
+        let distance = 1e9;
+        for (let i = 0; i < 16; i++) {
+            let tc = palettes[this.palette][i];
+            let d = Math.pow(
+                Math.abs(tc[0] - rgbdata[0]) + Math.abs(tc[1] - rgbdata[1]) + Math.abs(tc[2] - rgbdata[2]),
+                1/3
+            );
+            if (d < distance) {
+                closest = i;
+                distance = d;
+            }
+        }
+
+        return closest;
+    }
 }

diff --git a/src/PixelEditor.js b/src/PixelEditor.js
line changes: +27/-0
index ff1bd0e..adce7c7
--- a/src/PixelEditor.js
+++ b/src/PixelEditor.js
@@ -57,6 +57,33 @@ export default class PixelEditor extends Controller {
         this.pctx.fillRect(0, 0, w, h);
         previewContainer.appendChild(this.preview);
     }
+    loadFromImage(img) {
+        let validSize = false;
+        let sizes = [8, 16, 24, 32, 48, 64, 96, 128];
+        for (let i in sizes) {
+            if (img.width <= sizes[i]) {
+                this.setSize(sizes[i], sizes[i]);
+                validSize = true;
+                break;
+            }
+        }
+        if (!validSize) {
+            alert("Image too large. Must be less than 128x128");
+            return;
+        }
+
+        this.pctx.fillStyle = this.state.palette.getCSSColor(0);
+        this.pctx.fillRect(0, 0, this.width, this.height);
+        this.pctx.drawImage(img, 0, 0);
+        let imageData = this.pctx.getImageData(0, 0, this.width, this.height);
+        for (let i = 0; i < imageData.data.length; i += 4) {
+            let c = this.state.palette.findClosestColor(imageData.data.slice(i, i + 4));
+            this.pixels[i / 4] = c;
+        }
+
+        this.redraw();
+        this.refresh();
+    }
     getFile() {
         return new Promise((resolve, reject) => {
             this.preview.toBlob(blob => {

diff --git a/src/index.html b/src/index.html
line changes: +3/-2
index c1e4e4b..e433395
--- a/src/index.html
+++ b/src/index.html
@@ -14,8 +14,8 @@
       </div>
       <div class="spacer"></div>
       <div class="global-actions">
-        <button onclick="save()">Save</button>
-        <button>Load</button>
+        <button onclick="savePNG()">Save</button>
+        <button onclick="loadFile()">Load</button>
         <button onclick="toggleGrid()" id="button-grid" class="active">Grid</button>
         <div id="size-flyout" class="size-flyout">
           <button onclick="selectSize(8)">8x8</button>
@@ -68,3 +68,4 @@
 </div>
 
 <iframe id="saver"></iframe>
+<input id="loader" type="file">

diff --git a/src/main.js b/src/main.js
line changes: +17/-1
index 8e85f23..e66a2d3
--- a/src/main.js
+++ b/src/main.js
@@ -5,7 +5,7 @@ import { TOOL_PEN, TOOL_FILL, TOOL_LINE } from './Toolbox';
 
 var appState = {};
 
-window.save = function save() {
+window.savePNG = function save() {
     let saver = document.getElementById('saver');
     appState.pixelEditor.getFile().then(file => {
         let uri = URL.createObjectURL(file);
@@ -21,6 +21,22 @@ window.save = function save() {
     });
 }
 
+window.loadFile = function loadFile() {
+    let loader = document.getElementById('loader');
+    loader.onchange = function() {
+        let url = URL.createObjectURL(loader.files[0]);
+        let img = document.createElement('img');
+        img.src = url;
+        img.onload = function() {
+            appState.pixelEditor.loadFromImage(img);
+        };
+        img.onerror = function() {
+            alert("This doesn't appear to be an image");
+        };
+    };
+    loader.click();
+}
+
 window.nextPalette = function() {
     appState.palette.nextPalette();
     appState.pixelEditor.paletteChanged();

diff --git a/src/style.css b/src/style.css
line changes: +1/-1
index b82c467..4c76b88
--- a/src/style.css
+++ b/src/style.css
@@ -144,7 +144,7 @@ button.active {
 	flex: none;
 }
 
-#saver {
+#saver, #loader {
 	width: 0;
 	height: 0;
 	display: none;