Moves site

This commit is contained in:
javl
2016-01-22 15:18:34 +01:00
parent f365f5ee68
commit 43c668ddce
3 changed files with 544 additions and 65 deletions
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

+113 -65
View File
@@ -1,74 +1,122 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="chrome=1">
<title>Image2cpp by javl</title>
<link rel="stylesheet" href="stylesheets/styles.css">
<link rel="stylesheet" href="stylesheets/github-light.css">
<meta name="viewport" content="width=device-width">
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
<body>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>image2cpp</title>
<style type="text/css">
body{
font-family: arial;
}
.wrapper{
width: 800px;
}
.numberInput{
width: 50px;
}
label{
width: 220px;
display: inline-block;
font-weight: bold;
}
label.smallLabel{
width: auto;
}
td{
text-align: left;
vertical-align: top;
}
td.or{
padding: 20px;
width: 100px;
font-size: 30px;
/*vertical-align: center;*/
}
hr{
height: 1px;
background-color: black;
border: none;
}
img.inlineImg{
display: inline-block;
}
textarea.fullWidth{
width: 100%;
height: 100px;
}
table{
width: 100%;
}
</style>
</head>
<body>
<div class="wrapper">
<header>
<h1>Image2cpp</h1>
<p></p>
<p>
<table>
<tr>
<td>
<h3>Select image</h3>
<input type="file" id="fileInput" name="fileinput"/><br />
<label>Selected image size:</label> <span id="imageSize">-</span>
</h4>
<td class="or">or</td>
<td>
<h3>Paste text</h3>
<textarea id="textInput" class="fullWidth"></textarea><br />
<button onclick="handleTextInput('horizontal')">Read as horizontal</button>
<button onclick="handleTextInput('vertical')">Read as vertical</button>
</td>
</tr>
</table>
</p>
<hr />
<p class="view"><a href="https://github.com/javl/image2cpp">View the Project on GitHub <small>javl/image2cpp</small></a></p>
<p>
<h3>Image Settings</h3>
<label>Canvas size: </label> <input id="screenWidth" class="numberInput" type="text" name="screenWidth" onchange="updateInteger('screenWidth')" value="128"/> * <input id="screenHeight" class="numberInput" type="text" name="screenHeight" onchange="updateInteger('screenHeight')" value="64"/> pixels<br />
<label>Background color:</label>
<input id="backgroundColorWhite" type="radio" name="backgroundColor" value="white" checked="checked" onchange="updateRadio('backgroundColor')"/><label for="backgroundColorWhite" class="smallLabel">White</label>
<input id="backgroundColorBlack" type="radio" name="backgroundColor" value="black" onchange="updateRadio('backgroundColor')"/><label for="backgroundColorBlack" class="smallLabel">Black</label><br />
<label>Brightness threshold: </label> <input id="threshold" class="numberInput" type="text" name="threshold" onchange="updateInteger('threshold')" value="128"/> <i>0 - 255; pixels with brightness above become white, below become black.</i><br/>
<label for="scale">Scaling</label>
<select id="scale" name="scale" onchange="updateInteger('scale')">
<option value="1">original size</option>
<option value="2">scale to fit canvas</option>
<option value="3">stretch to fill canvas</option>
<option value="4">stretch to fill canvas horizontally</option>
<option value="5">stretch to fill canvas vertically</option>
</select><br />
<label for="centerHorizontally">Center horizontally</label><input id="centerHorizontally" type="checkbox" onchange="updateBoolean('centerHorizontally')" /><br />
<label for="centerVertically">Center vertically</label><input id="centerVertically" type="checkbox" onchange="updateBoolean('centerVertically')" /><br />
<i>Centering the image is only relevant when using a canvas larger than the selected image.</i><br />
<label for="invertColors">Invert image colors</label><input id="invertColors" type="checkbox" onchange="updateBoolean('invertColors')" />
</p>
<ul>
<li><a href="https://github.com/javl/image2cpp/zipball/master">Download <strong>ZIP File</strong></a></li>
<li><a href="https://github.com/javl/image2cpp/tarball/master">Download <strong>TAR Ball</strong></a></li>
<li><a href="https://github.com/javl/image2cpp">View On <strong>GitHub</strong></a></li>
</ul>
</header>
<section>
<h3>
<a id="welcome-to-github-pages" class="anchor" href="#welcome-to-github-pages" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Welcome to GitHub Pages.</h3>
<hr />
<p>This automatic page generator is the easiest way to create beautiful pages for all of your projects. Author your page content here <a href="https://guides.github.com/features/mastering-markdown/">using GitHub Flavored Markdown</a>, select a template crafted by a designer, and publish. After your page is generated, you can check out the new <code>gh-pages</code> branch locally. If youre using GitHub Desktop, simply sync your repository and youll see the new branch.</p>
<p>
<h3>Preview</h3>
<canvas id="imageCanvas" style="border: 1px solid black;" width="128" height="64"></canvas>
</p>
<h3>
<a id="designer-templates" class="anchor" href="#designer-templates" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Designer Templates</h3>
<hr />
<p>Weve crafted some handsome templates for you to use. Go ahead and click 'Continue to layouts' to browse through them. You can easily go back to edit your page before publishing. After publishing your page, you can revisit the page generator and switch to another theme. Your Page content will be preserved.</p>
<h3>
<a id="creating-pages-manually" class="anchor" href="#creating-pages-manually" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Creating pages manually</h3>
<p>If you prefer to not use the automatic generator, push a branch named <code>gh-pages</code> to your repository to create a page manually. In addition to supporting regular HTML content, GitHub Pages support Jekyll, a simple, blog aware static site generator. Jekyll makes it easy to create site-wide headers and footers without having to copy them across every page. It also offers intelligent blog support and other advanced templating features.</p>
<h3>
<a id="authors-and-contributors" class="anchor" href="#authors-and-contributors" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Authors and Contributors</h3>
<p>You can <a href="https://github.com/blog/821" class="user-mention">@mention</a> a GitHub username to generate a link to their profile. The resulting <code>&lt;a&gt;</code> element will link to the contributors GitHub Profile. For example: In 2007, Chris Wanstrath (<a href="https://github.com/defunkt" class="user-mention">@defunkt</a>), PJ Hyett (<a href="https://github.com/pjhyett" class="user-mention">@pjhyett</a>), and Tom Preston-Werner (<a href="https://github.com/mojombo" class="user-mention">@mojombo</a>) founded GitHub.</p>
<h3>
<a id="support-or-contact" class="anchor" href="#support-or-contact" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Support or Contact</h3>
<p>Having trouble with Pages? Check out our <a href="https://help.github.com/pages">documentation</a> or <a href="https://github.com/contact">contact support</a> and well help you sort it out.</p>
</section>
<footer>
<p>This project is maintained by <a href="https://github.com/javl">javl</a></p>
<p><small>Hosted on GitHub Pages &mdash; Theme by <a href="https://github.com/orderedlist">orderedlist</a></small></p>
</footer>
<p>
<h3>Output</h3>
<label for="addArduinoCode">Add Arduino code</label><input id="addArduinoCode" type="checkbox" onchange="updateBoolean('addArduinoCode')" /><br />
<i>Adds some extra Arduino code around the output for easy copy-paste into <a href="#" target="_blank">this example</a>.</i><br />
<br />
<label>Draw mode:</label>
<input id="drawModeHorizontal" type="radio" name="drawMode" value="horizontal" checked="checked" onchange="updateRadio('drawMode')"/><label for="drawModeHorizontal" class="smallLabel">Horizontal</label>
<input id="drawModeVertical" type="radio" name="drawMode" value="vertical" onchange="updateRadio('drawMode')"/><label for="drawModeVertical" class="smallLabel">Vertical</label><br />
<i>If your image looks all messed up on your display, like the image below, try the other mode.</i><br />
<br />
<img class="inlineImg" src="img/error.jpg" width="150" height="64" alt="" /><br /><br />
<button type="button" onclick="outputString()">Generate code</button><br /><br />
<textarea id="outputField" class="fullWidth"></textarea>
</p>
</div>
<script src="javascripts/scale.fix.js"></script>
<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
try {
var pageTracker = _gat._getTracker("UA-4564418-27");
pageTracker._trackPageview();
} catch(err) {}
</script>
</body>
<script type="text/javascript" src="script.js"></script>
</body>
</html>
+431
View File
@@ -0,0 +1,431 @@
// Add events to the file input button
var fileInput = document.getElementById('fileInput');
fileInput.addEventListener('click', function(){this.value = null;}, false);
fileInput.addEventListener('change', handleImageSelection, false);
// Filetypes accepted by the file picker
var fileTypes = ['jpg', 'jpeg', 'png', 'bmp', 'gif'];
// The canvas we will draw on
var canvas = document.getElementById('imageCanvas');
var ctx = canvas.getContext('2d');
// The variable to hold our image. Global so we can easily reuse it when the
// user updates the settings (change canvas size, scale, invert, etc)
var img = new Image();
// A bunch of settings used when converting
var settings = {
screenWidth: 128,
screenHeight: 64,
scaleToFit: true,
preserveRatio: true,
centerHorizontally: false,
centerVertically: false,
backgroundColor: "white",
scale: '1',
drawMode: 'horizontal',
threshold: 128,
addArduinoCode: false,
invertColors: false
};
// Easy way to update settings controlled by a textfield
function updateInteger(fieldName){
settings[fieldName] = document.getElementById(fieldName).value;
place_image();
}
// Easy way to update settings controlled by a checkbox
function updateBoolean(fieldName){
settings[fieldName] = document.getElementById(fieldName).checked;
place_image();
}
// Easy way to update settings controlled by a radiobutton
function updateRadio(fieldName){
var radioGroup = document.getElementsByName(fieldName);
for (var i = 0; i < radioGroup.length; i++) {
if (radioGroup[i].checked) {
settings[fieldName] = radioGroup[i].value;
}
}
place_image();
}
// Make the canvas black and white
function blackAndWhite(){
var imageData = ctx.getImageData(0,0,canvas.width, canvas.height);
var data = imageData.data;
for (var i = 0; i < data.length; i += 4) {
var avg = (data[i] + data[i +1] + data[i +2]) / 3;
if (settings['invertColors']){
avg > settings['threshold'] ? avg = 0 : avg = 255;
}else{
avg > settings['threshold'] ? avg = 255 : avg = 0;
}
data[i] = avg; // red
data[i + 1] = avg; // green
data[i + 2] = avg; // blue
}
ctx.putImageData(imageData, 0, 0);
};
// Invert the colors of the canvas
function invert() {
var imageData = ctx.getImageData(0,0,canvas.width, canvas.height);
var data = imageData.data;
for (var i = 0; i < data.length; i += 4) {
data[i] = 255 - data[i]; // red
data[i + 1] = 255 - data[i + 1]; // green
data[i + 2] = 255 - data[i + 2]; // blue
}
ctx.putImageData(imageData, 0, 0);
};
// Draw the image onto the canvas, taking into account color and scaling
function place_image(){
// Make sure we're using the right canvas size
canvas.width = settings['screenWidth'];
canvas.height = settings['screenHeight'];
// Invert colors if needed
if (settings['invertColors']){
settings['backgroundColor'] == 'white' ? ctx.fillStyle = 'black' : ctx.fillStyle = 'white';
}else{
ctx.fillStyle = settings['backgroundColor'];
}
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Offset used for centering the image when requested
var offset_x = 0;
var offset_y = 0;
switch(settings['scale']){
case '1': // Original
if(settings['centerHorizontally']){ offset_x = (canvas.width - img.width) / 2; }
if(settings['centerVertically']){ offset_y = (canvas.height - img.height) / 2; }
ctx.drawImage(img, 0, 0, img.width, img.height,
offset_x, offset_y, img.width, img.height);
break;
case '2': // Fit (make as large as possible without changing ratio)
var horRatio = canvas.width / img.width;
var verRatio = canvas.height / img.height;
var useRatio = Math.min(horRatio, verRatio);
if(settings['centerHorizontally']){ offset_x = (canvas.width - img.width*useRatio) / 2; }
if(settings['centerVertically']){ offset_y = (canvas.height - img.height*useRatio) / 2; }
ctx.drawImage(img, 0, 0, img.width, img.height,
offset_x, offset_y, img.width * useRatio, img.height * useRatio);
break;
case '3': // Stretch x+y (make as large as possible without keeping ratio)
ctx.drawImage(img, 0, 0, img.width, img.height,
offset_x, offset_y, canvas.width, canvas.height);
break;
case '4': // Stretch x (make as wide as possible)
offset_x = 0;
if(settings['centerVertically']){ offset_y = (canvas.height - img.height) / 2; }
ctx.drawImage(img, 0, 0, img.width, img.height,
offset_x, offset_y, canvas.width, img.height);
break;
case '5': // Stretch y (make as tall as possible)
if(settings['centerHorizontally']){ offset_x = (canvas.width - img.width) / 2; }
offset_y = 0;
ctx.drawImage(img, 0, 0, img.width, img.height,
offset_x, offset_y, img.width, canvas.height);
break;
}
// Make sure the image is black and white
blackAndWhite();
}
// Handle inserting an image by pasting code
function handleTextInput(drawMode){
var input = document.getElementById('textInput').value;
// Remove Arduino code
input = input.replace(/const unsigned char myBitmap \[\] PROGMEM = \{/g, "");
input = input.replace(/\};/g, "");
// Remove newlines
input = input.replace(/\r\n|\r|\n/g, "");
// Remove whitespace
input = input.replace(/\s/g, "");
// Remove "0x"
input = input.replace(/0x/g, "");
// Split into list
var list = input.split(",");
if(drawMode == 'horizontal'){
listToImageHorizontal(list);
}else{
listToImageVertical(list);
}
}
// Handle selecting an image with the file picker
function handleImageSelection(e){
var reader = new FileReader();
reader.onload = function(event){
// Crude check to see if the uploaded file is an image
if (reader.result.substring (0, 10) != "data:image"){
alert("Please select an image file.");
return false;
}
img.onload = function(){
// Show the size underneath the file picker
document.getElementById('imageSize').innerHTML = img.width+" * " + img.height + " pixels";
// Resize the canvas and update the input fields
document.getElementById('screenWidth').value = img.width;
document.getElementById('screenHeight').value = img.height;
settings['screenWidth'] = img.width;
settings['screenHeight'] = img.height;
place_image();
}
img.src = event.target.result;
}
reader.readAsDataURL(e.target.files[0]);
}
// Output the image as a string for horizontally drawing displays
function imageToStringHorizontal(){
var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
var output_string = "";
var output_index = 0;
var byteIndex = 7;
var number = 0;
for (var index=0; index < imageData.data.length; index+=4){
var avg = (imageData.data[index] + imageData.data[index +1] + imageData.data[index +2]) / 3;
if (avg > settings['threshold']){
number += Math.pow(2, byteIndex);
}
byteIndex--;
if(byteIndex < 0){
var byteSet = number.toString(16);
if (byteSet.length == 1){ byteSet = "0"+byteSet; }
var b = "0x"+byteSet;
output_string += b+", ";
output_index++;
if (output_index >= 16){
output_string += "\n";
output_index = 0;
}
number = 0;
byteIndex = 7;
}
}
return output_string;
}
// Output the image as a string for vertically drawing displays
function imageToStringVertical(){
var x = 0;
var y = 7;
var page = 0;
var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
var data = imageData.data;
var output_string = "";
var output_index = 0;
for (var p=0; p<Math.ceil(settings['screenHeight']/8);p++){
for (var x=0;x<=settings['screenWidth'];x++){
// for (var x=0;x<1;x++){
var byteIndex = 7;
var number = 0;
for (var y = 7; y >= 0; y--){
var index = ((p*8)+y)*(settings['screenWidth']*4)+x;
var avg = (data[index] + data[index +1] + data[index +2]) / 3;
if (avg > settings['threshold']){
number += Math.pow(2, byteIndex);
}
byteIndex--;
}
var byteSet = number.toString(16);
if (byteSet.length == 1){ byteSet = "0"+byteSet; }
var b = "0x"+byteSet.toString(16);
output_string += b+", ";
output_index++;
if (output_index >= 16){
output_string += "\n";
output_index = 0;
}
}
}
return output_string;
}
// Output the image string to the textfield
function outputString(){
var output_string = "";
if (settings['drawMode'] == 'horizontal'){
output_string = imageToStringHorizontal();
}else{
output_string = imageToStringVertical();
}
if(settings['addArduinoCode']){
output_string = "const unsigned char myBitmap [] PROGMEM = {\n" + output_string + "\n};";
}
document.getElementById('outputField').value = output_string;
}
// Use the horizontally oriented list to draw the image
function listToImageHorizontal(list){
ctx.clearRect(0, 0, canvas.width, canvas.height);
var imgData = ctx.createImageData(canvas.width, canvas.height);
var index = 0;
var page = 0;
var x = 0;
var y = 7;
// Move the list into the imageData object
for (var i=0;i<list.length;i++){
var binString = hexToBinary(list[i]).result;
if (binString.length == 4){
binString = binString + "0000";
}
// Check if pixel is white or black
for(var k=0; k<binString.length; k++){
var color = 0;
if(binString.charAt(k) == '1'){
color = 255;
}
imgData.data[index] = color;
imgData.data[index+1] = color;
imgData.data[index+2] = color;
imgData.data[index+3] = 255;
index += 4
}
}
// Draw the image onto the canvas, then save the canvas contents
// inside the img object. This way we can reuse the img object when
// we want to scale / invert, etc.
ctx.putImageData(imgData, 0, 0);
img.src = canvas.toDataURL('image/png');
}
// Use the vertically oriented list to draw the image
function listToImageVertical(list){
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Create a new imageData object, but 90 degrees rotates (height x width)
// var imgData = ctx.createImageData(canvas.width, canvas.height);
// var imgData = ctx.getImageData(0, 0, canvas.height, canvas.width);
//var imgData = ctx.createImageData(canvas.width, canvas.height);
// var data = imgData.data;
var index = 0;
var page = 0;
var x = 0;
var y = 7;
// Move the list into the imageData object
for (var i=0;i<list.length;i++){
var binString = hexToBinary(list[i]).result;
if (binString.length == 4){
binString = binString + "0000";
}
// Check if pixel is white or black
for(var k=0; k<binString.length; k++){
var color = 0;
if(binString.charAt(k) == '1'){
color = 255;
}
// color = 0;
drawPixel(x, (page*8)+y, color);
y--;
if(y < 0){
y = 7;
x++;
if(x >= settings['screenWidth']){
x = 0;
page++;
}
}
}
}
// Save the canvas contents inside the img object. This way we can
// reuse the img object when we want to scale / invert, etc.
img.src = canvas.toDataURL('image/png');
}
// Convert hex to binary
function hexToBinary(s) {
var i, k, part, ret = '';
// lookup table for easier conversion. '0' characters are padded for '1' to '7'
var lookupTable = {
'0': '0000', '1': '0001', '2': '0010', '3': '0011', '4': '0100',
'5': '0101', '6': '0110', '7': '0111', '8': '1000', '9': '1001',
'a': '1010', 'b': '1011', 'c': '1100', 'd': '1101',
'e': '1110', 'f': '1111',
'A': '1010', 'B': '1011', 'C': '1100', 'D': '1101',
'E': '1110', 'F': '1111'
};
for (i = 0; i < s.length; i += 1) {
if (lookupTable.hasOwnProperty(s[i])) {
ret += lookupTable[s[i]];
} else {
return { valid: false };
}
}
return { valid: true, result: ret };
}
// Quick and effective way to draw single pixels onto the canvas
// using a global 1x1px large canvas
var single_pixel = ctx.createImageData(1,1);
var d = single_pixel.data;
function drawPixel(x, y, color){
d[0] = color;
d[1] = color;
d[2] = color;
d[3] = 255;
ctx.putImageData(single_pixel, x, y);
}