I'm creating an application using html canvas and javascript. You upload and image and colour pick from it however I'm having an issue where I can only colour pick colours from a small section of the uploaded image. I've tried a few things to fix it and I'm a bit stumped. Anyone have any ideas? I used this to help me: http://www.webdesignerdepot.com/2013/03/how-to-create-a-color-picker-with-html5-canvas/
<canvas width="600" height="300" id="canvas_picker"></canvas>
<div id="hex">HEX: <input type="text"></input></div>
<div id="rgb">RGB: <input type="text"></input></div>
var $files = document.getElementById('file_upload').files[0];
var reader = new FileReader();
reader.onload = imageIsLoaded;
function imageIsLoaded(e) {
// canvas
var canvas = document.getElementById('canvas_picker');
var context = canvas.getContext('2d');
var $img = $('<img>', { src: e.target.result });
// Draws Image
$img.load(function() {
context.drawImage(this,10, 10);
$("#loader").hide();
});
}
$('#canvas_picker').click(function(event){
// getting user coordinates
var x = event.pageX;
var y = event.pageY;
// getting image data and RGB values
var img_data = canvas.getImageData(x,y , 1, 1).data;
var R = img_data[0];
var G = img_data[1];
var B = img_data[2];
var rgb = R + ',' + G + ',' + B;
// convert RGB to HEX
var hex = rgbToHex(R,G,B);
// making the color the value of the input
console.log(R);
console.log(B);
console.log(G);
$('#rgb input').val(rgb);
console.log(rgb);
$('#hex input').val('#' + hex);
});
function rgbToHex(R, G, B) {
return toHex(R) + toHex(G) + toHex(B)
}
function toHex(n) {
n = parseInt(n, 10);
if (isNaN(n))
return "00";
n = Math.max(0, Math.min(n, 255));
return "0123456789ABCDEF".charAt((n - n % 16) / 16) + "0123456789ABCDEF".charAt(n % 16);
}
reader.readAsDataURL($files);
when I click on a pixel outside the small area, it comes back as 0.
Fixed some issues like getImageData
trying to read canvas
instead of it's context
, and the image being drawn at XY 10,10 instead of 0,0.
Additionally you might want to adjust the Canvas size to the uploaded image W/H.
In order to prevent coordinates miscalculations (cause you're getting the click coordinate respective to the page edges) and to get the exact position of the mouse inside the canvas, you might want to subtract the canvas offset left / top from the resulting coordinate x
, y
var $picked = $("#picked"); // Just to preview picked colors
var canvas = $('#canvas_picker')[0];
var context = canvas.getContext('2d');
$("#file_upload").change(function (e) {
var F = this.files[0];
var reader = new FileReader();
reader.onload = imageIsLoaded;
reader.readAsDataURL(F);
});
function imageIsLoaded(e) {
var img = new Image();
img.onload = function(){
canvas.width = this.width; // If needed? adjust canvas size
canvas.height = this.height; // respective to image size
context.drawImage(this, 0, 0); // Draw image at 0, 0, not at 10, 10
};
img.src = e.target.result;
}
$('#canvas_picker').click(function(event){
var x = event.pageX - $(this).offset().left; // Fixed coordinates
var y = event.pageY - $(this).offset().top; // respective to canvas offs.
var img_data = context.getImageData(x,y , 1, 1).data;
var R = img_data[0];
var G = img_data[1];
var B = img_data[2];
var rgb = R + ',' + G + ',' + B ;
var hex = rgbToHex(R,G,B);
$('#rgb input').val( rgb );
$('#hex input').val('#' + hex);
$picked.append("<span style='background:#"+hex+"'>#"+hex+"</span>");
});
function rgbToHex(R, G, B) {
return toHex(R) + toHex(G) + toHex(B);
}
function toHex(n) {
n = parseInt(n, 10);
if (isNaN(n)) return "00";
n = Math.max(0, Math.min(n, 255));
return "0123456789ABCDEF".charAt((n - n % 16) / 16) + "0123456789ABCDEF".charAt(n % 16);
}
*{margin:0;}
canvas{background:#ddd;}
#picked span{
display:inline-block;
width:50px;
height:50px;
margin:3px;
text-align:center;
text-shadow:1px 1px 1px #000;
font:8px/50px Arial;
color:#fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas width="600" height="300" id="canvas_picker"></canvas><br>
<input type="file" id="file_upload"><br>
<div id="hex">HEX: <input type="text"></div>
<div id="rgb">RGB: <input type="text"></div>
<div id="picked"></div>