<!DOCTYPE html> <html> <head> <title>Photo Recoloring Tool by Zhou Bowei</title> <link type="text/css" rel="stylesheet" href="css/materialize.min.css" media="screen,projection" /> <link type="text/css" rel="stylesheet" href="css/style_user.css" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> </head> <body> <header> <!-- nav bar --> <nav> <div class="nav-wrapper"> <div class="container"> <a href="https://github.com/b-z/photo_recoloring"> <span class="brand-logo">PHOTO RECOLORING</span> </a> <ul id="nav-mobile" class="right hide-on-small-only"> <li><a href="https://github.com/b-z/photo_recoloring">ZHOU BOWEI</a></li> </ul> </div> </div> </nav> <!-- nav bar end --> <a href="https://github.com/b-z/photo_recoloring" class="hide-on-med-and-down"> <img style="position: absolute; top: 0; right: 0; border: 0;" src="img/github.png" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_orange_ff7600.png"> </a> </header> <main> <!-- container --> <div class="container"> <!-- search --> <div id="search" class="section"> <h5>UPLOAD FILE</h5> <div class="row"> <div class="col s12 m8 l8 offset-m2 offset-l2"> <form action="#"> <div class="file-field input-field"> <div class="btn"> <input id="file_path" type="file"> <span><i class="material-icons">perm_media</i></span> </div> <div class="file-path-wrapper"> <input class="file-path validate" type="text" placeholder="UPLOAD IMAGE FILE"> </div> </div> </form> </div> </div> <h5 class="source_image_area">THE IMAGE</h5> <div class="row source_image_area"> <div class="col s12 m8 l8 offset-m2 offset-l2"> <canvas class="materialboxed z-depth-1" id="source_image"></canvas> </div> </div> <div id="palette" class="row source_image_area"></div> <div id="palette_e" class="row"></div> <div id="modals" class="row"></div> <div id="confirm_change" class="row"> <div class="col s6 m3 center-align offset-m3"> <a class="btn waves-effect waves-light" onclick="Palette.putImage(Palette.img);">RESTORE</a> </div> <div class="col s6 m3 center-align"> <a class="btn waves-effect waves-light" onclick="Palette.colorTransform(color_list1, color_list2);Palette.putImage(Palette.img_copy);">CONFIRM CHANGE</a> </div> </div> </div> </div> <!-- container end --> </main> <!-- footer --> <footer class="footer-copyright"> <div class="container"> Copyright © 2015 Zhou Bowei. All rights reserved. </div> </footer> <!-- footer end --> <script type="text/javascript" src="js/jquery-2.1.3.min.js"></script> <script type="text/javascript" src="js/materialize.min.js"></script> <script type="text/javascript" src="js/math.min.js"></script> <script type="text/javascript" src="js/color.js"></script> <script type="text/javascript" src="js/palette.js"></script> <script> var canv, file, ctx; var img_raw, width, height; $(document).ready(function() { $('.materialboxed').materialbox(); $('.modal-trigger').leanModal(); }); function uploadFile(e) { //Materialize.toast('PROCESSING...', 200); var file = e.target.files[0]; var filename = file.name; var reader = new FileReader(); reader.onload = putImage2Canvas; reader.readAsDataURL(file); } function putImage2Canvas(event) { var img = new Image(); img.src = event.target.result; img.onload = function() { window.color_list_rgb = []; window.color_list1 = []; window.color_list2 = []; window.change_list = [false, false, false, false, false]; window.Ls = []; window.Ls_user = []; var canv = $('#source_image')[0]; width = canv.width = img.width; height = canv.height = img.height; ctx = canv.getContext('2d'); ctx.drawImage(img, 0, 0); img_raw = ctx.getImageData(0, 0, img.width, img.height); Palette.init(img_raw, ctx); Palette.palette(img_raw.data); var colors = Palette.kmeans(); addPalette(colors); $('#palette_e').hide(); $('#confirm_change').hide(); $('.source_image_area').fadeIn(1000); } } function addPalette(colors) { var tmp = '', tmp_e = '', modals = ''; color_list_rgb = colors; color_list1 = []; color_list2 = []; for (var i = 0; i < colors.length; i++) { var Lab = Color.rgb2lab(colors[i]); color_list1.push(Lab); color_list2.push(Color.rgb2lab(colors[i])); window.Ls.push(Lab[0]); window.Ls_user.push(Lab[0]); } color_list2[0] = false; for (var i = 1; i < colors.length; i++) { tmp += '\ <div class="col s1_5' + (i == 1 ? ' offset-s2 offset-m2 offset-l2' : ' ') + ' center-align">\ <a class="plt' + i + ' z-depth-1 btn-thin btn waves-effect waves-light hide-on-med-and-up"></a>\ <a class="plt' + i + ' z-depth-1 btn-floating btn waves-effect waves-light hide-on-small-only hide-on-large-only"></a>\ <a class="plt' + i + ' z-depth-1 btn-floating btn-large waves-effect waves-light hide-on-med-and-down"></a>\ </div>'; tmp_e += '\ <div class="col s1_5' + (i == 1 ? ' offset-s2 offset-m2 offset-l2' : ' ') + ' center-align">\ <a class="plt' + i + '_e z-depth-1 btn-thin btn waves-effect waves-light hide-on-med-and-up"></a>\ <a class="plt' + i + '_e z-depth-1 btn-floating btn waves-effect waves-light hide-on-small-only hide-on-large-only"></a>\ <a class="plt' + i + '_e z-depth-1 btn-floating btn-large waves-effect waves-light hide-on-med-and-down"></a>\ <div class="plt' + i + '_p" style="width:1px;height:1px;"></div>\ </div>'; modals += '\ <div id="modal' + i + '" class="modal modal-fixed-footer">\ <div class="modal-content">\ <h4>CHANGE COLOR</h4>\ <div class="row">\ <div class="input-field col s6">\ <input id="modal' + i + '_ori_txt" type="text" class="validate">\ <label class="active" for="modal' + i + '_ori_txt">Origin</label>\ </div>\ <div class="col s3 modal-color z-depth-1 btn-thin btn waves-effect waves-light" id="modal' + i + '_ori">\ </div>\ </div>\ <div class="row">\ <div class="input-field col s6">\ <input id="modal' + i + '_dst_txt" type="text" class="validate">\ <label class="active" for="modal' + i + '_dst_txt">Destination</label>\ </div>\ <div class="col s3 modal-color z-depth-1 btn-thin btn waves-effect waves-light" id="modal' + i + '_dst" style="display:none;">\ </div>\ </div>\ <div class="row">\ <form action="#" class="col s6">\ <p class="range-field">\ <input type="range" id="range' + i + '_r" min="0" max="255" onmousemove="changeColor(' + i + ');" ontouchmove="changeColor(' + i + ');"/>\ </p>\ <p class="range-field">\ <input type="range" id="range' + i + '_g" min="0" max="255" onmousemove="changeColor(' + i + ');" ontouchmove="changeColor(' + i + ');"/>\ </p>\ <p class="range-field">\ <input type="range" id="range' + i + '_b" min="0" max="255" onmousemove="changeColor(' + i + ');" ontouchmove="changeColor(' + i + ');"/>\ </p>\ </form>\ </div>\ </div>\ <div class="modal-footer">\ <a class="modal-action modal-close waves-effect waves-green btn-flat" onclick="confirmChange(' + i + ');">CONFIRM</a>\ <a class="modal-action modal-close waves-effect waves-green btn-flat">CANCEL</a>\ </div>\ </div>' } $('#palette').html(tmp); $('#palette_e').html(tmp_e); $('#modals').html(modals); for (var i = 1; i < colors.length; i++) { var c = colors[i]; var color = 'rgb(' + c[0] + ',' + c[1] + ',' + c[2] + ')'; setTimeout((function(j, cl, rgb) { return function() { $('.plt' + j).attr('style', 'background-color:' + cl + '!important'); $('.plt' + j + ',.plt' + j + '_e').click((function(k, co, RGB) { return function() { $('#modal' + j + '_ori,#modal' + j + '_dst').attr('style', 'background-color:' + co + '!important'); $('#modal' + j + '_ori_txt').val(co); $('#range' + j + '_r').val(RGB[0]); $('#range' + j + '_g').val(RGB[1]); $('#range' + j + '_b').val(RGB[2]); $('#modal' + j).openModal(); changeColor(j); } })(j, cl, rgb)); }; })(i, color, c), 600 * (0.5 + i)); } setTimeout(function() { $('#palette').append('<div id="helper" class="col s12 center-align" style="display:none;"><h5>CLICK THE PALETTE TO RECOLOR.</h5></div>'); $('#helper').fadeIn(1000); }, 2200); } function changeColor(id) { var r = $('#range' + id + '_r').val(); var g = $('#range' + id + '_g').val(); var b = $('#range' + id + '_b').val(); var color = 'rgb(' + r + ',' + g + ',' + b + ')'; $('#modal' + id + '_dst').attr('style', 'background-color:' + color + '!important'); $('#modal' + id + '_dst_txt').val(color); $('#modal' + id + '_dst').show(); } function confirmChange(id) { var R = $('#range' + id + '_r').val(); var G = $('#range' + id + '_g').val(); var B = $('#range' + id + '_b').val(); var color = 'rgb(' + R + ',' + G + ',' + B + ')'; var show = true; var Lab = Color.rgb2lab([R, G, B]); Ls_user[id] = Lab[0]; for (var i = 1; i < Ls.length; i++) { Ls[i] = Ls_user[i]; color_list2[i][0] = Ls[i]; } color_list2[id] = Lab; for (var i = 1; i < Ls.length; i++) { if (i < id) { if (Ls[i] > Ls[i + 1]) { Ls[i] = Ls[i + 1]; color_list2[i][0] = Ls[i + 1]; } } if (i > id) { if (Ls[i] < Ls[i - 1]) { Ls[i] = Ls[i - 1]; color_list2[i][0] = Ls[i - 1]; } } } change_list[id - 1] = color; if (show) { $('#palette_e').show(); $('#helper').hide(); $('#confirm_change').show(); for (var i = 0; i < change_list.length; i++) { // var t = color_list_rgb[i + 1]; // var color1_txt = 'rgb(' + t[0] + ',' + t[1] + ',' + t[2] + ')'; // var color2_txt = (change_list[i] == false ? color1_txt : change_list[i]) var idx = i + 1; var RGB = Color.lab2rgb(color_list2[idx]); var color2_txt = 'rgb(' + RGB[0] + ',' + RGB[1] + ',' + RGB[2] + ')'; $('.plt' + idx + '_e').show(); $('.plt' + idx + '_p').hide(); $('.plt' + idx + '_e').attr('style', 'background-color:' + color2_txt + '!important'); } } else { $('#palette_e').hide(); $('#helper').show(); $('#confirm_change').hide(); } } $('#file_path')[0].onchange = uploadFile; </script> </body> </html>