Skip to content

Instantly share code, notes, and snippets.

@glynthomas
Created February 19, 2014 22:46
Show Gist options
  • Save glynthomas/9103273 to your computer and use it in GitHub Desktop.
Save glynthomas/9103273 to your computer and use it in GitHub Desktop.
HTML5 File API thumbnail : EXIF orientation tag (lightweight fix)
<!DOCTYPE html>
<head>
<title>HTML5 Camera Fun</title>
</head>
<style type="text/css">
.crop-canvas {
bottom: -30px;
left: -38px;
position: relative;
}
body {
background-color: #FFFFFF;
color: #333333;
font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
font-size: 14px;
line-height: 20px;
margin: 0;
}
a {
color: #0088CC;
text-decoration: none;
}
a:hover, a:focus {
color: #005580;
text-decoration: underline;
}
.file-upload {
margin: 10px;
overflow: hidden;
position: relative;
}
.file-upload input.upload {
cursor: pointer;
font-size: 20px;
margin: 0;
opacity: 0;
padding: 0;
position: absolute;
right: 0;
top: 0;
}
.btn {
-moz-border-bottom-colors: none;
-moz-border-left-colors: none;
-moz-border-right-colors: none;
-moz-border-top-colors: none;
background-color: #F5F5F5;
background-image: linear-gradient(to bottom, #FFFFFF, #E6E6E6);
background-repeat: repeat-x;
border-color: #CCCCCC #CCCCCC #B3B3B3;
border-image: none;
border-radius: 4px;
border-style: solid;
border-width: 1px;
box-shadow: 0 1px 0 rgba(255, 255, 255, 0.2) inset, 0 1px 2px rgba(0, 0, 0, 0.05);
color: #333333;
cursor: pointer;
display: inline-block;
font-size: 14px;
line-height: 20px;
margin-bottom: 0;
padding: 4px 12px;
text-align: center;
text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);
vertical-align: middle;
}
.btn:hover, .btn:focus, .btn:active, .btn.active, .btn.disabled, .btn[disabled] {
background-color: #E6E6E6;
color: #333333;
}
.btn:active, .btn.active {
}
.btn:first-child {
}
.btn:hover, .btn:focus {
background-position: 0 -15px;
color: #333333;
text-decoration: none;
transition: background-position 0.1s linear 0s;
}
.btn:focus {
outline: thin dotted #333333;
outline-offset: -2px;
}
.btn.active, .btn:active {
background-image: none;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15) inset, 0 1px 2px rgba(0, 0, 0, 0.05);
outline: 0 none;
}
.btn.disabled, .btn[disabled] {
background-image: none;
box-shadow: none;
cursor: default;
opacity: 0.65;
}
</style>
<body>
<div style="left: 0; top: 0; width: 100px;">
<br />
<br />
<div class="file-upload btn btn-default">
<span class="">Upload</span>
<br>
<input type="file" class="upload" id="photopick" accept="image/*" capture="camera">
</div>
<p>
<button class="file-upload btn btn-default" id="ProcessButton">Process</button>
<p>
<div class="crop-canvas">
<canvas id="photoedit" width="100" height="100" ></canvas>
</div>
<!--
<p><font color="white">This browser does not support the required features.
Please try
<a href="http://windows.microsoft.com/en-us/internet-explorer/products/ie/home">Internet Explorer 10</a>,
or a current version of
<a href="http://www.mozilla.org/en-US/firefox/new/">Firefox</a>,
<a href="http://www.google.com/chrome">Chrome</a>, or
<a href="http://www.apple.com/safari/">Safari</a>.</font></p>
</canvas> -->
<script type="text/javascript">
// Wrapper around MPL-licensed http://www.nihilogic.dk/labs/binaryajax/binaryajax.js
// to support JavaScript typed arrays since binary strings are not supported in IE 10
document.getElementsByTagName('input')[0].onchange = function (e) {
var createBinaryFile = function(uintArray) {
var data = new Uint8Array(uintArray);
var file = new BinaryFile(data);
file.getByteAt = function(iOffset) {
return data[iOffset];};
file.getBytesAt = function(iOffset, iLength) {
var aBytes = [];
for (var i = 0; i < iLength; i++) {
aBytes[i] = data[iOffset + i];
}
return aBytes;
};
file.getLength = function() {
return data.length;
};
console.log('picure size in bytes: ' +data.length);
switch (true) {
case (data.length > 30000000):
// case (data.length > 130000):
// console.log('your picture is larger than 3MB');
console.log('your picture is larger than 130k');
oFile = null;
return;
break;
}
return file;
};
e.preventDefault();
if(this.files.length === 0) return;
var imageFile = this.files[0];
var img = new Image();
var url = window.URL ? window.URL : window.webkitURL;
img.src = url.createObjectURL(imageFile);
img.onload = function(e) {
url.revokeObjectURL(this.src);
var width;
var height;
var binaryReader = new FileReader();
binaryReader.onloadend=function(d) {
var exif, transform = "none";
exif=EXIF.readFromBinaryFile(createBinaryFile(d.target.result));
if(typeof exif != 'undefined') {
switch (exif.Orientation) {
case 8:
width = img.height;
height = img.width;
transform = "left";
break;
case 6:
width = img.height;
height = img.width;
transform = "right";
break;
case 1:
width = img.width;
height = img.height;
break;
case 3:
width = img.height;
height = img.width;
transform = "flip";
break;
default:
width = img.width;
height = img.height;
}
/* proportional sizing ... */
var MAX_WIDTH = 300;
var MAX_HEIGHT = 200;
switch (true) {
case (width/MAX_WIDTH > height/MAX_HEIGHT):
switch (true) {
case (width > MAX_WIDTH):
height *= MAX_WIDTH / width;
width = MAX_WIDTH;
break;
}
break;
case (height > MAX_HEIGHT):
width *= MAX_HEIGHT / height;
height = MAX_HEIGHT;
break;
}
var canvas = $('#photoedit')[0];
canvas.width = width;
canvas.height = height;
var ctx = canvas.getContext("2d");
ctx.fillStyle = 'white';
ctx.fillRect(0, 0, canvas.width, canvas.height);
switch (transform) {
case ('left'):
ctx.setTransform(0, -1, 1, 0, 0, height);
// ctx.drawImage(img, 0, 0, height, width);
ctx.drawImage(img, 0, 0, 100, 100);
break;
case ('right'):
ctx.setTransform(0, 1, -1, 0, width, 0);
// ctx.drawImage(img, 0, 0, height, width);
ctx.drawImage(img, 0, 0, 100, 100);
break;
case ('flip'):
ctx.setTransform(1, 0, 0, -1, 0, height);
// ctx.drawImage(img, 0, 0, width, height);
ctx.drawImage(img, 0, 0, 100, 100);
default:
ctx.setTransform(1, 0, 0, 1, 0, 0);
// ctx.drawImage(img, 0, 0, width, height);
ctx.drawImage(img, 0, 0, 100, 100);
}
ctx.setTransform(1, 0, 0, 1, 0, 0);
}
};
binaryReader.readAsArrayBuffer(imageFile);
};
};
/*
$('#ProcessButton').click(function() {
var canvas = $('#PhotoEdit')[0];
var ctx = canvas.getContext("2d");
var pixels = ctx.getImageData(0, 0, canvas.width, canvas.height);
var r, g, b, i;
for (var py = 0; py < pixels.height; py += 1) {
for (var px = 0; px < pixels.width; px += 1) {
i = (py*pixels.width + px)*4;
r = pixels.data[i];
g = pixels.data[i+1];
b = pixels.data[i+2];
if(g > 100 && g > r*1.35 && g > b*1.6) pixels.data[i+3] = 0;
}
}
ctx.putImageData(pixels, 0, 0);
var data = canvas.toDataURL('image/png');
setTimeout(function() {alert("Modified Image Data: "+data.substring(0, 30)+"...");}, 100);
// Do something with the image file now...
return false;
});
*/
// };
//});
//();
</script>
<script src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
<script src="js/exif.js" type="text/javascript"></script>
<script src="js/binaryajax.js" type="text/javascript"></script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment