How to crop a selected rectangle using based on mouse clicks - javascript

I have drawn an image on the canvas.
I want the user to click on the canvas to crop a portion of the image.
How can I do this?

Here's an outline to get you started:
Draw the image onto the canvas
var canvas=document.getElementById('myCanvas');
canvas.drawImage(yourImageObject,0,0);
Listen for mousedown events.
canvas.onmousedown=function(e){handleMouseDown(e);};
Have the user click in the top-left [x0,y0] and bottom-right [x1,y1] corners where they want to crop and record those 2 mouse positions.
The cropping rectangle is defined like this:
var x=x0;
var y=y0;
var width=x1-x0;
var height=y1-y0;
Create a second canvas element and size it to the cropping size:
var secondCanvas = document.createElement('canvas');
secondCanvas.width = width;
secondCanvas.height = height;
document.body.appendChile(secondCanvas);
Use the clipping version of drawImage to draw the cropping rectangle from the first canvas onto the second canvas
secondCanvas.drawImage(canvas,
x,y,width,height, // clip just the cropping rectangle from the first canvas
0,0,width,height // draw just the cropped part onto the first canvas
);
The user's selected portion of the image is now on the second canvas.
If you want to convert the second canvas into an image object, you can do this:
var img=new Image();
img.onload=start;
img.src=secondCanvas.toDataURL();
function start(){
// at this point, img contains the cropped portion of the original image
}

Related

Make a Canvas Transparent [duplicate]

This question already has answers here:
how to edit pixels and remove white background in a canvas image in html5 and javascript
(3 answers)
Closed 7 years ago.
I have a canvas with an id #cnv.
<canvas id="cnv"></canvas>
<img id="img" src=""></img>
I converted the canvas to an image using the code below:
var a = document.getElementById("img");
a.src = document.getElementById("cnv").toDataURL();
After doing so, I save the image in physical disk.Below is the result image:
It's background is white and not transparent. I want to make the image transparent except the lines that is drawn into it.How will I do that?
You can use context.getImageData to fetch the rgba pixel data of your image drawn to a canvas. Then knockout the white values -- leaving only the black lines.
Here's annotated code and a Demo:
// load the image into a new image object
var img=new Image();
img.crossOrigin='anonymous';
img.onload=start;
img.src="https://dl.dropboxusercontent.com/u/139992952/bk.png";
function start(){
// create a canvas element
var canvas=document.createElement("canvas");
var ctx=canvas.getContext("2d");
// size the canvas to the image size
canvas.width=img.width;
canvas.height=img.height;
// draw the image onto the canvas
ctx.drawImage(img,0,0);
// get the pixel data of the canvas
var imgData=ctx.getImageData(0,0,canvas.width,canvas.height);
var data=imgData.data;
// make any pure white pixel transparent: data[i+3]=0
// Note: if needed, lower threshold slightly to catch "off-whites"
var threshold=255;
for(var i=0;i<data.length;i++){
if(data[i]==threshold && data[i+1]==threshold && data[i+2]==threshold){
data[i+0]=0;
data[i+1]=0;
data[i+2]=0;
data[i+3]=0;
}
}
// put the modified pixels back on the canvas
ctx.putImageData(imgData,0,0);
// create an image from the canvas contents
// and add that image to the page
var img1=new Image();
img1.onload=function(){
document.body.appendChild(img1);
}
img1.src=canvas.toDataURL();
}
<h4>Image with pure white knocked out</h4>
<br>

Erasing Parts of an Image on HTML5 Canvas?

I have an HTML5 Canvas. I am using the KineticJS(KonvaJS) canvas library. On a blank canvas I dram an image as shown in the figure below. Now I want to create a circle Shape which can be used to erase parts of the image. The red circle in the image is the eraser.
How can I erase parts of an Image on HTML5 Canvas?
You can use Compositing to "erase" pixels.
Specifically you use destination-out compositing.
KineticJS does not support compositing, but you still have a couple of options:
(Note: KineticJS has become KonvaJS and I haven't checked whether KonvaJs supports compositing. If it now does, just use destination-out compositing inside KonvaJS)
Option#1: Use a native canvas element as your Kinetic.Image source
Create an in-memory html5 canvas using var c=document.createElement,
Resize the canvas to image size,
drawImage your image onto the canvas,
Create a Kinetic.Image and set its image property to a reference to the native canvas. The Kinetic.Image will display whatever is drawn onto the native canvas.
var kImage=new Kinetic.Image({
...
image:c,
...
Set the canvas Compositing to cause new drawings to "erase" existing pixels:
c.globalCompositeOperation='destination-out';
Listen for drag events on your circle-eraser. Use those events to draw a circle on the canvas that move just like the Kinetic circle-eraser moves. Since the canvas's compositing is set to "erase", new drawings of the circle on the canvas will erase the image on the canvas.
Your Kinetic.Image exactly reflects its canvas source (var c), so your Kinetic.Image will also display the image being erased in response to the Kinetic circle-eraser movements.
Option#2: Use a Kinetic.Shape
You can do the same operation as Option#1 by creating a Kinetic.Shape on a separate layer and getting a reference to the native canvas context using:
var ctx = myShapeLayer.getContext()._context;
This is a weaker option because KineticJS will redraw the shape--causing your erasing to be undone. Therefore you must do the additional step of saving all your circle-eraser's movements and replaying those movements (in drawFunc) to redo your erasing.
Thanks for markE for his detailed answer,
I have tried to get the context from the Konva.Layer() and it worked.
var freeHandDrawingImage = new Image();
freeHandDrawingImage.onload = function() {
var context = freeHandDrawingLayer.getContext('2d');
context.drawImage(this, 0,0);
context.globalCompositeOperation='destination-out';
freeHandDrawingLayer.draw();
};
freeHandDrawingImage.src = "image.png";
and I have used the Konva.Shape to erase by "destination-out" and draw free draw by custom "source-over":
freeDrawingType = 'brush';
isFreeDrawingMode = false;
isPaint = false;
lastPointerPosition = {};
drawFreeDrawings = function(){
var freeDraw = new Konva.Shape({
name: "freeDraw",
stroke: 'black',
strokeWidth: 5,
closed : false,
sceneFunc: function(context){
// free draw quad
debugger;
if(isPaint){
if (freeDrawingType === 'brush') {
context.globalCompositeOperation = 'source-over';
}
if (freeDrawingType === 'eraser') {
context.globalCompositeOperation = 'destination-out';
}
context.beginPath();
context.moveTo(lastPointerPosition.x, lastPointerPosition.y);
var newPosition = stage.getPointerPosition();
context.lineTo(newPosition.x, newPosition.y);
context.stroke();
debugger;
lastPointerPosition = newPosition;
context.strokeShape(this);
}
}
});
freeHandDrawingLayer.add(freeDraw);
// now we need to bind some events
// we need to start drawing on mousedown
// and stop drawing on mouseup
selectionBoxBackground.on('mousedown', function() {
if(isFreeDrawingMode){
isPaint = true;
lastPointerPosition = stage.getPointerPosition();
stage.draw();
}
});
selectionBoxBackground.on('mouseup', function() {
if(isFreeDrawingMode){
isPaint = false;
}
});
// and core function - drawing
selectionBoxBackground.on('mousemove', function() {
if (!isPaint) {
return;
}
freeHandDrawingLayer.draw();
});
}
In plain JavaScript this is pretty straight forward.
First get your canvas and drawing context ready:
var context=document.getElementById("your_canvas_id").getContext("2d");
var image=document.getElementById("your_image_id");
Now you want to draw the image to the context:
context.drawImage(image,0,0,image.width,image.height,0,0,image.width,image.height);
Now, when you want to erase part of your image, just draw over the canvas:
var x=y=radius=10;// Circle coordinates and radius.
context.fillStyle="#ffffff";// Your eraser color (not transparent)
context.beginPath();
context.arc(x,y,radius,0,Math.PI*2);
context.fill();
This only simulates erasing, however. If you want what you erase to be transparent afterwards, you might look into context.clearRect, but I'm not sure how you would do that with a circle.

Saving Canvas with the background image

I have a HTML5 canvas element with a background image. User is allowed to draw on the image and then need to save the complete canvas element with the background. I'm using below code for saving part but it only gets the canvas drawing but not the background image. what could i do to get the background image also?
var canvas = document.getElementById('your_canvas');
var context = canvas.getContext('2d');
// save canvas image as data url (png format by default)
var dataURL = canvas.toDataURL();
// set canvasImg image src to dataURL
// so it can be saved as an image
document.getElementById('canvasImg').src = dataURL;
Update:
My HTML
<div name='coords1' class='canvas-area input-xxlarge' disabled
placeholder='Shape Coordinates' id='imgDiv'
data-image-url='BackGround.jpg'></div>
I have the above div in my HTML page. then i dynamically create the canvas and draw on it. It's a bit lengthy code.
Don't use image on the div, draw the image on the canvas ..
use the following code to draw image on canvas,
var img=new Image();
img.src=/*image src*/;
var ctx=canvas.getContext("2d");
img.onload=function()
{
ctx.drawImage(img,x,y,width,height);
}
After image drawing completion at img.onload callback , allow user to draw on canvas...
Now save the canvas drawing....
To Get the Canvas with backgound Image
context.globalCompositeOperation="destination-over";
drawImage(yourBackgroundImage,0,0);

how to draw both image and sketch on canvas together

I want to draw an image to canvas and then allow user to draw some sketch on it by sketch.js. Now the situation is:
1.the image has been drawn on the canvas successfully
2. but when my mouse over the canvas, then image disappeared, and the canvas shows empty
3. when I dragged the mouse, some sketch shows on the empty canvas(the sketch looks correct)
so, I've made both functions right, but I'm confused about the part in between. I hope to draw the sketch on the canvas with the image on it. Here is my code:
index.html:
<canvas id="mysketch" width="578" height="400" style="margin: 0px; "></canvas>
canvas.js:
var mysketch = jQuery("#mysketch");
// draw the captured image to canvas
var displayImage = function() {
var context = mysketch.get(0).getContext("2d");
var image = new Image();
image.onload = function() {
context.drawImage(image, 0, 0);
}
// prepend the required image info again
image.src = dataURL;
// call sketch.js to draw sketch on the canvas
mysketch.sketch({defaultColor: "#ff0"});
}
I think that, on your call to sketch method
sketch.js is clearing the canvas first then allows you to draw something on it.
As you can see in the link here, in the 3rd example (i.e. Tools Example) the image is not drawn by drawImage method.
It is actually the background of the canvas which will always be there as background, whatever you draw on it.
So what you can do is:
either do same thing as in the example i.e. set your image as background,
or make a new canvas just behind your canvas with same width, height and on same location and draw your image on it. and do your sketch thing on the second one.

Using JavaScript or jQuery, how can I get the RGB color where ever the mouse is moving specially in <img> or <div> elements

I have an image, <img src="/meAndMy/face.jpg" />. I am trying to get the RGB color when ever or where ever I move my mouse cursor.
How can I do this with jQuery or plain JavaScript? e.g: http://www.script-tutorials.com/demos/158/index.html
Follow up (for copy paste testing):
<?=$this->headScript(); ?>
<script>
$(document).ready(function()
{
var image = new Image();
var ctx = $('#panel')[0].getContext("2d");
/* Load the picture empty.jpg */
image.onload = function ()
{
ctx.drawImage(image, 0, 0, image.width, image.height);
}
/* How can i reload later new?
image.empty; */
image.src = "/agents/empty.jpg";
/* On mouse over to my image, show me the background with RGB
change mousemove to click if requires */
$('#panel').mousemove(function(e)
{
/* Leave as it is */
var canvasOffset = $(this).offset();
var canvasX = Math.floor(e.pageX - canvasOffset.left);
var canvasY = Math.floor(e.pageY - canvasOffset.top);
var imageData = ctx.getImageData(canvasX, canvasY, 1, 1);
var pixel = imageData.data;
var pixelColor = "rgba("+pixel[0]+", "+pixel[1]+", "+pixel[2]+", "+pixel[3]+")";
/* Meat */
$(document.body).css('background-color',pixelColor);
});
});
</script>
<body>
<canvas id="panel" width="500" height="333"></canvas>
<body>
You can do it just like the script for that demo does. Note that the demo does not use an img element, rather it loads the image into a canvas element. The canvas API allows you to get the pixel data like so:
var imageData = ctx.getImageData(canvasX, canvasY, 1, 1);
var pixel = imageData.data;
See the HTML 5 canvas API for details.
If for whatever reason you are required to load the image into the img element, as opposed to a canvas element, you could:
Dynamically create a canvas element with the same size and at the same location as the img.
Copy the image data from img to canvas via the drawImage method from the canvas context.
Hide the img element, leaving the canvas in its place.
You can't get the color of point of an image only with JavaScript ( without the Canvas support ). You need some server-side.
For example: you have a jpg image. You point somewhere, click. An event-listener should send to the server the coordinates and a server-side application will determine what the color is ( the image should be present on the server, of course). see http://muffinresearch.co.uk/code/javascript/pickr/
For your example - the image is read and displayed by a canvas element. An event-listener gets the coordinates of the click and with getImageData() gets a copy of the pixel. The data property contains info for a red, green, blue, and alpha component.

Categories