Proper Cropping of Image Issue - javascript

This is the layout and design of my page.
HTML Code:
<div id="myid_browse_modal_image" >
<image id="img_browse" src=""></image>
</div>
<div id="div_myphoto">
<img id="img_myphoto" src="" alt="ID Photo"/>
</div>
CSS Code:
#myid_browse_modal_image
{
height: 370px;
line-height: 370px;
text-align:center;
border: 1px;
border-style: solid;
border-color: gray;
}
#myid_browse_modal_image > img
{
max-width: 100%;
height: 100%;
}
#div_myphoto > img
{
width: 150px;
height: 150px;
max-width:150px;
max-height: 150px;
border: 2px;
border-style: solid;
border-color: black;
}
My problem goes like this. I am implementing a functionality where I can browse an image and be able to crop it. It looks like the image below:
When I click the "Set as an ID Photo", it calls function that do the cropping functionality:
function myid_browse_crop()
{
var img_browse = document.getElementById('img_browse');
var $img_browse = $(img_browse);
var img_myphoto= document.getElementById('img_myphoto');
var $img_myphoto = $(img_myphoto);
//Create a temporary canvas
var canvas= document.createElement("canvas");
canvas.id = "temp_canvas";
canvas.width = img_browse.width;
canvas.height = img_browse.height;
// get the canvas context;
var ctx = canvas.getContext('2d');
ctx.drawImage(img_browse, 0, 0);
//Get the position of my resizable div relative to the image
var relativeX = $(".browse-selection").offset().left - $("#img_browse").offset().left;
var relativeY = $(".browse-selection").offset().top - $("#img_browse").offset().top;
var relativeW = $(".browse-selection").width();
var relativeH = $(".browse-selection").height();
var imageData = ctx.getImageData(relativeX,relativeY, relativeW, relativeH);
// create destination canvas
var canvas1 = document.createElement("canvas");
canvas1.width = relativeW;
canvas1.height = relativeH;
var ctx1 = canvas1.getContext("2d");
ctx1.rect(0, 0, relativeW, relativeH);
ctx1.putImageData(imageData, 0, 0);
img_myphoto.src = canvas1.toDataURL();
}
The result cropped image is below, which is not right.
It might be because of the dimensions of the image. The image is smaller in reality(202 x 250 pixels), but it gets distorted when browse and selected because of the css below, making it (299 x 370 pixels):
#myid_browse_modal_image > img
{
max-width: 100%;
height: 100%;
}
How will I fix it? To get just the correct selected region. Anyways ".browse -selection" is a div with a dashed lines in the Image 1. It is generated by a jquery plug-in that's why it is not included in my Original HTML Code.

Change
#myid_browse_modal_image > img
{
max-width: 100%;
height: 100%;
}
To this:
#myid_browse_modal_image > img
{
max-width: 100%;
height: auto;
max-height: 370px !important;
}

This issue is cause by having an image file dimensions on disk, different from what is being rendered in the browser.
In this case,I edited my code:
function myid_browse_crop()
{
var img_browse = document.getElementById('img_browse');
var $img_browse = $(img_browse);
var img_myphoto= document.getElementById('img_myphoto');
var $img_myphoto = $(img_myphoto);
//Create a temporary canvas
var canvas= document.createElement("canvas");
canvas.id = "temp_canvas";
canvas.width = img_browse_width ;
canvas.height = img_browse_height;
// get the canvas context;
var ctx = canvas.getContext('2d');
ctx.drawImage(img_browse, 0, 0);
//Get the position of my resizable div relative to the image
var relativeX = $(".browse-selection").offset().left - $("#img_browse").offset().left;
var relativeY = $(".browse-selection").offset().top - $("#img_browse").offset().top;
var relativeW = $(".browse-selection").width();
var relativeH = $(".browse-selection").height();
var xrelativeX = relativeX * (img_browse_width /img_browse.width);
var xrelativeY = relativeY * (img_browse_height/img_browse.height);
var xrelativeW = (img_browse_width /img_browse.width)*relativeW;
var xrelativeH = (img_browse_height/img_browse.height)*relativeH;
var imageData = ctx.getImageData(xrelativeX,xrelativeY, xrelativeW,xrelativeH );
// create destination canvas
var canvas1 = document.createElement("canvas");
canvas1.width = xrelativeW ;
canvas1.height = xrelativeH;
var ctx1 = canvas1.getContext("2d");
ctx1.rect(0, 0, xrelativeW, xrelativeH);
ctx1.putImageData(imageData, 0, 0);
img_myphoto.src = canvas1.toDataURL();
}
img_browse_height and img_browse_width are the actual file size of the image on disk. I had acquired this variables from reading an image file through an input file:
function readURL(input, imageframe) {
if (input.files && input.files[0]) {
var reader = new FileReader();
var image = new Image();
reader.onload = function (e) {
image.src = e.target.result;
image.onload = function() {
//Actual File Size in Disk of "#img_browse"
img_browse_width = this.width;
img_browse_height = this.height;
}
$('#img_browse')
.attr('src', e.target.result);
};
reader.readAsDataURL(input.files[0]);
}
}

Related

EventListener and onClick - why do I have to click twice to trigger?

I am trying to extract base64 HTML image data after clicking a button which loads the base64 data from the server.
When testing locally, I have to click twice initially to get the expected results. And every subsequent click works as expected.
How can I shape this code so that it triggers on only one click?
<html>
<button id="t-load" type="button" data-board="g" data-tid="0" style="font-size: 11px; padding: 0px; width: 90px; box-sizing: border-box; margin: 0px 6px 0px 0px; vertical-align: middle; height: 18px;">Get Captcha</button>
<div id="t-fg" style="width: 100%; height: 100%; position: absolute; background-repeat: no-repeat; background-position: left top; background-image: url("data:image/png;base64,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");"></div>
</html>
<script>
// turn string to image
function b64toImageData(datas) {
return new Promise(async function (resolve, reject) {
// We create an image to receive the Data URI
var img = document.createElement('img');
// When the event "onload" is triggered we can resize the image.
img.onload = function () {
// We create a canvas and get its context.
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
// We set the dimensions at the wanted size.
canvas.width = img.width;
canvas.height = img.height;
// We resize the image with the canvas method drawImage();
ctx.drawImage(this, 0, 0, img.width, img.height);
// get image data
var imageDatas = ctx.getImageData(0, 0, img.width, img.height);
// This is the return of the Promise
resolve(imageDatas);
};
// add data to img
img.src = datas;
})
}
// event listener;
document.addEventListener("click", function () {
document.getElementById("t-load").onclick = async function () {
// get img
var fg = document.getElementById("t-fg").style.backgroundImage.slice(5, -2);
console.log(fg)
// get img data
var base_img = await b64toImageData(fg);
// log results
console.log(base_img.data);
}
});
</script>
Instead of the event handlers that you are using, you can delegate the click handler to the body and use still async.
function b64toImageData(datas) {
return new Promise(async function(resolve, reject) {
// We create an image to receive the Data URI
var img = document.createElement('img');
// When the event "onload" is triggered we can resize the image.
img.onload = function() {
// We create a canvas and get its context.
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
// We set the dimensions at the wanted size.
canvas.width = img.width;
canvas.height = img.height;
// We resize the image with the canvas method drawImage();
ctx.drawImage(this, 0, 0, img.width, img.height);
// get image data
var imageDatas = ctx.getImageData(0, 0, img.width, img.height);
// This is the return of the Promise
resolve(imageDatas);
};
// add data to img
img.src = datas;
})
}
document.body.addEventListener("click", async(e) => {
let el = e.target;
if (el.id == "t-load") {
var fg = document.getElementById("t-fg").style.backgroundImage.slice(5, -2);
console.log(fg)
console.log("WAITING!! don't click again!")
var base_img = await b64toImageData(fg);
console.log(base_img.data);
}
});
<button id="t-load" type="button" data-board="g" data-tid="0" style="font-size: 11px; padding: 0px; width: 90px; box-sizing: border-box; margin: 0px 6px 0px 0px; vertical-align: middle; height: 18px;">Get Captcha</button>
<div id="t-fg" style="width: 100%; height: 100%; position: absolute; background-repeat: no-repeat; background-position: left top; background-image: url("data:image/png;base64,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");"></div>

How to change font color based on background image with javascript?

I want to change the font color based on the color of the image. The font color must be black or white, but it should change proportionally to the color of the image as it does in the code below.
So, I have this js function that if you move the mouse it changes the background color and consequently also the text (in the snippet move the pointer under the background). Obviously the part where you move the mouse to change color doesn't interest me, it's just a test. Is there a way to apply the function to my personal div?
In simple terms I want the color of the text to change based on my background and not if you move the mouse. Sorry for the poor explanation, I'm relatively new here, trying to learn how to exercise this function. Currently I don't know how to do it, I appreciate any answer, thanks.
function getTextColor(rgba){
rgba = rgba.match(/\d+/g);
if((rgba[0]*0.299)+(rgba[1]*0.587)+(rgba[2]*0.114)>186) {
return 'black';
} else {
return 'white';
}
}
var div = document.createElement('div');
div.style.height = '100vh';
document.body.appendChild(div);
div.addEventListener('mousemove', (event)=>{
var x = event.clientX;
var y = event.clientY;
div.textContent = `${x} , ${y}`;
div.style.backgroundColor = `rgba(${x},${y},100,100)`;
div.style.color = getTextColor(div.style.backgroundColor);
});
.background {
height: 100vh;
background: url("https://i.pinimg.com/originals/bc/a3/2d/bca32d5cdfabeaeb4faeb12bff160524.jpg");
}
<div class="background">Background example</div>
Explanation
Here is an example showing how to get the average using a canvas rendered to a 1x1-px scale. From there we set the header background and then apply a light or dark class based on the luminance of the aforementioned average.
Notes
Note 1:
There is some extra code to allow for easier visualization, this is commented and can be removed.
Note 2: The below code is not guaranteed to run on all browsers. Please see this thread for more specifics.
Note 3: This code only works with local images and CORS-enabled image URLs due to it's reliance on canvas.drawImage. Please see this for more information.
Example 1:
this example shows the functionality. It uses two image URLs in the JS to toggle between.
/*
THE TOGGLE ACTION
*/
/* The urls for toggling between */
const urlLight = 'https://images.unsplash.com/photo-1484503793037-5c9644d6a80a?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=930&q=80';
const urlDark = 'https://images.unsplash.com/photo-1517999144091-3d9dca6d1e43?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=627&q=80';
let currentUrl = urlLight;
const toggle = document.getElementById('toggle');
toggle.addEventListener("click", function() {
if (currentUrl === urlLight) {
currentUrl = urlDark;
} else {
currentUrl = urlLight;
}
getImageBrightness(currentUrl, function(brightness) {
const header = document.getElementById("header");
header.style.backgroundImage = `url(${currentUrl}`;
header.classList.remove("dark");
header.classList.remove("light");
console.log(brightness);
if (brightness > 225 / 2) {
header.classList.toggle("dark");
} else {
header.classList.toggle("light");
}
});
});
/*
Important get brightness code
*/
function getImageBrightness(imageSrc, callback) {
var img = document.createElement("img");
img.src = imageSrc;
img.style.display = "none";
img.crossOrigin = "anonymous";
document.body.appendChild(img);
var colorSum = 0;
img.onload = function() {
// create canvas
var canvas = document.createElement("canvas");
canvas.width = this.width;
canvas.height = this.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(this, 0, 0);
var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
var data = imageData.data;
var r, g, b, avg;
for (var x = 0, len = data.length; x < len; x += 4) {
r = data[x];
g = data[x + 1];
b = data[x + 2];
avg = Math.floor((r + g + b) / 3);
colorSum += avg;
}
var brightness = Math.floor(colorSum / (this.width * this.height));
callback(brightness);
}
}
getImageBrightness(currentUrl, function(brightness) {
const header = document.getElementById("header");
header.style.backgroundImage = `url(${currentUrl}`;
header.classList.remove("dark");
header.classList.remove("light");
if (brightness > 225 / 2) {
header.classList.toggle("dark");
} else {
header.classList.toggle("light");
}
});
.dark {
color: black;
}
.light {
color: white;
}
* {
text-align: center;
}
#header {
padding: 2rem 0;
font-size: 4rem;
background-size: cover;
margin-bottom: 1rem;
background-position: center center;
}
<div id="header">
Header
</div>
<button id='toggle'>
Toggle Background
</button>
Example 2:
This example directly answers the question by retrieving the background image of the current div and running the function using said image.
/*
Important get brightness code
*/
function getImageBrightness(imageSrc, callback) {
var img = document.createElement("img");
img.src = imageSrc;
img.style.display = "none";
img.crossOrigin = "anonymous";
document.body.appendChild(img);
var colorSum = 0;
img.onload = function() {
// create canvas
var canvas = document.createElement("canvas");
canvas.width = this.width;
canvas.height = this.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(this, 0, 0);
var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
var data = imageData.data;
var r, g, b, avg;
for (var x = 0, len = data.length; x < len; x += 4) {
r = data[x];
g = data[x + 1];
b = data[x + 2];
avg = Math.floor((r + g + b) / 3);
colorSum += avg;
}
var brightness = Math.floor(colorSum / (this.width * this.height));
callback(brightness);
}
}
/* The element we wish to work on */
const header = document.getElementById("header");
/* To get the background image. Get style and then background image with a slice to remove quotes */
var imageElement = document.getElementById('header'),
style = imageElement.currentStyle || window.getComputedStyle(imageElement, false),
backgroundImage = style.backgroundImage.slice(4, -1).replace(/"/g, "");
getImageBrightness(backgroundImage, function(brightness) {
/* Remove dark and light classes from the element */
header.classList.remove("dark");
header.classList.remove("light");
/* check brightness and apply correct style */
/* Please modify the below brightness comparison statement to adjust to your needs */
if (brightness > 225 / 2) {
header.classList.toggle("dark");
} else {
header.classList.toggle("light");
}
});
.dark {
color: black;
}
.light {
color: white;
}
* {
text-align: center;
}
#header {
padding: 2rem 0;
font-size: 4rem;
background-size: cover;
margin-bottom: 1rem;
background-position: center center;
background-image: url('https://images.unsplash.com/photo-1530128118208-89f6ce02b37b?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1740&q=80')
}
<div id="header">
<h1>
Header
</h1>
</div>

Binding a Range Slider to Image Sequence

I want to show a timelapse video but have it with a Range slider so the user can drag it back and forth. I've tried with a video but I don't like the loading effect as you scroll. I also exported the video as images and binded it to the range slider. First question is, isn't there any plugins or applications out there that do this? Maybe i'm searching the wrong terms. Second is an image sequence the best way to do this? In my code below I can get it to partially work, but I can't figure out how to resize the image, and it's way to big for the canvas.
<style>
canvas {
height: 650px;
width: 1000px;
border: 1px solid black;
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
<canvas id="canvas" height="650px" width="1000px"></canvas>
<br>
<input id="my-input" type="range" min="1" max="50" value="1">
<script type="text/javascript">
var canvas = document.getElementById("canvas");
canvas.height = window.innerHeight;
canvas.width = window.innerWidth;
var totalImages = 50;
var videoFrames = [];
for (var i = 1; i <= totalImages; i++) {
var videoFrame = new Image;
var videoFrameUrl = 'http://dacwebdesign.com/testing/images/timelapse-' + i + '.jpg';
videoFrame.src = videoFrameUrl;
videoFrames.push(videoFrame);
}
$("#my-input").on("input", function(event) {
var currentImage = videoFrames[event.target.value - 1];
var context = canvas.getContext("2d");
context.drawImage(currentImage, 0, 0);
});
</script>
You can resize the images to fit your canvas with:
var currentImage = videoFrames[event.target.value - 1];
var context = canvas.getContext("2d");
var dstWidth = canvas.width;
var dstHeight = canvas.height;
var srcWidth = currentImage.naturalWidth;
var srcHeight = currentImage.naturalHeight;
context.drawImage(currentImage, 0, 0, srcWidth, srcHeight, 0, 0, dstWidth, dstHeight);
That does not take into account aspect ratios, so if your canvas has a different aspect ratio to your images, it will appear distorted.

HTML attributes (width, height) of canvas change independently

I have some script on JS, it change width and height of canvas element:
function RefreshSizes (canvas) {
var temp_width = 320;
var temp_height = 240;
document.getElementById(canvas).setAttribute('width', temp_width);
document.getElementById(canvas).setAttribute('height', temp_height);
}
this functions calling right after canvas initializing.
It works fine on Chrome.
But in FireFox 49 I see that:
What could it be?
UPD#1 Tested code of BukkitmanPlays MCPE
UPD#2
Full CSS for canvas:
element {
width: 320px;
height: 240px;
}
.canvas {
border: 3px solid #E0E0E0;
z-index: 0;
position: relative;
}
html {
font: 10px/10px arial;
}
some code on one browser isn't the same on another browser, so in this case, what I would do:
function RefreshSizes (canv) {
var temp_width = 320;
var temp_height = 240;
var canvas = canv;
canvas.width = temp_width;
canvas.height = temp_height;
}
I'm sure this will work

Fabric Js - Is it possible to auto scale a image object to the canvas?

We currently upload an image via the below code:
reader.onload = function (event) {
fabric.Image.fromURL(event.target.result, function (img) {
whiteboardService.uploadImageToCanvas(img);
});
}
and...
service.uploadImageToCanvas = function (image) {
service.canvas.add(image);
image.id = service.getUniqueId();
service.objectMap[image.id] = image;
var data = {
image: image,
id: image.id
};
signalService.sendMessage(service.recipient, data);
};
If the image is too large, bigger than our fixed width and height of the canvas would it be possible for that image to be scaled down automatically to fit into the fixed width and height of the canvas?
I should point out that I am using Angular.js as well
ta
fabricjs put a very simple method to do this.
Those methods are scaleToWidth and scaleToHeight that are close to 'apply a scale factor that will fit the image on the specified dimensions'
So you can do
image.scaleToWidth(service.canvas.getWidth());
service.canvas.add(image);
it depends if you want to preserve aspect ratio if you have to scale for the biggest, the smallest or both.
Inspired by #AndreaBogazzi, I wrote below code to fit image to canvas totally.
var canvas = new fabric.Canvas('canvas');
fabric.Image.fromURL('https://d32ogoqmya1dw8.cloudfront.net/images/NAGTWorkshops/structure/SGT2012/activities/noaa_global_topographic_map.jpg', function(oImg) {
let imgWidth = oImg.width;
let imgHeight = oImg.height;
let canvasWidth = canvas.getWidth();
let canvasHeight = canvas.getHeight();
let imgRatio = imgWidth / imgHeight;
let canvasRatio = canvasWidth / canvasHeight;
if(imgRatio <= canvasRatio){
if(imgHeight> canvasHeight){
oImg.scaleToHeight(canvasHeight);
}
}else{
if(imgWidth> canvasWidth){
oImg.scaleToWidth(canvasWidth);
}
}
canvas.clear();
canvas.add(oImg);
canvas.centerObject(oImg);
});
.image-preview{
border: solid 1px #979797;
width: 200px;
height: 200px;
}
<script src="http://cdnjs.cloudflare.com/ajax/libs/fabric.js/4.3.1/fabric.min.js"></script>
<div class="image-preview">
<canvas id="canvas" width='200' height='200'></canvas>
<hr/>
<p>Origin Image</p>
<img src="https://d32ogoqmya1dw8.cloudfront.net/images/NAGTWorkshops/structure/SGT2012/activities/noaa_global_topographic_map.jpg" />
</div>

Categories