Example of how to mosaic an image using js

Example of how to mosaic an image using js

This article mainly introduces an example of how to mosaic an image with js, and shares it with you, as follows:

Effect Demonstration

insert image description here

Introduction to Canvas

This HTML element is designed for client-side vector graphics. It has no behavior of its own, but exposes a drawing API to client-side JavaScript so that the script can draw whatever it wants onto a canvas.

HTML5 tags are used to draw images (via scripts, usually JavaScript)

However, the element itself has no drawing capabilities (it is just a container for graphics) - you must use scripts to do the actual drawing.

The getContext() method returns an object that provides methods and properties for drawing on the canvas.

This manual provides a complete set of getContext("2d") object properties and methods, which can be used to draw text, lines, rectangles, circles, etc. on the canvas.

Differences between markup and SVG and VML:

An important difference between the markup and SVG and VML is that there is a JavaScript-based drawing API, whereas SVG and VML use an XML document to describe the drawing.

These two approaches are functionally equivalent, and either can be simulated by the other. On the surface, they are very different, however, each has strengths and weaknesses. For example, SVG drawings are easily editable by simply removing elements from their description.

To remove an element from a markup on the same figure, you often need to erase the drawing and redraw it.

insert image description here

Knowledge Point Introduction

Creating images using js

let img = new Image()
//You can give the picture a link img.src = 'https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=826495019,1749283937&fm=26&gp=0.jpg'
//Or the path of an existing local image//img.src = './download.jpg'

//Add to HTML document.body.appendChild(img)

canvas.getContext("2d")

grammar:
The contextID parameter specifies the type of drawing you want to do on the canvas. Currently the only legal value is "2d", which specifies two-dimensional drawing and causes this method to return an environment object that exports a two-dimensional drawing API.

let ctx = Canvas.getContext(contextID)

ctx.drawImage()

JavaScript Syntax 1:
Position the image on the canvas:

context.drawImage(img,x,y);

JavaScript Syntax 2:
Position the image on the canvas and specify its width and height:

context.drawImage(img,x,y,width,height);

JavaScript Syntax 3:
Crop the image and position the cropped portion on the canvas:

JavaScript Syntax
The getImageData() method returns an ImageData object that copies the pixel data of the specified rectangle of the canvas.
For each pixel in an ImageData object, there are four pieces of information, namely RGBA values:
R - Red (0-255)
G - Green (0-255)
B - Blue (0-255)
A - alpha channel (0-255; 0 is transparent, 255 is fully visible)
color/alpha exists in array form and is stored in the data property of the ImageData object

var imgData = context.getImageData(x,y,width,height);

ctx.putImageData()

The putImageData() method puts the image data (from the specified ImageData object) back onto the canvas.

Next, follow me step by step to complete this small function~

insert image description here

step-by-step

Prepare our image and add our method

<body>
    <img src="./download.jpg">
    <button onclick="addCanvas()">Generate Canvas</button>
    <button onclick="generateImg()">Generate image</button>
</body>

insert image description here

Next, write addCanvas method

function addCanvas() {
		let bt = document.querySelector('button')

        let img = new Image(); //1. Prepare to copy a picture img.src = './download.jpg'; 
        img.onload = function() { //2. Wait for the image to load. let width = this.width
            let height = this.height
			
			let canvas = document.createElement('canvas') //3. Create a canvas let ctx = canvas.getContext("2d"); //4. Get the content of the canvas canvas.setAttribute('width', width) //5. For uniformity, set the width and height of the canvas to the width and height of the image canvas.setAttribute('height', height)
   
            ctx.drawImage(this, 0, 0, width, height); //5. Draw the image on the canvas document.body.insertBefore(canvas, bt) //5. Insert the canvas in front of the button}
    }

Successfully get the image on the canvas:

insert image description here

Well, we have successfully taken a small step towards success, what should we do next? …Well, we need to use the native onmouseup and onmousedown events to represent the process of pressing the mouse, so where do we add these two events?

That's right, since we want to perform mosaic operations on canvas, we must add these two events to the canvas element

Considering that the process of creating canvas is a bit complicated, let's make a module encapsulation!

function addCanvas() {
        let bt = document.querySelector('button')

        let img = new Image();
        img.src = './download.jpg'; //Put your own picture here img.onload = function() {
            let width = this.width
            let height = this.height

            let {
                canvas,
                ctx
            } = createCanvasAndCtx(width, height) //Object deconstruction receives canvas and ctx

            ctx.drawImage(this, 0, 0, width, height);

            document.body.insertBefore(canvas, bt)

        }
    }

    function createCanvasAndCtx(width, height) {
        let canvas = document.createElement('canvas')
        canvas.setAttribute('width', width)
        canvas.setAttribute('height', height)
        canvas.setAttribute('onmouseout', 'end()') //Fix the mouse not leaving the canvas canvas.setAttribute('onmousedown', 'start()') //Add mouse down canvas.setAttribute('onmouseup', 'end()') //Add mouse up let ctx = canvas.getContext("2d");
        return {
            canvas,
            ctx
        }
    }

	function start() {
            let canvas = document.querySelector('canvas')
            canvas.onmousemove = () => {
                console.log('You pressed and moved the mouse')
            }
        }

        function end() {
            let canvas = document.querySelector('canvas')
            canvas.onmousemove = null
        }

Test whether our start() and end() are effective

insert image description here

Well, at this point, our code is still working as we wish.

The next challenge is more severe. We need to get pixels and process them. Let's rewrite the start() function again.

function start() {
    let img = document.querySelector('img')
    let canvas = document.querySelector('canvas')
    let ctx = canvas.getContext("2d");
    imgData = ctx.getImageData(0, 0, img.clientWidth, img.clientHeight);
    canvas.onmousemove = (e) => {
        let w = imgData.width; //1. Get the image width and height let h = imgData.height;

        //The degree of mosaic, the larger the number, the blurrier let num = 10;

        //Get the pixel RGBA where the mouse is currently located
        let color = getXY(imgData, e.offsetX, e.offsetY);

        for (let k = 0; k < num; k++) {
            for (let l = 0; l < num; l++) {
                //Set the color of imgData with coordinates (e.offsetX + l, e.offsetY + k)setXY(imgData, e.offsetX + l, e.offsetY + k, color);
            }
        }
        //Update canvas data ctx.putImageData(imgData, 0, 0);
    }
}

//Here are two functions, setXY and getXY. If you are interested, you can study the principle of getting. function setXY(obj, x, y, color) {
    var w = obj.width;
    var h = obj.height;
    var d = obj.data;
    obj.data[4 * (y * w + x)] = color[0];
    obj.data[4 * (y * w + x) + 1] = color[1];
    obj.data[4 * (y * w + x) + 2] = color[2];
    obj.data[4 * (y * w + x) + 3] = color[3];
}

function getXY(obj, x, y) {
    var w = obj.width;
    var h = obj.height;
    var d = obj.data;
    var color = [];
    color[0] = obj.data[4 * (y * w + x)];
    color[1] = obj.data[4 * (y * w + x) + 1];
    color[2] = obj.data[4 * (y * w + x) + 2];
    color[3] = obj.data[4 * (y * w + x) + 3];
    return color;
}

Well, we are not far from success. The last step is to generate the image.

Fortunately, canavs provides us with a direct method to directly export the canvas as a Base64-encoded image:

function generateImg() {
    let canvas = document.querySelector('canvas')
    var newImg = new Image();
    newImg.src = canvas.toDataURL("image/png");
    document.body.insertBefore(newImg, canvas)
}

Final result:

insert image description here

Isn't it very easy? Let's see if your handwritten code is the same as the following:

Complete code

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

    <body>
        <img src="./download.jpg">
        <button onclick="addCanvas()">Generate Canvas</button>
        <button onclick="generateImg()">Generate image</button>
    </body>
    <script>
        function addCanvas() {
            let bt = document.querySelector('button')

            let img = new Image();
            img.src = './download.jpg'; //Put your own picture here img.onload = function() {
                let width = this.width
                let height = this.height

                let {
                    canvas,
                    ctx
                } = createCanvasAndCtx(width, height)

                ctx.drawImage(this, 0, 0, width, height);

                document.body.insertBefore(canvas, bt)

            }
        }

        function createCanvasAndCtx(width, height) {
            let canvas = document.createElement('canvas')
            canvas.setAttribute('width', width)
            canvas.setAttribute('height', height)
            canvas.setAttribute('onmouseout', 'end()')
            canvas.setAttribute('onmousedown', 'start()')
            canvas.setAttribute('onmouseup', 'end()')
            let ctx = canvas.getContext("2d");
            return {
                canvas,
                ctx
            }
        }

        function start() {
            let img = document.querySelector('img')
            let canvas = document.querySelector('canvas')
            let ctx = canvas.getContext("2d");
            imgData = ctx.getImageData(0, 0, img.clientWidth, img.clientHeight);
            canvas.onmousemove = (e) => {
                let w = imgData.width; //1. Get the image width and height let h = imgData.height;

                //The degree of mosaic, the larger the number, the blurrier let num = 10;

                //Get the pixel RGBA where the mouse is currently located
                let color = getXY(imgData, e.offsetX, e.offsetY);

                for (let k = 0; k < num; k++) {
                    for (let l = 0; l < num; l++) {
                        //Set the color of imgData with coordinates (e.offsetX + l, e.offsetY + k)setXY(imgData, e.offsetX + l, e.offsetY + k, color);
                    }
                }
                //Update canvas data ctx.putImageData(imgData, 0, 0);
            }
        }

        function generateImg() {
            let canvas = document.querySelector('canvas')
            var newImg = new Image();
            newImg.src = canvas.toDataURL("image/png");
            document.body.insertBefore(newImg, canvas)
        }

        function setXY(obj, x, y, color) {
            var w = obj.width;
            var h = obj.height;
            var d = obj.data;
            obj.data[4 * (y * w + x)] = color[0];
            obj.data[4 * (y * w + x) + 1] = color[1];
            obj.data[4 * (y * w + x) + 2] = color[2];
            obj.data[4 * (y * w + x) + 3] = color[3];
        }

        function getXY(obj, x, y) {
            var w = obj.width;
            var h = obj.height;
            var d = obj.data;
            var color = [];
            color[0] = obj.data[4 * (y * w + x)];
            color[1] = obj.data[4 * (y * w + x) + 1];
            color[2] = obj.data[4 * (y * w + x) + 2];
            color[3] = obj.data[4 * (y * w + x) + 3];
            return color;
        }

        function end() {
            let canvas = document.querySelector('canvas')
            canvas.onmousemove = null
        }
    </script>
</body>

</html>

Of course, you can do more creations. For example, the mosaic above is a square. You can use your mathematical knowledge to make it circular and spread it with the center of the circle as the center of the mouse.

You can also choose to improve some processes. For example, if the mosaic position is wrong, you can choose to clear the canvas and start again.
Or do some post-processing and hide the canvas after exporting the image

This is the end of this article about examples of how to use js to mosaic images. For more relevant js image mosaic content, please search 123WORDPRESS.COM's previous articles or continue to browse the following related articles. I hope everyone will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Three.js sample code for mosaicking images
  • Use javascript to display the image mosaic and switch to add text function
  • Use javascript to display and switch images after mosaic

<<:  How to deploy Spring Boot using Docker

>>:  Detailed installation steps for MySQL 8.0.11

Recommend

How to run tomcat source code in maven mode

Preface Recently, I was analyzing the startup pro...

Detailed explanation of tcpdump command examples in Linux

Preface To put it simply, tcpdump is a packet ana...

How to install and modify the initial password of mysql5.7.18

For Centos installation of MySQL, please refer to...

React gets input value and submits 2 methods examples

Method 1: Use the target event attribute of the E...

Solve the problem of docker images disappearing

1. Mirror images disappear in 50 and 93 [root@h50...

Summary of common MySQL table design errors

Table of contents Mistake 1: Too many columns of ...

How to match the size of text in web design: small text, big experience

With the rise of mobile terminals such as iPad, p...

How to set up the use of Chinese input method in Ubuntu 18.04

In the latest version of Ubuntu, users no longer ...

Use Docker Compose to quickly deploy ELK (tested and effective)

Table of contents 1. Overview 1.1 Definition 1.2 ...

Application of Beautiful Style Sheets in XHTML+CSS Web Page Creation

This is an article written a long time ago. Now it...

MySQL 8.0.23 installation super detailed tutorial

Table of contents Preface 1. Download MySQL from ...

MySQL InnoDB MRR Optimization Guide

Preface MRR is the abbreviation of Multi-Range Re...