How to insert a watermark in PNG

4

Following this example, I would like to be able to use a png in place of the banners on the canvas:

link

I'm using this code as a study, because it's all commented out, so my question applies to exactly this code:

/*  @preserve
 *  Project: Celebrate Pride Canvas
 *  Description: Puts a rainbow filter over your image like Facebook 'Celebrate Pride'.
 *  Author: Zzbaivong (devs.forumvi.com)
 *  Version: 1.2
 *  License: MIT
 */
(function ($) {

    'use strict';

    /**
     * Get image data
     * @param {Array} files
     */
    function readerImage(files) {
        if (files.length && files[0].type.indexOf('image/') === 0) {
            var reader = new FileReader();
            reader.readAsDataURL(files[0]);
            reader.onload = function (_file) {
                generator(_file.target.result, false);
            };
        }
    }

    // Upload success or error
    function endUpload() {
        setTimeout(function () {
            $get.text('Get link');
        }, 300);
        $progress.removeAttr('style');
        $download.removeClass('progress');
    }

    // Upload image to Imgur
    function upToImgur() {
        uploadImage = $.ajax({
            url: 'https://api.imgur.com/3/image',
            xhr: function () {
                var xhr = new window.XMLHttpRequest();
                xhr.upload.addEventListener('progress', function (evt) {
                    if (evt.lengthComputable) {
                        var percentComplete = Math.round(evt.loaded / evt.total * 100) + '%';
                        $progress.width(percentComplete);
                        $get.text(percentComplete);
                    }
                }, false);
                return xhr;
            },
            method: 'POST',
            headers: {
                Authorization: 'Client-ID 9ac8502e00ab613'
            },
            data: {
                image: dataUrl.replace(/.*,/, ''),
                type: 'base64'
            },
            success: function (result) {
                $result.val(result.data.link).fadeIn().focus();
                $get.fadeOut();
                dataUrl = null;
                endUpload();
            },
            error: function (json) {
                endUpload();
                console.log(json);
            }
        });
    }

    /**
     * Rainbow image gen
     * @param {String} url Image url
     */
    function generator(url, cross) {
        $wrap_img.addClass('generator');
        rainbowLGBT(url, cross, 320, function (img) {
            dataUrl = img;
            $wrap_img.html('<a href="' + img + '" download="CelebratePride.jpg"><img src="' + img + '" alt="Celebrate Pride"></a>');
            $input.prop('disable', false).val('');
            $add.slideUp('fast');
            $complete.slideDown('fast');
            $submit.removeAttr('style');
        });
    }

    /**
     * Puts a filter over image
     * @param  {String}   url      Image url
     * @param  {Boolean}   cross    CrossOrigin
     * @param  {Number}   cw       Image width
     * @param  {Function} callback Export to base64 image
     */
    function rainbowLGBT(url, cross, cw, callback) {
        var img = new Image();
        if (cross) {
            img.crossOrigin = 'Anonymous';
        }
        img.onload = function () {
            var canvas = document.createElement('CANVAS');
            var ctx = canvas.getContext('2d');

            var w = this.width, // image height
                h = this.height, // image width
                rh = h / w * cw, // ratio height
                ch = rh, // canvas height
                sixthly,
                mh = cw * 1.2; // canvas max height
            if (rh > mh) {
                ch = mh;
            }
            $wrap_img.height(ch);
            sixthly = ch / 6; // 1/6 canvas height

            canvas.width = cw;
            canvas.height = ch;

            ctx.drawImage(this, 0, 0, cw, rh);

            ctx.globalAlpha = 0.5;
            ctx.fillStyle = '#ff3e18';
            ctx.fillRect(0, 0, cw, sixthly);
            ctx.fillStyle = '#fc9a00';
            ctx.fillRect(0, sixthly, cw, sixthly);
            ctx.fillStyle = '#ffd800';
            ctx.fillRect(0, (sixthly * 2), cw, sixthly);
            ctx.fillStyle = '#39ea7c';
            ctx.fillRect(0, (sixthly * 3), cw, sixthly);
            ctx.fillStyle = '#0bb2ff';
            ctx.fillRect(0, (sixthly * 4), cw, sixthly);
            ctx.fillStyle = '#985aff';
            ctx.fillRect(0, (sixthly * 5), cw, sixthly);

            var dataURL = canvas.toDataURL('image/jpeg');
            if (typeof callback === 'function') {
                callback(dataURL);
            }
            canvas = null;
        };
        img.onerror = function () {
            $submit.css('backgroundImage', 'url(img/cancel.png)');
            $wrap_img.removeClass('generator');
        };
        img.src = url;
    }

    var uploadImage,
        dataUrl = null,
        $wrap_img = $('#celebrate-img'),
        $add = $('#celebrate-add'),
        $input = $('#celebrate-input'),
        $submit = $('#celebrate-submit'),
        $complete = $('#celebrate-complete'),
        $reset = $('#celebrate-reset'),
        $download = $('#celebrate-download'),
        $progress = $('#celebrate-progress'),
        $get = $('#celebrate-get'),
        $result = $('#celebrate-result');

    $add.on('submit', function (event) {
        event.preventDefault();
        $input.prop('disable', true);
        $submit.css('backgroundImage', 'url(img/load.gif)');
        generator($input.val(), true);
    });

    $input.on('input', function () {
        var val = $input.val();
        if ($.trim(val) === '') {
            $submit.css('backgroundImage', 'url(img/enter.png)');
        } else if (val.indexOf('http') === 0) {
            $submit.css('backgroundImage', 'url(img/ok.png)');
        } else {
            $submit.css('backgroundImage', 'url(img/cancel.png)');
        }
    });

    //$wrap_img.on('dragenter', function () {
    //    event.preventDefault();
    //    $wrap_img.addClass('dragging');
    //});

    $wrap_img.on('dragover', function (event) {
        event.preventDefault();
        $wrap_img.addClass('dragging');
    });

    $wrap_img.on('dragleave', function (event) {
        event.preventDefault();
        $wrap_img.removeClass('dragging');
    });

    $wrap_img.on('click', function () {
        if (!$wrap_img.hasClass('generator')) {
            $('#celebrate-file').click();
        }
    });

    $wrap_img.on('drop dragdrop', function (event) {
        event.preventDefault();
        $wrap_img.removeClass('dragging');
        readerImage(event.originalEvent.dataTransfer.files);
    });

    $download.on('click', function () {
        if (!$download.hasClass('progress') && dataUrl !== null) {
            $download.addClass('progress');
            upToImgur();
        }
    });

    $result.on('focus click mouseenter', function () {
        $result[0].select();
    });

    $('html').on('change', '#celebrate-file', function () {
        readerImage(this.files);
        $('#celebrate-file').replaceWith('<input id="celebrate-file" type="file" accept="image/*">');
    });

    $reset.on('click', function () {
        $wrap_img.removeAttr('style').html('<div><strong>Drop image</strong><br><span>(or click)</span></div>').removeClass('generator');
        $add.slideDown('fast');
        $complete.slideUp('fast');
        $submit.removeAttr('style');
        $progress.removeAttr('style');
        $get.text('Get link').show();
        $result.hide();
        $download.removeClass('progress');
        if (uploadImage) {
            uploadImage.abort();
        }
    });

}(jQuery));
body {
    background: #f8f8f8;
}

h1 {
    text-align: center;
    font-family: sans-serif;
    font-weight: 300;
    color: rgb(255, 0, 174);
}

#celebrate-img {
    border: 14px dashed #fff;
    width: 292px;
    height: 292px;
    margin: 0 auto;
    overflow: hidden;
    background: url(https://raw.githubusercontent.com/baivong/Celebrate-Pride-Canvas/master/img/drop.png) center center no-repeat #fff;
    position: relative;
    transition: .2s;
    -webkit-transition: .2s;
}

#celebrate-img.dragging,
#celebrate-img:hover {
    border-color: #2196f3;
    cursor: pointer;
}

#celebrate-img.generator {
    border-color: #fff;
    border: 0 none;
    width: 320px;
    height: 320px;
    background: url(data:image/gif;base64,R0lGODlhCgAKAIAAAAAAAP///yH5BAEAAAAALAAAAAAKAAoAAAIRhB2ZhxoM3GMSykqd1VltzxQAOw==) repeat scroll #ddd;
}

#celebrate-img.generator:after {
    content: url(https://raw.githubusercontent.com/baivong/Celebrate-Pride-Canvas/master/img/download.png);
    position: absolute;
    right: 5px;
    bottom: 5px;
    -webkit-animation: down 1.2s cubic-bezier(0, 0.79, 0.39, 0.35) infinite;
    animation: down 1.2s cubic-bezier(0, 0.79, 0.39, 0.35) infinite;
}

#celebrate-img > div {
    position: absolute;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
    height: 35px;
    margin: auto;
    text-align: center;
    color: #464646;
}

#celebrate-img.dragging > div,
#celebrate-img:hover > div {
    color: #2196f3;
}

#celebrate-file {
    display: none;
}

.wrap-btn {
    width: 318px;
    display: block;
    height: 40px;
    margin: 10px auto;
    border: 1px solid #ccc;
    position: relative;
    background: #fff;
}

.large-btn {
    width: 250px;
    position: absolute;
    left: 0;
    top: 0;
    height: 36px;
    border: 0 none;
    background: transparent;
    padding: 2px 7px;
}

.small-btn {
    position: absolute;
    right: 0;
    top: 0;
    width: 50px;
    height: 40px;
    border: 0;
    background: url(https://raw.githubusercontent.com/baivong/Celebrate-Pride-Canvas/master/img/enter.png) no-repeat center center transparent;
    text-indent: -99999px;
    cursor: pointer;
}

#celebrate-complete {
    border: 0 none;
    display: none;
    width: 320px;
}

#celebrate-reset {
    left: 0;
    right: auto;
    background-image: url(https://raw.githubusercontent.com/baivong/Celebrate-Pride-Canvas/master/img/reset.png);
    background-color: #3a3a3a;
}

#celebrate-download {
    display: block;
    padding: 0px;
    left: auto;
    right: 0px;
    width: 260px;
    height: 40px;
    background: #3a3a3a;
    cursor: pointer;
}

#celebrate-get {
    position: absolute;
    left: 0;
    top: 0;
    width: 260px;
    text-align: center;
    line-height: 40px;
    color: #FFF;
    font-family: monospace;
    font-size: 16px;
    font-weight: bold;
}

#celebrate-progress {
    display: block;
    height: 100%;
    background: #2196F3 none repeat scroll 0% 0%;
    width: 0;
}

#celebrate-result {
    width: 246px;
    background: #fff;
    color: #2196F3;
    display: none;
}

@-webkit-keyframes down {
    from {
        transform: scale(.3);
    }
    to {
        transform: scale(1);
    }
}

@keyframes down {
    from {
        transform: scale(.1);
    }
    to {
        transform: scale(1);
    }
}
<!doctype html>
<html>

<head>
    <meta charset="UTF-8">
    <title>Celebrate Canvas</title>
    <link rel="shortcut icon" type="image/x-icon" href="http://baivong.github.io/cdn/devsforumvi/favicon.ico">
    <link rel="stylesheet" href="style.css">
</head>

<body>

    <div id="celebrate">
        <h1>Let's Celebrate Pride</h1>
        <div id="celebrate-img">
            <div>
                <strong>Drop image</strong>
                <br>
                <span>(or click)</span>
            </div>
        </div>
        <form id="celebrate-add" class="wrap-btn">
            <input type="url" id="celebrate-input" placeholder="ENTER image url" required class="large-btn">
            <button id="celebrate-submit" type="submit" class="small-btn">OK</button>
        </form>
        <input id="celebrate-file" type="file" accept="image/*">
        <div id="celebrate-complete" class="wrap-btn">
            <div id="celebrate-reset" class="small-btn"></div>
            <div id="celebrate-download" class="large-btn">
                <span id="celebrate-progress"></span>
                <span id="celebrate-get">Get link</span>
                <input type="url" id="celebrate-result" class="large-btn">
            </div>
        </div>
    </div>

    <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
    <script src="script.js"></script>
</body>

</html>
    
asked by anonymous 23.09.2015 / 00:25

1 answer

4

Just load and print another image over the first one.

Simplified example:

//após desenhar a primeira...
var marcaDagua = new Image();
marcaDagua.onload = function() {
    ctx.drawImage(marcaDagua, 0, 0, largura, altura);
}
marcaDagua.src = '/marca-dagua.png';

Watch out for images uploaded from different domains. However, you can use the following attribute to work around this:

marcaDagua.crossOrigin = 'Anonymous';

In the example below, I modified the code posted in the question to add a watermark to the original image that is sent:

/*  @preserve
 *  Project: Celebrate Mustache Canvas
 *  Description: Puts a mustache filter over your image like Facebook 'Celebrate Mustache'.
 *  Author: Zzbaivong (devs.forumvi.com)
 *  Version: 1.2
 *  License: MIT
 */
(function ($) {

    'use strict';

    /**
     * Get image data
     * @param {Array} files
     */
    function readerImage(files) {
        if (files.length && files[0].type.indexOf('image/') === 0) {
            var reader = new FileReader();
            reader.readAsDataURL(files[0]);
            reader.onload = function (_file) {
                generator(_file.target.result, false);
            };
        }
    }

    // Upload success or error
    function endUpload() {
        setTimeout(function () {
            $get.text('Get link');
        }, 300);
        $progress.removeAttr('style');
        $download.removeClass('progress');
    }

    // Upload image to Imgur
    function upToImgur() {
        uploadImage = $.ajax({
            url: 'https://api.imgur.com/3/image',
            xhr: function () {
                var xhr = new window.XMLHttpRequest();
                xhr.upload.addEventListener('progress', function (evt) {
                    if (evt.lengthComputable) {
                        var percentComplete = Math.round(evt.loaded / evt.total * 100) + '%';
                        $progress.width(percentComplete);
                        $get.text(percentComplete);
                    }
                }, false);
                return xhr;
            },
            method: 'POST',
            headers: {
                Authorization: 'Client-ID 9ac8502e00ab613'
            },
            data: {
                image: dataUrl.replace(/.*,/, ''),
                type: 'base64'
            },
            success: function (result) {
                $result.val(result.data.link).fadeIn().focus();
                $get.fadeOut();
                dataUrl = null;
                endUpload();
            },
            error: function (json) {
                endUpload();
                console.log(json);
            }
        });
    }

    /**
     * Mustache image gen
     * @param {String} url Image url
     */
    function generator(url, cross) {
        $wrap_img.addClass('generator');
        mustache(url, cross, 320, function (img) {
            dataUrl = img;
            $wrap_img.html('<a href="' + img + '" download="CelebrateMustache.png"><img src="' + img + '" alt="Celebrate Mustache"></a>');
            $input.prop('disable', false).val('');
            $add.slideUp('fast');
            $complete.slideDown('fast');
            $submit.removeAttr('style');
        });
    }

    /**
     * Puts a filter over image
     * @param  {String}   url      Image url
     * @param  {Boolean}   cross    CrossOrigin
     * @param  {Number}   cw       Image width
     * @param  {Function} callback Export to base64 image
     */
    function mustache(url, cross, cw, callback) {
        var img = new Image();
        if (cross) {
            img.crossOrigin = 'Anonymous';
        }
        img.onload = function () {
            var that = this; 
            var $mustache = new Image();
            $mustache.crossOrigin = 'Anonymous';
            $mustache.onload = function() {

              var canvas = document.createElement('CANVAS');
              var ctx = canvas.getContext('2d');

              var w = that.width, // image height
                  h = that.height, // image width
                  rh = h / w * cw, // ratio height
                  ch = rh, // canvas height
                  mh = cw * 1.2; // canvas max height
              if (rh > mh) {
                  ch = mh;
              }
              $wrap_img.height(ch);

              canvas.width = cw;
              canvas.height = ch;

              ctx.drawImage(that, 0, 0, cw, rh);
              ctx.drawImage(this, 0, 0, cw, rh);
 
              var dataURL = canvas.toDataURL();
              if (typeof callback === 'function') {
                  callback(dataURL);
              }
            };
            $mustache.src = 'https://i.imgur.com/FIksZ8Y.png';

        };
        img.onerror = function () {
            $submit.css('backgroundImage', 'url(img/cancel.png)');
            $wrap_img.removeClass('generator');
        };
        img.src = url;
    }

    var uploadImage,
        dataUrl = null,
        $wrap_img = $('#celebrate-img'),
        $add = $('#celebrate-add'),
        $input = $('#celebrate-input'),
        $submit = $('#celebrate-submit'),
        $complete = $('#celebrate-complete'),
        $reset = $('#celebrate-reset'),
        $download = $('#celebrate-download'),
        $progress = $('#celebrate-progress'),
        $get = $('#celebrate-get'),
        $result = $('#celebrate-result');

    $add.on('submit', function (event) {
        event.preventDefault();
        $input.prop('disable', true);
        $submit.css('backgroundImage', 'url(img/load.gif)');
        generator($input.val(), true);
    });

    $input.on('input', function () {
        var val = $input.val();
        if ($.trim(val) === '') {
            $submit.css('backgroundImage', 'url(img/enter.png)');
        } else if (val.indexOf('http') === 0) {
            $submit.css('backgroundImage', 'url(img/ok.png)');
        } else {
            $submit.css('backgroundImage', 'url(img/cancel.png)');
        }
    });

    //$wrap_img.on('dragenter', function () {
    //    event.preventDefault();
    //    $wrap_img.addClass('dragging');
    //});

    $wrap_img.on('dragover', function (event) {
        event.preventDefault();
        $wrap_img.addClass('dragging');
    });

    $wrap_img.on('dragleave', function (event) {
        event.preventDefault();
        $wrap_img.removeClass('dragging');
    });

    $wrap_img.on('click', function () {
        if (!$wrap_img.hasClass('generator')) {
            $('#celebrate-file').click();
        }
    });

    $wrap_img.on('drop dragdrop', function (event) {
        event.preventDefault();
        $wrap_img.removeClass('dragging');
        readerImage(event.originalEvent.dataTransfer.files);
    });

    $download.on('click', function () {
        if (!$download.hasClass('progress') && dataUrl !== null) {
            $download.addClass('progress');
            upToImgur();
        }
    });

    $result.on('focus click mouseenter', function () {
        $result[0].select();
    });

    $('html').on('change', '#celebrate-file', function () {
        readerImage(this.files);
        $('#celebrate-file').replaceWith('<input id="celebrate-file" type="file" accept="image/*">');
    });

    $reset.on('click', function () {
        $wrap_img.removeAttr('style').html('<div><strong>Drop image</strong><br><span>(or click)</span></div>').removeClass('generator');
        $add.slideDown('fast');
        $complete.slideUp('fast');
        $submit.removeAttr('style');
        $progress.removeAttr('style');
        $get.text('Get link').show();
        $result.hide();
        $download.removeClass('progress');
        if (uploadImage) {
            uploadImage.abort();
        }
    });

}(jQuery));
body {
    background: #f8f8f8;
}

h1 {
    text-align: center;
    font-family: sans-serif;
    font-weight: 300;
    color: rgb(0, 0, 174);
}

#celebrate-img {
    border: 14px dashed #fff;
    width: 292px;
    height: 292px;
    margin: 0 auto;
    overflow: hidden;
    background: url(https://raw.githubusercontent.com/baivong/Celebrate-Pride-Canvas/master/img/drop.png) center center no-repeat #fff;
    position: relative;
    transition: .2s;
    -webkit-transition: .2s;
}

#celebrate-img.dragging,
#celebrate-img:hover {
    border-color: #2196f3;
    cursor: pointer;
}

#celebrate-img.generator {
    border-color: #fff;
    border: 0 none;
    width: 320px;
    height: 320px;
    background: url(data:image/gif;base64,R0lGODlhCgAKAIAAAAAAAP///yH5BAEAAAAALAAAAAAKAAoAAAIRhB2ZhxoM3GMSykqd1VltzxQAOw==) repeat scroll #ddd;
}

#celebrate-img.generator:after {
    content: url(https://raw.githubusercontent.com/baivong/Celebrate-Pride-Canvas/master/img/download.png);
    position: absolute;
    right: 5px;
    bottom: 5px;
    -webkit-animation: down 1.2s cubic-bezier(0, 0.79, 0.39, 0.35) infinite;
    animation: down 1.2s cubic-bezier(0, 0.79, 0.39, 0.35) infinite;
}

#celebrate-img > div {
    position: absolute;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
    height: 35px;
    margin: auto;
    text-align: center;
    color: #464646;
}

#celebrate-img.dragging > div,
#celebrate-img:hover > div {
    color: #2196f3;
}

#celebrate-file {
    display: none;
}

.wrap-btn {
    width: 318px;
    display: block;
    height: 40px;
    margin: 10px auto;
    border: 1px solid #ccc;
    position: relative;
    background: #fff;
}

.large-btn {
    width: 250px;
    position: absolute;
    left: 0;
    top: 0;
    height: 36px;
    border: 0 none;
    background: transparent;
    padding: 2px 7px;
}

.small-btn {
    position: absolute;
    right: 0;
    top: 0;
    width: 50px;
    height: 40px;
    border: 0;
    background: url(https://raw.githubusercontent.com/baivong/Celebrate-Pride-Canvas/master/img/enter.png) no-repeat center center transparent;
    text-indent: -99999px;
    cursor: pointer;
}

#celebrate-complete {
    border: 0 none;
    display: none;
    width: 320px;
}

#celebrate-reset {
    left: 0;
    right: auto;
    background-image: url(https://raw.githubusercontent.com/baivong/Celebrate-Pride-Canvas/master/img/reset.png);
    background-color: #3a3a3a;
}

#celebrate-download {
    display: block;
    padding: 0px;
    left: auto;
    right: 0px;
    width: 260px;
    height: 40px;
    background: #3a3a3a;
    cursor: pointer;
}

#celebrate-get {
    position: absolute;
    left: 0;
    top: 0;
    width: 260px;
    text-align: center;
    line-height: 40px;
    color: #FFF;
    font-family: monospace;
    font-size: 16px;
    font-weight: bold;
}

#celebrate-progress {
    display: block;
    height: 100%;
    background: #2196F3 none repeat scroll 0% 0%;
    width: 0;
}

#celebrate-result {
    width: 246px;
    background: #fff;
    color: #2196F3;
    display: none;
}

@-webkit-keyframes down {
    from {
        transform: scale(.3);
    }
    to {
        transform: scale(1);
    }
}

@keyframes down {
    from {
        transform: scale(.1);
    }
    to {
        transform: scale(1);
    }
}
<!doctype html>
<html>

<head>
    <meta charset="UTF-8">
    <title>Celebrate Canvas</title>
    <link rel="shortcut icon" type="image/x-icon" href="http://baivong.github.io/cdn/devsforumvi/favicon.ico">
    <link rel="stylesheet" href="style.css">
</head>

<body>

    <div id="celebrate">
        <h1>Let's Celebrate Mustache</h1>
        <div id="celebrate-img">
            <div>
                <strong>Drop image</strong>
                <br>
                <span>(or click)</span>
            </div>
        </div>
        <form id="celebrate-add" class="wrap-btn">
            <input type="url" id="celebrate-input" placeholder="ENTER image url" required class="large-btn">
            <button id="celebrate-submit" type="submit" class="small-btn">OK</button>
        </form>
        <input id="celebrate-file" type="file" accept="image/*">
        <div id="celebrate-complete" class="wrap-btn">
            <div id="celebrate-reset" class="small-btn"></div>
            <div id="celebrate-download" class="large-btn">
                <span id="celebrate-progress"></span>
                <span id="celebrate-get">Get link</span>
                <input type="url" id="celebrate-result" class="large-btn">
            </div>
        </div>
    </div>

    <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
    <script src="script.js"></script>
</body>

</html>
    
12.10.2015 / 05:08