I work at a web application for painting images. I use a CANVAS element and JavaScript to draw on it, but I have a problem: how can I load an image from the PC of the user and draw it on the canvas? I don't want to save it on the server, only on the webpage.
Here is a shortened version of the code:
HTML:
Open file: <input type="file" id="fileUpload" accept="image/*" /><br />
<canvas id="canvas" onmousemove="keepLine()" onmouseup="drawLine()" onmousedown="startLine()" width="900" height="600" style="background-color:#ffffff;cursor:default;">
Please open this website on a browser with javascript and html5 support.
</canvas>
JavaScript:
var x = 0;
var y = 0;
var clicked = false;
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
context.strokeStyle = "black";
context.lineCap = "round";
canvas.addEventListener('mousemove', function(e) { getMousePos(canvas, e); }, false);
takePicture.onchange = function (event) {
var files = event.target.files,
file;
if (files && files.length > 0) {
file = files[0];
processImage(file);
}
};
function processImage(file) {
var reader = new FileReader();
reader.readAsDataURL(file)
reader.onload = function(e) {
var img = new Image();
img.onload = function() {
context.drawImage(img, 100,100)
}
img.src = e.target.result;
}
}
// functions for drawing (works perfectly well)
function getMousePos(canvas, e) {
var rect = canvas.getBoundingClientRect();
x = evt.clientX - rect.left;
y = evt.clientY - rect.top;
}
function startLine() {
context.moveTo(x,y);
context.beginPath();
clicked = true;
}
function keepLine() {
if(clicked) {
context.lineTo(x,y);
context.stroke();
context.moveTo(x,y);
}
}
function drawLine() {
context.lineTo(x,y);
context.stroke();
clicked = false;
}
There's no copyright
const EL = (sel) => document.querySelector(sel);
const ctx = EL("#canvas").getContext("2d");
function readImage() {
if (!this.files || !this.files[0]) return;
const FR = new FileReader();
FR.addEventListener("load", (evt) => {
const img = new Image();
img.addEventListener("load", () => {
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.drawImage(img, 0, 0);
});
img.src = evt.target.result;
});
FR.readAsDataURL(this.files[0]);
}
EL("#fileUpload").addEventListener("change", readImage);
canvas {display: block;}
<input type='file' id="fileUpload" />
<canvas id="canvas" width="300" height="200"></canvas>
<html>
<head>
<script type="text/javascript" src="http://fiddle.jshell.net/js/lib/mootools-core-1.4.5-nocompat.js"></script>
<script type="text/javascript">
//<![CDATA[
window.addEvent('load', function() {
var imageLoader = document.getElementById('imageLoader');
imageLoader.addEventListener('change', handleImage, false);
var c = document.getElementById('myCanvas');
var ctx = c.getContext('2d');
function handleImage(e){
var reader = new FileReader();
reader.onload = function(event){
var img = new Image();
img.onload = function(){
c.width = img.width;
c.height = img.height;
ctx.drawImage(img,0,0);
}
img.src = event.target.result;
}
reader.readAsDataURL(e.target.files[0]);
}
});//]]>
</script>
</head>
<body>
<div style="background:#990; width:100%; padding:20px; ">
<label>Image File:</label><br/>
<input type="file" id="imageLoader" name="imageLoader"/>
</div>
<canvas id="myCanvas" ></canvas>
</body>
</html>
Here is a much simpler method, which doesn't use inefficient data urls:
var canvas = document.getElementById('canvas')
var input = document.getElementById('input')
var c2d = canvas.getContext('2d')
input.onchange=function() {
var img = new Image()
img.onload = function() {
canvas.width = this.width
canvas.height = this.height
c2d.drawImage(this, 0, 0)
URL.revokeObjectURL(this.src)
}
img.src = URL.createObjectURL(this.files[0])
}
<input type=file id=input> <br>
<canvas id=canvas></canvas>
Related
I want to check for the size of image, and then display the image as a cropped version by defining the set size(w*h).
How can i do this?
This is the code I have tried:
var filesSelected = document.getElementById("inputFileToLoad").files;
if (filesSelected.length > 0)
{
var fileToLoad = filesSelected[0];
if (fileToLoad.type.match("image.*"))
{
var fileReader = new FileReader();
fileReader.onload = function(fileLoadedEvent)
{
var imageLoaded = document.createElement("img");
imageLoaded.src = fileLoadedEvent.target.result;
document.body.appendChild(imageLoaded);
};
fileReader.readAsDataURL(fileToLoad);
}
}
<input type="file" onchange="handleFiles(this.files[0])" id="inputFileToLoad">
<canvas id="canvas"></canvas>
function handleFiles(fileToLoad) {
if (fileToLoad.type.match("image.*")) {
var fileReader = new FileReader();
fileReader.onload = function (fileLoadedEvent) {
var img = new Image();
img.onload = function () {
var canvas = document.getElementById("canvas");
canvas.width = img.width;
canvas.height = img.height;
var ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0);
// cropped = ctx.getImageData(x, y, crop_width, crop_height);
cropped = ctx.getImageData(500, 500, 200, 200);
// clearing is optional ... new img is over the old one
ctx.clearRect(0, 0, canvas.width, canvas.height);
// re-size canvas to croped img size
canvas.width = 200;
canvas.height = 200;
ctx.putImageData(cropped, 0, 0)
};
img.src = fileLoadedEvent.target.result;
};
fileReader.readAsDataURL(fileToLoad);
}
}
draw the imageLoaded into canvas of the size w*h shifted by some position
get the image data by yourcanvas.toDataUrl()
place the image data into image element
The function that does this
function getImagePortion(imgObj, newWidth, newHeight, startX, startY, ratio){
/* the parameters: - the image element - the new width - the new height - the x point we start taking pixels - the y point we start taking pixels - the ratio */
//set up canvas for thumbnail
var tnCanvas = document.createElement('canvas');
var tnCanvasContext = canvas.getContext('2d');
tnCanvas.width = newWidth; tnCanvas.height = newHeight;
/* use the sourceCanvas to duplicate the entire image. This step was crucial for iOS4 and under devices. Follow the link at the end of this post to see what happens when you don’t do this */
var bufferCanvas = document.createElement('canvas');
var bufferContext = bufferCanvas.getContext('2d');
bufferCanvas.width = imgObj.width;
bufferCanvas.height = imgObj.height;
bufferContext.drawImage(imgObj, 0, 0);
/* now we use the drawImage method to take the pixels from our bufferCanvas and draw them into our thumbnail canvas */
tnCanvasContext.drawImage(bufferCanvas, startX,startY,newWidth * ratio, newHeight * ratio,0,0,newWidth,newHeight);
return tnCanvas.toDataURL();
}
is step by step described here
Thank you guys,
Using Canvas is the right approach here. This is my final piece of code
Here is the final Code:
Ref Link
<html>
<title>
Upload Image
</title>
<div style="text-align: center">
<h1>: UPLOAD IMAGE : </h1>
</div>
<div>
<input type="file" id="imageLoader" name="imageLoader" onchange="checkFileDetails()"/>
<br/>
<h3>Horizontal<h3>
<canvas id="imageCanvas1"></canvas>
<br/>
<h3>Vertical<h3>
<canvas id="imageCanvas2"></canvas>
<br/>
<h3>Horizontal Small<h3>
<canvas id="imageCanvas3"></canvas>
<br/>
<h3>Gallery<h3>
<canvas id="imageCanvas4"></canvas>
</div>
<script>
//Check for the image Size and type
// Display Image in the required format
var imageLoader = document.getElementById('imageLoader');
imageLoader.addEventListener('change', handleImage1, false);
var canvas1 = document.getElementById('imageCanvas1');
var ctx1 = canvas1.getContext('2d');
function handleImage1(e){
var reader = new FileReader();
reader.onload = function(event){
var img = new Image();
img.onload = function(){
canvas1.width = 755;
canvas1.height = 450;
ctx1.drawImage(img,0,0);
}
img.src = event.target.result;
}
reader.readAsDataURL(e.target.files[0]);
}
var imageLoader1 = document.getElementById('imageLoader');
imageLoader1.addEventListener('change', handleImage2, false);
var canvas2 = document.getElementById('imageCanvas2');
var ctx2 = canvas2.getContext('2d');
function handleImage2(e){
var reader = new FileReader();
reader.onload = function(event){
var img = new Image();
img.onload = function(){
canvas2.width = 365;
canvas2.height = 450;
ctx2.drawImage(img,0,0);
}
img.src = event.target.result;
}
reader.readAsDataURL(e.target.files[0]);
}
var imageLoader2 = document.getElementById('imageLoader');
imageLoader2.addEventListener('change', handleImage3, false);
var canvas3 = document.getElementById('imageCanvas3');
var ctx3 = canvas3.getContext('2d');
function handleImage3(e){
var reader = new FileReader();
reader.onload = function(event){
var img = new Image();
img.onload = function(){
canvas3.width = 365;
canvas3.height = 212;
ctx3.drawImage(img,0,0);
}
img.src = event.target.result;
}
reader.readAsDataURL(e.target.files[0]);
}
var imageLoader3 = document.getElementById('imageLoader');
imageLoader3.addEventListener('change', handleImage4, false);
var canvas4 = document.getElementById('imageCanvas4');
var ctx4 = canvas4.getContext('2d');
function handleImage4(e){
var reader = new FileReader();
reader.onload = function(event){
var img = new Image();
img.onload = function(){
canvas4.width = 380;
canvas4.height = 380;
ctx4.drawImage(img,0,0);
}
img.src = event.target.result;
}
reader.readAsDataURL(e.target.files[0]);
}
</script>
I'm want to make the uploaded image to fill the size of the canvas, by setting the canvas size to the size of the image. The canvas size is set correctly but the image becomes smaller, and doesn't fill the canvas. How can I make the image fill the canvas? here's what I've tried so far.
<canvas id="canvas" style="border: 1px solid #000; width: 400px; height: 300px"></canvas>
<input type="file" name="photo" id="image" accept="image/*">
JS
var image = document.getElementById('image');
var canvas = document.getElementById('canvas');
var canvasWidth = 400;
var canvasHeight = 300;
if (image) {
image.addEventListener('change', function () {
var context = canvas.getContext('2d');
if (this.files && this.files[0]) {
var fr = new FileReader();
fr.onload = function (ev) {
var img = new Image();
img.onload = function () {
canvasWidth = img.width;
canvasHeight = img.height;
canvas.style.width = canvasWidth + 'px';
canvas.style.height = canvasHeight + 'px';
context.drawImage(img, 0, 0);
};
img.src = ev.target.result;
};
fr.readAsDataURL(this.files[0]);
}
}, false);
}
var image = document.getElementById('image');
var canvas = document.getElementById('canvas');
var canvasWidth = 400;
var canvasHeight = 300;
if (image) {
image.addEventListener('change', function () {
var context = canvas.getContext('2d');
if (this.files && this.files[0]) {
var fr = new FileReader();
fr.onload = function (ev) {
var img = new Image();
img.onload = function () {
canvasWidth = img.naturalWidth;
canvasHeight = img.naturalHeight;
canvas.width = canvasWidth;
canvas.height = canvasHeight;
context.drawImage(img, 0, 0, canvasWidth, canvasHeight);
};
img.src = ev.target.result;
};
fr.readAsDataURL(this.files[0]);
}
}, false);}
here is you html code
<canvas id="canvas" width="400" height="300" style="border:1px solid red"></canvas>
<input type="file" name="photo" id="image" accept="image/*">
Trying to separate image loading on canvas functionality.
It works perfect like that
html
<label>Image File:</label>
<br/>
<input type="file" id="imageLoader" name="imageLoader" />
<canvas id="imageCanvas"></canvas>
javascript
var imageLoader = document.getElementById('imageLoader');
imageLoader.addEventListener('change', handleImage, false);
var canvas = document.getElementById('imageCanvas');
var ctx = canvas.getContext('2d');
function handleImage(e){
var reader = new FileReader();
reader.onload = function(event){
var img = new Image();
img.onload = function(){
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img,0,0);
}
img.src = event.target.result;
}
reader.readAsDataURL(e.target.files[0]);
}
http://jsfiddle.net/influenztial/qy7h5/
But when I trying to separate it, it stucks because of event.target.result is becaming undefind for some reason.
Code is here
http://jsfiddle.net/qy7h5/1840/
Whats wrong? is there some best practice about that?
You need to understand the code first right. Try my code which works fine.
Where I remove event cast and Image onload cast , also remove Image as argument which had been worked as event not image object.
var imageLoader = document.getElementById('imageLoader');
imageLoader.addEventListener('change', handleImage, false);
var canvas = document.getElementById('imageCanvas');
var ctx = canvas.getContext('2d');
function handleImage(e) {
var reader = new FileReader();
reader.onload = function(event) {
onReaderLoad(event);
}
reader.readAsDataURL(e.target.files[0]);
}
var onReaderLoad = function(event) {
var image = new Image();
image.onload = function() {
onImageLoad(image);
}
image.src = event.target.result;
}
var onImageLoad = function(img) {
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0, 0);
}
I update fiddle here
I have the following code:
var imageLoader = document.getElementById('imageLoader');
var patternLoader = document.getElementById("patternLoader");
var canvas = document.getElementById('imageCanvas');
var ctx = canvas.getContext('2d');
function handleImage(e) {
var reader = new FileReader();
reader.onload = function (event) {
var img = new Image();
img.onload = function () {
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0, 0);
}
img.src = event.target.result;
}
reader.readAsDataURL(e.target.files[0]);
};
imageLoader.addEventListener("change", handleImage, false);
patternLoader.addEventListener("change", handleImage, false);
How can I load one image over another from inputs and not replace them?
I want it to be like that http://i.gyazo.com/85c8c6bdcd2efcdd6a1c1b156000f204.png
Here's a crude way to add images dynamically. Declare an array to keep track on all your images and scale the canvas based on the largest image.
Since I didn't konw what kind of DOM elements the OP used for "imageLoader" and "patternLoader", I simply used an <input>-tag.
Just keep pasting URLs for images to add images to your canvas. The images will be drawn in the order as you add them.
var c = document.getElementById("canvas");
var ctx = c.getContext("2d");
var maxWidth = 0;
var maxHeight = 0;
var images = [];
var myInput = document.getElementById("myInput");
myInput.addEventListener('change',handleImage,false);
function handleImage(e) {
var myImage = new Image();
myImage.onload = function () {
if (myImage.width > maxWidth) {
maxWidth = myImage.width;
}
if (myImage.height > maxHeight) {
maxHeight = myImage.height;
}
canvas.width = maxWidth;
canvas.height = maxHeight;
images.push(myImage);
drawImages();
}
myImage.src = e.target.value;
}
function drawImages() {
for (var i = 0; i<images.length; i++) {
ctx.drawImage(images[i],canvas.width/2-images[i].width/2,canvas.height/2-images[i].height/2);
}
}
<input type="text" id="myInput"><br />
<canvas id="canvas"></canvas>
I'm trying to build a freeform lasso tool to clip an image inside canvas. I'm using fabric.js to draw the shape.
var canvas = document.getElementById('c');
var ctx = canvas.getContext('2d');
var img = document.createElement('IMG');
img.onload = function() {
var OwnCanv = new fabric.Canvas('c', {
isDrawingMode: true
});
OwnCanv.freeDrawingBrush.color = "purple"
OwnCanv.freeDrawingBrush.width = 4
ctx.clip();
ctx.drawImage(img, 0, 0);
}
img.src = "http://upload.wikimedia.org/wikipedia/commons/3/33/Jbassette4.jpg?uselang=fi";
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.4.0/fabric.min.js"></script>
<canvas id="c" width="500" height="500"></canvas>
This is my attempt which doesn't seem to work, what am I doing wrong here ?
Can anyone help me please? It would really be appreciated.
The image needs to be a fabric.Image.
You could try something like this:
var canvas = document.getElementById('c');
var ctx = canvas.getContext('2d');
var img = document.createElement('IMG');
img.onload = function() {
var OwnCanv = new fabric.Canvas('c', {
isDrawingMode: true
});
var imgInstance = new fabric.Image(img, {
left: 0,
top: 0,
});
OwnCanv.add(imgInstance);
OwnCanv.freeDrawingBrush.color = "purple"
OwnCanv.freeDrawingBrush.width = 4
OwnCanv.on('path:created', function(options) {
var path = options.path;
OwnCanv.isDrawingMode = false;
OwnCanv.remove(imgInstance);
OwnCanv.remove(path);
OwnCanv.clipTo = function(ctx) {
path.render(ctx);
};
OwnCanv.add(imgInstance);
});
}
img.src = "http://upload.wikimedia.org/wikipedia/commons/3/33/Jbassette4.jpg?uselang=fi";
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.4.0/fabric.min.js"></script>
<canvas id="c" width="500" height="500"></canvas>
See these resources for more:
http://fabricjs.com/fabric-intro-part-1/
Multiple clipping areas on Fabric.js canvas
Fabric.js Clip Canvas (or object group) To Polygon