xxxxxxxxxx
<html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v3.min.js"></script>
<script src="hermite.js"></script>
<style>
.panel {
fill: black;
}
canvas {
display: none;
}
.slider {
width: 400px;
}
#phosphene-image {
width: 400px;
}
</style>
</head>
<body>
<canvas id="phosphene-image"></canvas>
<div class="container"></div>
<div class="controls">
<input class="slider" type="range" min="8" max="32" value="8" step="1"><br>
<div class="count"></div>
</div>
<script>
var link = 'https://lh3.googleusercontent.com/-2Dq25Dtewk4/VqkoGGLdtxI/AAAAAAAAC7Q/r3BSJnQoSo0/s609-Ic42/BionicEye2.jpg';
var outputW = 400;
var hermite = Hermite.init('hermite-worker.js');
var phospheneCanvas = document.getElementById('phosphene-image');
var phospheneCtx = phospheneCanvas.getContext('2d');
var root = d3.select('.container').append('svg');
var panel = root.append('rect').classed('panel', true);
root.append('defs').append('filter')
.attr({
id: 'f1',
x: 0,
y: 0
})
.append('feGaussianBlur')
.attr({
in: 'SourceGraphic',
stdDeviation: 2
});
var imgData, img;
d3.select('.slider').on('input', function(d){
buildGrid(this.value);
});
img = new Image;
img.onload = function(){
buildGrid(8);
};
img.crossOrigin = '';
img.src = link;
function buildGrid(outputResolution){
d3.select('.count').text(outputResolution * outputResolution + ' phosphenes');
var imgW = outputResolution;
var imgH = imgW * img.height / img.width;
phospheneCanvas.width = img.width;
phospheneCanvas.height = img.height ;
phospheneCtx.drawImage(img, 0, 0, img.width, img.height);
hermite.resize({
source: phospheneCanvas,
width: imgW,
height: imgH
}, function(output) {
imgData = phospheneCtx.getImageData(0, 0, imgW, imgH).data;
var data = [];
var dataIdx = -1;
var r, g, b, gray;
for(var i = 0; i < imgData.length / 4; i++){
if(i % imgW === 0){
dataIdx++;
data.push([]);
}
r = imgData[i*4];
g = imgData[i*4+1];
b = imgData[i*4+2];
gray = r*0.2126 + g*0.7152 + b*0.0722;
data[dataIdx].push(gray);
}
buildPhosphenes(data, imgH, imgW);
});
}
function buildPhosphenes(data, imgH, imgW){
var outputH = outputW * imgH / imgW;
var cellSize = outputW / imgW;
root.attr({width: outputW, height: outputH});
panel.attr({width: outputW, height: outputH});
var rowGroup = root.selectAll('g.row')
.data(data);
rowGroup.enter().append('g')
.classed('row', true)
.attr({
transform: function(d, i){
var y = cellSize * i;
var x = 0;
if(i % 2 === 0){
x += cellSize / 2;
}
return 'translate(' + [x, y] + ')';
}
});
rowGroup
.attr({
transform: function(d, i){
var y = cellSize * i;
var x = 0;
if(i % 2 === 0){
x += cellSize / 4;
}
else{
x -= cellSize / 4;
}
return 'translate(' + [x, y] + ')';
}
});
rowGroup.exit().remove();
var cells = rowGroup.selectAll('circle.cell')
.data(function(d, i){
return d;
});
cells.enter().append('circle')
.classed('cell', true);
cells.attr({
r: (cellSize / 2) * 0.9,
fill: function(d){
return d3.rgb(d, d, d).toString();
},
filter: 'url(#f1)',
cy: cellSize / 2,
cx: function(d, i){
return cellSize * i + cellSize / 2;
}
});
cells.exit().remove();
}
</script>
</body>
</html>
Modified http://d3js.org/d3.v3.min.js to a secure url
https://d3js.org/d3.v3.min.js