Canvas images are fuzzy and not complete - javascript

I tried every example that is on internet and NONE of them is working.
I tried to get a full image into a canvas, but it's zoomed in with really bad quality.
I tried rotate (standing pictures need to be laying) and I need the dataurl back.
Getting the dataurl was not the problem.
The problem is that it doesn't work.
<script>
function readFile(file, callback){
var reader = new FileReader();
reader.onload = callback
reader.readAsDataURL(file);
result = reader.readAsDataURL(file);
console.log(result);
}
function snapitgetFile(){
snapitloadshit();
}
function snapitloadshit(){
$('#snapitUpload').on('change', function(e){
var filesize = this.files[0].size;
var filename = this.files[0].name;
var extension = filename.substring(filename.lastIndexOf('.')+1);
var filePath = $(this).val();
readFile(this.files[0], function(e) {
//console.log(e.target.result);
var canvas = document.getElementById("pic");
var ctx = canvas.getContext("2d");
var image = new Image();
image.onload = function() {
var imgwidth = this.width;
var imgheigt = this.height;
$('#pic').css('height', imgheigt);
$('#pic').css('width', imgwidth);
ctx.drawImage(image, 0,0);
};
image.src = e.target.result;
});
});
}
</script>
demo: http://www.aeglobalresearch.com/demo/rotate.html
Try to select a picture and you see what I mean.
I googled and checked here, but all examples makes the picture look ugly or moves them to weird position.
I just want to get load the picture, rotate 90 degrees so a picture that is standing is laying.
Get the dataurl and than the rest of my script will do the rest.
Keeping all the exif, it just need to rotate 90 degrees right that's all.
What I'm doing wrong

Do the rotation like this:
make the canvas the same size as the image (as #Akaryatrh says),
translate to the center of the image,
rotate by 90 degrees (==90*Math.PI/180)
draw the image offset by -img.width/2 and -img.height/2
Demo: http://jsfiddle.net/m1erickson/NZZ3s/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; }
#canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var img=new Image();img.onload=start;img.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/2014.png";
function start(){
canvas.width=img.width;
canvas.height=img.height;
ctx.translate(img.width/2,img.height/2);
ctx.rotate(90 * Math.PI/180);
ctx.drawImage(img,-img.width/2,-img.height/2);
}
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=300 height=300></canvas>
</body>
</html>

Replace these lines :
$('#pic').css('height', imgheigt);
$('#pic').css('width', imgwidth)
With this :
canvas.height = imgheigt;
canvas.width = imgwidth;
Actually you were setting width and height css styles to your canvas, while you were supposed to modify element attributes.
[EDIT] Here's a full solution on jsfiddle with 90° rotation : http://jsfiddle.net/Akaryatrh/r6u9c/

Related

Reading pixel data by JavaScript thought Canvas

I have a problem t read the pixel's RGBA data from a image.But I am facing that all RGBA data( all 4 bytes for all pixel ) zero value.
i use this code for JavaScript :
By the way I use this code for html.
and tehn I run html by Chrome or Firefox but When I see the console log the all value of pixel Data is Zero.Why?
var canvas= document.getElementById('mycanvas');
var c=canvas.getContext("2d");
// c.beginPath();
// c.moveTo(0,0);
// c.lineTo(500,200);
// c.stroke();
var img = new Image();
img.src = 'https://mdn.mozillademos.org/files/5397/rhino.jpg';
img.crossOrigin = "Anonymous";
// var img= document.getElementById('image')
img.onload=function () {
c.drawImage(img,0,0);
}
var myImageData = c.getImageData(0, 0, 500, 500);
//var myImageData = c.createImageData(600, 600);
var numBytes = myImageData.data.length;
var pixelData=myImageData.data;
console.log (numBytes);
console.log (pixelData);
// var x= function () {
// for(var i=0;i<pixelData.length;i+=40)
// {
// pixelData[i] = 255 - pixelData[i]; // red
// pixelData[i + 1] = 255 - pixelData[i + 1]; // green
// pixelData[i + 2] = 255 - pixelData[i + 2]; // blue
// }
// c.putImageData(myImageData, 0, 0);
// };
// //if (pixelData[i]&&pixelData[i+1]&&pixelData[i+2]===255) {
// //console.log (numBytes);
// //}
// //else {}
// //};
// //
// x();
//pixel = imageData.data[((row * (imageData.width * 4)) + (colume * 4)) + colorindex];
//var img = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream"); // here is the most important part because if you dont replace you will get a DOM 18 exception.
//window.location.href=image;
<!DOCTYPE html>
<html>
<head>
<title>Image processing</title>
<style type="text/css">
</style>
</head>
<body>
<canvas id="mycanvas" width="300" height="227">
</canvas>
<img src="https://mdn.mozillademos.org/files/5397/rhino.jpg" id="image" style="display:none;">
</style>
</style>="">
<script src="img.js">
</script>
</body>
</html>
This won't work as the image comes from another domain. The canvas accepts only images from the same origin. You cannot and should not be using getImageData() from external sources that don't support CORS.
But you can convert the image into dataURL and then paint the canvas.
Edit: Sorry for not expressing it properly. The only way would be to locally download the image to your server/domain and then draw it on the canvas.
I solved my problme.
firstly as Mohanesh Said we need use Localhost or http domain.So I installed the Python and used this command to creat localhost erver.
Python -m http.server
Second I used the creatpattern command instead drawimage.this code works for me:
var canvas = document.getElementById('mycanvas')
var c = canvas.getContext('2d');
// canvas.height = window.innerHeight;
// canvas.width = window.innerWidth;
var img = document.getElementById("image")
img.crossOrigin = "Anonymous";
var ptrn = c.createPattern(img, 'no-repeat');
c.fillStyle = ptrn;
c.fillRect(0, 0, canvas.width, canvas.height);
var myImageData = c.getImageData(0, 0, canvas.width, canvas.height);
var numBytes = myImageData.data.length;
var pixelData = myImageData.data;
console.log(numBytes);
console.log(pixelData);
<!DOCTYPE html>
<html>
<head>
<title>Image processing</title>
<style type="text/css">
</style>
</head>
<body>
<canvas id="mycanvas" width="100" height="100">
</canvas>
<img src="test1.png" alt="" id="image" style="display: none;" />
<script src="img22.js">
</script>
</body>
</html>

Getting the RGB value of image for colour wheel

I am trying to grab the RGB value from a click on a colour wheel image.
Now i am trying to grab the RGB from this Colour wheel image below without using canvas getImageData.
How can i do this without canvas?
With canvas you can run.
$('#picker').click(function(e) { // mouse move handler
// get coordinates of current position
var canvasOffset = $(canvas).offset();
var canvasX = Math.floor(e.pageX - canvasOffset.left);
var canvasY = Math.floor(e.pageY - canvasOffset.top);
alert("canvasX " + canvasX + " canvasY " + canvasY);
// get current pixel
var imageData = ctx.getImageData(canvasX, canvasY, 1, 1);
var pixel = imageData.data;
alert(JSON.stringify(pixel));
});
I cannot use canvas for this only javascript can anyone tell me the best way to getImageData from a image would i need to build a rgb grid with a for loop over the top and work out the selected pixel from the x and y value and then match it.
Really stumped on where to start any help?
Here's #Pointy's good idea put to code:
Illustrating with just 1 of your color wheel wedges. You can expand this starting point to include all wedges in your color wheel.
Example code and a Demo: http://jsfiddle.net/m1erickson/9pc4orw8/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; }
#wheel{border:1px solid red;}
#results{width:50px;height:25px;background-color:black;border:1px solid green;}
</style>
<script>
$(function(){
var $wheel=$("#wheel");
var wheelOffset=$wheel.offset();
var offsetX=wheelOffset.left;
var offsetY=wheelOffset.top;
var PI=Math.PI;
var cx=0;
var cy=0;
// define the angle & radius of each color in the color wheel
var colors=[];
colors.push({sAngle:0,eAngle:PI/6,sRadius:0,eRadius:15,color:'rgb(255,255,255)'});
colors.push({sAngle:0,eAngle:PI/6,sRadius:15,eRadius:32,color:'rgb(253,237,238)'});
colors.push({sAngle:0,eAngle:PI/6,sRadius:32,eRadius:53,color:'rgb(251,211,212)'});
colors.push({sAngle:0,eAngle:PI/6,sRadius:53,eRadius:87,color:'rgb(246,145,149)'});
colors.push({sAngle:0,eAngle:PI/6,sRadius:87,eRadius:117,color:'rgb(240,73,80)'});
colors.push({sAngle:0,eAngle:PI/6,sRadius:117,eRadius:138,color:'rgb(237,27,36)'});
$("#wheel").mousedown(function(e){handleMouseDown(e);});
// test the current mouse position against the saved angle & radius of each color
// return the colors index of any color under the mouse
function hit(mx,my){
var hitIndex=-1;
for(var i=0;i<colors.length;i++){
var c=colors[i];
var a0=c.sAngle;
var a1=c.eAngle;
var r0=c.sRadius;
var r1=c.eRadius;
var dx=mx-cx;
var dy=my-cy;
var radius=Math.sqrt(dx*dx+dy*dy);
var angle=Math.atan2(dy,dx);
if(angle>a0 && angle<a1 && radius>r0 && radius<r1){
hitIndex=i;
break;
}
}
return(hitIndex);
}
function handleMouseDown(e){
e.preventDefault();
e.stopPropagation();
mx=parseInt(e.clientX-offsetX);
my=parseInt(e.clientY-offsetY);
var colorIndex=hit(mx,my);
if(colorIndex>=0){
$('#results').css('background-color',colors[colorIndex].color);
}
}
}); // end $(function(){});
</script>
</head>
<body>
Click to select color:<div id=results></div>
<img id=wheel src='https://dl.dropboxusercontent.com/u/139992952/multple/colorwheel1.png'/>
</body>
</html>

Very High Resolution Images in HTML5 Canvas

At the end of this question is an SSCCE to display a 24000x12000 Miller projection of satellite imagery on an HTML5 canvas. It has a couple problems:
Rather than showing the entire image in one screen as I desire only a small section of the upper left corner is displayed.
The image suffers from extreme pixellation that should not appear at the scale displayed because the image is very high resolution
The image used is available at Wikimedia. I renamed it "world.jpg".
This is not a normal web application and the large image will not be downloaded during application execution so any advice to not require downloading such a large image is moot.
The application will dynamically zoom into various map areas, thus the large image size.
In the real code I use an external stylesheet and javascript file. I integrated them into the html solely for the SSCCE.
This is the code.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>The Earth</title>
<script type="text/javascript">
function draw() {
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var map = new Image();
map.src = "world.jpg";
map.onload = function() {
var width = window.innerWidth;
var height = window.innerHeight;
ctx.drawImage(map, 0, 0, width, height);
};
}
</script>
<style>
html, body {
width: 100%;
height: 100%;
margin: 0px;
}
#canvas {
width: 100%;
height: 100%;
position: absolute;
top: 0px;
left: 0px;
background-color: rgba(0, 0, 0, 0);
}
</style>
</head>
<body onload="draw();">
<canvas id="canvas"></canvas>
</body>
</html>
Use the version of context.drawImage that clips and scales the original image:
context.drawImage(
sourceImage,
clipSourceAtX, clipSourceAtY, sourceClipWidth, sourceClipHeight,
canvasX, canvasY, canvasDrawWidth, canvasDrawHeight
)
For example, assume that you are focusing on coordinate [x==1000,y==500] on the image.
To display the 640px x 512px portion of the image at [1000,500] you can use drawImage like this:
context.drawImage(
// use "sourceImage"
sourceImage
// clip a 640x512 portion of the source image at left-top = [1000,500]
sourceImage,1000,500,640,512,
// draw the 640x512 clipped subimage at 0,0 on the canvas
0,0,640,512
);
A demo: http://jsfiddle.net/m1erickson/MtAEY/
Here's the working javascript code, formatted nicely.
function draw() {
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var map = new Image();
map.src = "world.jpg";
map.onload = function() {
var width = window.innerWidth;
var height = window.innerHeight;
canvas.width=width;
canvas.height=height;
var mapWidth=map.width;
var mapHeight=map.height;
var scale=scalePreserveAspectRatio(mapWidth,mapHeight,width,height);
ctx.mozImageSmoothingEnabled = false;
ctx.imageSmoothingEnabled = false;
ctx.webkitImageSmoothingEnabled = false;
ctx.drawImage(map, 0, 0, mapWidth, mapHeight, 0, 0, mapWidth*scale, mapHeight*scale);
};
}
function scalePreserveAspectRatio(imgW,imgH,maxW,maxH){
return(Math.min((maxW/imgW),(maxH/imgH)));
}
The key is the two lines
canvas.width=width;
canvas.height=height;
Simply setting these to 100% in CSS doesn't work, the 100% is apparently not 100% of the inner dimensions of the window as I assumed. Since these dimensions are dynamic they must be set via JS not CSS.

drawing over an Image in HTML5 Canvas while preserving the image

In HTML5 Canvas, what's the simplest way to draw and move a line over an Image (already on the canvas), preserving the image underneath? (e.g. have a vertical line track the mouse X position)
My current canvas:
$(document).ready(function() {
canvas = document.getElementById("myCanvas");
context = canvas.getContext("2d");
imageObj = new Image();
imageObj.onload = function() {
context.drawImage(imageObj, 0,0);
}
imageObj.src = "http://example.com/some_image.png";
$('#myCanvas').click(doSomething);
});
You will have to do most of the ground-work with canvas which in this case you will have to implement the functionality to move the line and then redraw everything.
The steps can be:
Keep the line as an object which can self-render (method on the object)
Listen to mousemove (in this case) in order to move the line
For each move, redraw background (image) then render the line at its new position
You can redraw the background as a whole or you can optimize it to just draw over the last line.
Here is some example code of this and a live demo here:
var canvas = document.getElementById('demo'), /// canvas element
ctx = canvas.getContext('2d'), /// context
line = new Line(ctx), /// our custom line object
img = new Image; /// the image for bg
ctx.strokeStyle = '#fff'; /// white line for demo
/// start image loading, when done draw and setup
img.onload = start;
img.src = 'http://i.imgur.com/O712qpO.jpg';
function start() {
/// initial draw of image
ctx.drawImage(img, 0, 0, demo.width, demo.height);
/// listen to mouse move (or use jQuery on('mousemove') instead)
canvas.onmousemove = updateLine;
}
Now all we need to do is to have a mechnism to update the background and the line for each move:
/// updates the line on each mouse move
function updateLine(e) {
/// correct mouse position so it's relative to canvas
var r = canvas.getBoundingClientRect(),
x = e.clientX - r.left,
y = e.clientY - r.top;
/// draw background image to clear previous line
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
/// update line object and draw it
line.x1 = x;
line.y1 = 0;
line.x2 = x;
line.y2 = canvas.height;
line.draw();
}
The custom line object is in this demo very simple:
/// This lets us define a custom line object which self-draws
function Line(ctx) {
var me = this;
this.x1 = 0;
this.x2 = 0;
this.y1 = 0;
this.y2 = 0;
/// call this method to update line
this.draw = function() {
ctx.beginPath();
ctx.moveTo(me.x1, me.y1);
ctx.lineTo(me.x2, me.y2);
ctx.stroke();
}
}
If you are not gonna do anything specific with the image itself you can also set it as a background-image using CSS. You will still need to clear the canvas before redrawing the line though.
May this is not an actual answer, just in case you need it (in the future). Working with canvas would be better (and easier) with some library. I have tried EaselJS of CreateJS and find myself loving it.
You can have a look at it EaselJS
(I have done an example allow drawing and dragging image using EaselJS long time before)
You can get your "crosshairs" by listening to mousemove events and then:
clear the canvas
draw the image
draw your line at the mouse position
Here is code and a Fiddle: http://jsfiddle.net/m1erickson/jEc7N/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; padding:20px; }
#canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
ctx.lineWidth=2;
var canvasOffset=$("#canvas").offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
var img=new Image();
img.onload=function(){
canvas.width=img.width;
canvas.height=img.height;
ctx.drawImage(img,0,0);
}
img.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/KoolAidMan.png";
function handleMouseMove(e){
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.drawImage(img,0,0);
ctx.beginPath();
ctx.moveTo(mouseX,0);
ctx.lineTo(mouseX,canvas.height);
ctx.moveTo(0,mouseY);
ctx.lineTo(canvas.width,mouseY);
ctx.stroke();
}
$("#canvas").mousemove(function(e){handleMouseMove(e);});
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=300 height=300></canvas>
</body>
</html>
or just use 2 layers:
background layer has image and do not change,
top layer has line, what you can clear and redraw it lots of time without affecting background layer.

How to change the fillStyle of a canvas element using javascript or jquery?

I have some html5 canvas code to make an image, the current fillstyle is green, but when I link is clicked, it should change to red, but it's not working. How do I fix this? thanks
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<script>
window.onload = function() {
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
context.fillStyle = "rgb(0,200,0)";
context.fillRect (0, 0, 608, 105);
var img = new Image();
img.src = 'Round Borders.png';
context.drawImage(img,0,0);
var dataURL = canvas.toDataURL();
document.getElementById("canvasImg").src = dataURL;
};
</script>
<script type="text/javascript">
function change_bg_color(val) {
document.getElementById('myCanvas').getContext('2d').fillStyle = val;
}
</script>
</head>
<body onmousedown="return false;">
<canvas id="myCanvas" width="608" height="105" style="display:none;"></canvas>
<img id="canvasImg" title="Right click to save me!">
<br/>
change to red
</body>
</html>
Working Demo
Think of fillStyle like choosing your paint for an actual painters canvas. You have to choose your paint first, then begin painting. If you want to change your color you have to dip your brush and repaint.
So basically you need to redraw the everything on the canvas with the new fillStyle like the following.
var link = document.getElementsByTagName("a")[0],
canvas = document.getElementById('myCanvas'),
context = canvas.getContext('2d');
link.onclick = function(){
draw('rgb(200,0,0)');
}
function draw(val){
context.fillStyle = val;
context.fillRect (0, 0, 608, 105);
var img = new Image();
img.src = 'Round Borders.png';
context.drawImage(img,0,0);
var dataURL = canvas.toDataURL();
document.getElementById("canvasImg").src = dataURL;
}
draw("rgb(0,200,0)");
Just pass the color to draw and it will repaint with the chosen color.
​

Categories