Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HTML5 Canvas brightness control

I wanted to implement a slider control that changes the brightness of the image, much like the one shown at this link but through Html5 canvas :

http://camanjs.com/examples/

I want to control brightness of image by using input slider on html and define on javascript.

any idea how is possible to change the Brightness of this image with javascript.

// Dispatch a change event to file input element.
$(document).ready(function() {
    $('#imgfile').change(function(e) {
        var file = e.target.files[0],
            imageType = /image.*/;

        if (!file.type.match(imageType))
            return;
// Get the uploaded file from the event handler and get a data URL by using the FileReader object.
        var reader = new FileReader();
        reader.onload = fileOnload;
        reader.readAsDataURL(file);
    });

// Use some jQuery to trigger click on canvas to input
    $('#canvas').on('click', function() {
        $('#imgfile').trigger('click');
        //show the slider after click to choose the image
        $('#slider').show();
    });


// Make an img element with the data URL and draw it on the canvas.
    function fileOnload(e) {
      //Like this in javascript make an image
     // img = new Image();
     //img.onload = imageLoaded;
        var $img = $('<img>', { src: e.target.result });
        $img.load(function() {
            var canvas = $('#canvas')[0];
            var context = canvas.getContext('2d');
            context.drawImage(this, 0, 0, canvas.width, canvas.height );
        });
    }



    var slider = $('#slider').change(function(){
        console.log(this.value);
    })
});
body {
  text-align: center;
  width: 100%;

}

canvas {
  border: 1px solid black;
  margin: 50px auto;
}

.container {
  margin: 0 auto;
}

@media(max-width:1200px) {
  .container {
  margin: 0 50px;
  }
  #canvas {
  width: 100%;
  height: auto;
 }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <link rel="stylesheet" href="css/style.css">
  <script src="https://cdn.rawgit.com/konvajs/konva/1.7.6/konva.min.js"></script>
  <script src="js/jquery.js" charset="utf-8"></script>
  <script src="js/main.js" charset="utf-8"></script>
  <title>Brightness-Adjustment</title>
</head>
<body>
<div class="container">
  <canvas id="canvas" width="600" height="384">
    <!-- <img src="https://www.smashingmagazine.com/wp-content/uploads/2015/06/10-dithering-opt.jpg" width="150" height="150" alt=""/> -->
  </canvas>

    <form action='#' onsubmit="return false;">
      <input type='file' id='imgfile' style="display: none;"/>
      <input id="slider" type="range" min="-1" max="1" step="0.05" value="0" style="display: none;">
    </form>

</div>


</body>
</html>
like image 458
Mina Avatar asked Nov 05 '17 04:11

Mina


1 Answers

Realtime brightness control.

That demo is very very old, slow, and completely outdated. These days there are a variety of ways to achieve image filters that are realtime and not restricted to same domain and CORS safe images.

For everything you need to know about the canvas got to MDN CanvasRenderingContext2D

ctx.filter property

The simple solution is to use the canvas filter property and just set the brightness to the value you want. The draw the image.

ctx.filter = "brightness(150%)";
ctx.drawImage(image,0,0);

As shown in the example below.

(Note that the SVG brightness is not the same as a brightness filter, but that is their interpretation of what brightness means)

const imageUrl = "http://camanjs.com/images/example1_600.jpg";
const ctx = canvas.getContext("2d");

ctx.fillText("Please wait loading image..",20,20);
const image = new Image;
image.src = imageUrl;
image.onload = () => {
  canvas.width = image.width;
  canvas.height = image.height;     
  ctx.drawImage(image, 0, 0);
  slider.addEventListener("mousemove", () => {
    if (slider.value !== slideOldVal) {
      setBrightness(Number(slider.value));
    }
    val.textContent = slider.value;
    slideOldVal = Number(slider.value);
  });
}

function setBrightness(value) {
  ctx.filter = `brightness(${value + 100}%)`;
  ctx.drawImage(image, 0, 0);
}

var slideOldVal;
canvas {
  border: 2px solid black;
}
Brightness<input id="slider" type="range" min="-100" max="400" value="0" step="1"></input><span id="val"></span><br>
<canvas id="canvas"></canvas>

ctx.globalCompositeOperation property

A little more complicated but has more support (well its IE11 that is stuck in 2014 so as long as we cater to lazy clients we all are stuck in 2014)

For brightening use the composite operation "lighten" and draw a light fill over the image to set the brightness. The effect can reduce the contrast so I like to bump up the image contrast by drawing the image on top once with the lighten filter.

 ctx.drawImage(image,0,0);
 ctx.globalCompositeOperation = "lighten";
 ctx.drawImage(image,0,0);  // draw image to bump up the contrast
 ctx.globalAlpha = amount; // 0-1
 ctx.fillStyle = "white";
 ctx.fillRect(0,0,ctx.canvas.width,ctx.canvas.height);

For reducing the brightness use the comp mode "multiply" and just draw a black over the image using the alpha to control the amount.

Example shows how.

const imageUrl = "http://camanjs.com/images/example1_600.jpg";
const ctx = canvas.getContext("2d");
ctx.fillText("Please wait loading image..",20,20);
const image = new Image;
image.src = imageUrl;
image.onload = () => {
  canvas.width = image.width;
  canvas.height = image.height;
  ctx.drawImage(image, 0, 0);
  slider.addEventListener("mousemove", () => {
    if (slider.value !== slideOldVal) {
      setBrightness(Number(slider.value));
    }
    val.textContent = slider.value;
    slideOldVal = Number(slider.value);
  });
}
ctx.drawImage(image, 0, 0);
ctx.globalCompositeOperation = "lighten";
ctx.fillStyle = "white";
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);

function setBrightness(value) {
  ctx.drawImage(image, 0, 0);
  ctx.save();
  if (value < 0) {
    ctx.globalCompositeOperation = "multiply";
    ctx.fillStyle = "black";
    ctx.globalAlpha = -value / 100;
    ctx.fillRect(0, 0, canvas.width, canvas.height);

  } else if (value > 0) {
    ctx.fillStyle = "white";
    ctx.globalCompositeOperation = "lighten";
    ctx.globalAlpha = 1;
    ctx.drawImage(image, 0, 0);
    ctx.globalAlpha = value / 100;
    ctx.fillRect(0, 0, canvas.width, canvas.height);

  }
  ctx.restore();
}

var slideOldVal;
canvas {
  border: 2px solid black;
}
Brightness<input id="slider" type="range" min="-100" max="100" value="0" step="1"></input><span id="val"></span><br>
<canvas id="canvas"></canvas>

Note The image used in the examples is from the OP's link for comparison only

like image 161
Blindman67 Avatar answered Oct 23 '22 10:10

Blindman67