Canvas toDataURL with CSS webkitFilter - javascript

I have applied a CSS filter to a canvas like so:
canvas.style.webkitFilter = 'hue-rotate(90deg)';
If I then try to download the content of the canvas using the download attribute of an anchor element:
var imgData = canvas.toDataURL('image/*');
link.download = 'Image';
link.href = imgData;
the downloaded image does not have the applied filter. Even if I use getImageData to just view the image data or try setting the source of an image to the image data the same problem occurs. Is there anyway in JavaScript to get the image data of a canvas with a CSS filter applied?

You can apply Hue-shift in canvas itself.
For example, the CamanJS library has some nice image filters: http://camanjs.com/
This is from their docs:
Hue
Adjusts the hue of the image. It can be used to shift the colors in an
image in a uniform fashion. The Range is 0 to 100.
Sometimes, Hue is expressed in the range of 0 to 360. If that's the
terminology you're used to, think of 0 to 100 representing the
percentage of Hue shift in the 0 to 360 range.
Example code from CamanJS:
Caman("#image", function () {
this.hue(90).render();
});

Related

I would like to know if there is a way to check in Javascript if a bitmap image is a valid mask image?

I want to place a main bitmap on canvas (jpg,png) and I also want to upload a bitmap file that is going to perform as a mask of the main bitmap.
I would like to know if there is a way to check in Javascript if a bitmap image is a valid mask image? (Like the uploaded image)
I have created a codepen and upload a mask image. If you upload a mask image, you can see the changes on main bitmap on canvas, and if you upload a non mask image nothing will change. I need to validade the mask image by code in some way
`context.drawImage(bg, 0, 0, canvas.width, canvas.height);
maskInput.addEventListener('change', () => {
mask.src = URL.createObjectURL(maskInput.files[0]);
mask.onload = function() {
maskImage.setAttribute('src', mask.src)
isMaskValid(maskImage)
draw()
}
})
function isMaskValid(maskImage){
// todo
}
//You can check all code here
https://codepen.io/thaisdsilve/pen/zYaENbx`
Mask:
(Definition of a "mask iage" in order to base the code: An image mask is a bitmap that specifies an area to paint, but not the color. Namely, a mask image is a monochrome image used to generate the alpha component of an original customer image pixel by pixel, in such a way that a black pixel (RGB 0,0,0) will generate a 100% transparent pixel in the final image (alpha 0), and a white pixel (RGB 255,255,255) will generate a 100% opaque pixel in the final image (alpha 255). Intermediate RGB values ​​in the mask image will generate semi-transparencies in the final image.)
Original image:
Result:
Opening a mask image in the browser is detected by the (pseudo) code
maskInput.addEventListener('change', () => {
mask.src = URL.createObjectURL(maskInput.files[0]);
mask.onload = function() {
maskImage.setAttribute('src', mask.src)
isMaskValid(maskImage)
draw()
}
})
This appears to be loading the same mask image twice, doesn't look at its mime type and doesn't return for an invalid check.
Although it may work without it, I would also suggest releasing the object URL after use, and setting image src values after adding their load event listener (instead of beforehand). Hence you could try something like
maskInput.addEventListener('change', () => {
if(maskInput.files[0].type != "image/png") {
// invalid file type error
alert('Error: mask file of type "image/png" expected')
return;
}
const maskURL = URL.createObjectURL(maskInput.files[0]);
maskImage.onload = function() {
URL.revokeObjectURL( maskURL)
if( isMaskValid(maskImage) {
draw()
}
}
maskImage.src = maskURL;
})
To avoid race conditions between loading the main and mask images, I would suggest disabling the file input element held in maskInput until after the main image element held in bg has loaded.
Validity checking could now check if the bg (the castle) and maskImage elements have the same image dimensions using their naturalWidth and naturalHeight properties. It could also check if the mask image is a grey-scale file by writing it to a canvas and checking that the rgb values for pixels are the same - and return a boolean status for the validity of the mask file.

How to get rotated image with html2canvas

I'm using Guillotine JS to manipulate the image rotation, scale, positions, x,y, when user has finish making changes, I use html2canvas to get the final image generated inside a div, in this case my div has a class .frame, so, when user zoom in or out move left right up, down, I do this:
html2canvas(target, {
onrendered: function(canvas)
{
var data = canvas.toDataURL("image/png");
//console.log(data);
var imgdata = data.replace(/^data:image\/(png|jpg);base64,/, "");
}
})
I have skip a bunch of code this is the only thing I use, with that I get a 64base code for the image inside my div up to this point everything is ok, the generated image is exactly what is need.
The problem is when rotation is apply to the image, for testing I'm using an image with: width: 1036, height: 615px inside a div with: width:676, height:459px.
This is the generated images
Same as before, different area
Same image but this time it has a rotation 180'
same image, rotation 90'
As you can see every time a rotation is use, the result are wrong.
How can I fix that?
I have used Imagemagick to rote and crop the image using guillotine data, the problem here is that the scale is all messup image width * scale only gives 1 x 1px image as a final result, if I hardcode the width and height the result is the same, so I'd love to find a way to fix the rotation with html2canvas.

How to resize canvas contents and upload image to server?

I have been trying to figure out how I could resize the canvas contents to get roughly a 100x100 thumbnail and upload it to the server. I would like to keep my existing canvas in its current size, because all these actions have to be invisible to the user.
I know I can get the contents in the current size of the canvas by using toDataURL, but how could I resize it and then upload to the server?
var image = canvas.toDataURL("image/png");
You can create canvas in your JS script (without appending it to DOM), then draw on it your content from working canvas (your image), resize it in context of your temp canvas ( Post about resizing in canvas ). And only then do canvas.toDataURL("image/png"); to get resized image. Then you send it as base64 string and save on your server as png file.
Thanks to Alexander Kremenets I managed to put together the code I needed. I used the Hermite resize from the question Alexander linked. Also combined code from other questions coming up with this:
var originalCanvas = document.getElementById("c");
// Create canvas for resizing
var resizeCanvas = document.createElement("canvas");
resizeCanvas.height = originalCanvas.height;
resizeCanvas.width = originalCanvas.width;
var resizeCtx = resizeCanvas.getContext('2d');
// Put original canvas contents to the resizing canvas
resizeCtx.drawImage(originalCanvas, 0, 0);
// Resize using Hermite resampling
resampleHermite(resizeCanvas, resizeCanvas.width, resizeCanvas.height, 150, 90);
// Use the resized image to do what you want
var image = resizeCanvas.toDataURL("image/png");

How to get color that is behind a transparent element?

I am working on a site where the body has many color. When the content is scrolled down the background of the content changes.
In the below image u can see body text with blue color background. So when the content is scrolled down with the scrollbar then the background image should also scroll along with the content.
So what happens is when scroll bar stops at a color like blue then automatically the menu header(Home) background should change to blue.
First of all we should know what we want to do. Step one is actually get a color of the image, thus acces a property of the image.
However the browser cannot get direct information of the image itself(You can, of course, get information from the element of the image). However one webbrowser drawing method let us control every aspect of a image: Canvas.
So first we have to convert our image to an canvas element.
This is fairly simply done with drawImage(img, posx, posy, canvasWidth, canvasHeight);
We will also stretch the canvas image + the element to the entire screen. The reason we want to define to size also at the canvas is because this way the canvas will calculate every new generated pixel, so we can acces every of the new pixels:
var screenWidth = window.innerWidth,
screenHeight = window.innerHeight,
c = document.createElement('canvas');
ctx = c.getContext("2d"),
img = document.getElementById("image");
c.width = screenWidth;
c.height = screenHeight;
ctx.drawImage(img, 0, 0, screenWidth, screenHeight);
$(c).attr('id', 'c');
$('body').prepend(c);
$(img).remove();
An Canvas element as is dynamically made and will fit to the screen size(Note that this is only at first start of the webbrowser. So when you resize the canvas will not resize with the screen).
We remove the image as it is no use anymore. It's a good practive to transform from image to canvas in my opinion. As you will be certain that the image will be loaded in the browser first and then transformed to a canvas element.
Next we're going to acces a pixel. You can acces pixel data with getImageData(offsetX, offsetY, sizeX, sizeY).data; And RGBA color array will be returned.
Now the offsetX and offsetY will be the offset of the element color picker. Note that this elements offset should be relative to the webbrowsers viewport as the background is fixed You can do this with getBoundingClientRect();
The size is just 1x1 as we want 1 pixel.
This all should happen when the user is scrolling, you can catch the scroll event with .scroll(function); :
$(window).scroll(function () {
var offset = document.getElementById('color').getBoundingClientRect(),
offsetX = offset.left,
offsetY = offset.top;
var color = document.getElementById('c').getContext('2d').getImageData(offsetX, offsetY, 1, 1).data;
$('header').css('background-color',"rgba("+ color[0] + ', ' + color[1] + ', '+ color[2] + ', ' + color[3] + ")");
});
Where we add the rgba array colors just with the first 4 indexes(Because and rgba collor pattern never has more as 4 values) with plain css to the header element.
Loading External image into a canvas
When you want to transform an external image to a canvas element you might get this error:
Cross-origin image load denied by Cross-Origin Resource Sharing policy.
It is for security reasons that you can't fully acces this image.
As explained here: HTML 5 canvas getImageData from an externally-loaded image
There are some external hosts that supports this, for example dropbox.
Local
However when you just store it locally it will just work fine.
jsFiddle
This method was tested in chrome, IE and firefox.
I want to use those external (dropbox) files
I'm not sure why this happens but for some reason with this method there are still some security diffecults. To enable this CORS you have to add a image property .crossOrigin = "Anonymous";. However when you load the image with HTML the the element has been made without this property. So you should assign this property when the image is created:
var canvas = document.getElementById("c"),
ctx = canvas.getContext("2d"),
screenWidth = window.innerWidth,
screenHeight = window.innerHeight;
// Using image WITH crossOrigin=anonymous
// Succeeds in Chrome+Mozilla, Still fails in IE
var externalImage2 = new Image();
externalImage2.onload = function(){
canvas.width= screenWidth;
canvas.height= screenHeight;
ctx.drawImage(externalImage2, 0, 0, screenWidth, screenHeight);
// this will FAIL on a CORS violation
}
externalImage2.crossOrigin = "Anonymous";
externalImage2.src="https://dl.dropboxusercontent.com/s/8g8lgmdx341j1d6/rainbow_gradient_horizontal.jpg";
This is just an picture i uploaded to my dropbox where i just shared the photo. Note:
The way to convert a share link to a direct link is to change the domain from "www.dropbox.com" to "dl.dropboxusercontent.com". See https://www.dropbox.com/developers/blog/53/programmatically-download-content-from-share-links.
source: Cross-origin image load from cross-enabled site is denied
This creates an image and puts it into an excisting canvas element. So note that you should have a canvas element into your HTML.
jsFiddle
This method does only work for chrome and firefox as other browsers still have some security issues.
Additional note is the pixel that gets captured is the top-left pixel of the 'color-pick' element. You can adjust this offset if you want it to catch, for example, the middle pixel of the element.
This was a very interesting question. I hope it helped!
well, you may give background color of the home bar as transparent if you have no band between the home and the content.
.home{
background:transparent;
}

color to grey scale conversion in canvas

I am trying out a sample code that converts a color image to grey scale on a canvas in WebOS (enyo). When I use the ctx.getImageData method to read the pixels, the imageData contains only zeros. The sample I am using is provided in the link below:
http://chopapp.com/#x8t2ymad
Does WebOS support reading pixel data from canvas? Am I doing something wrong here?
I have refered to the following link for the logic and the code:
http://net.tutsplus.com/tutorials/javascript-ajax/how-to-transition-an-image-from-bw-to-color-with-canvas/
This works fine.
you should move the getimagedata in the callback from the onload event of the image.
something like:
draw: function(image) {
this.ctx.drawImage(event.target, 0, 0);
this.greyImage();
},
and set the source after binding the event
image.onload = enyo.bind(this, "draw");
image.src = "images/image.png";
to avoid a racing condition
now the imagedata is retrieved before the actual pixels are loaded. Which results in an empty array.

Categories

Resources