4

In my codepen i want to use pixelmatch to show the difference of two images in the browser. The function is used like this

// img1, img2 — ImageData.data of the images to compare  
// output — ImageData to write the diff to, or null if don't need a diff image.
// width, height of the images - all 3 images need to have the same dimensions.


// calling pixelmatch  looks like this
var numDiffPixels = pixelmatch(img1.data, img2.data
      , imageDataOutput, wdth, hght, {threshold: 0.1});

I got this to work

  1. create an ImageData-Object from an <img>-tag and retrieve the data as Uint8Array from the image
  2. pass the Uint8Array for each image using imageData.data to the function pixelmatch
  3. fill imageDataOutput and get a number of different pixels in numDiffixels

the HTML

<p>
    <img id="imgBefore" src="./img/T1_Before.jpg">
    <img id="imgAfter" src="./img/T1_After.jpg"  >
</p>
<p>
    <button id="diff" class="js-compareImages">compare images</button>
    <canvas id="cnvDiff"></canvas>
</p>
<p id="result"> </p>

Helper Function

First a helper function to get a 'canvas' from an image

// Converts image to canvas; returns new canvas element
function convertImageToCanvas(imageID) {
    var image = document.getElementById(imageID);
    var canvas = document.createElement("canvas");
    canvas.width = image.width;
    canvas.height = image.height;
    canvas.getContext("2d").drawImage(image, 0, 0);
    // image.style = "width: 400px";
    return canvas;
}

The main function

The the main function to compare the images

function compareImages()
{        
    var cnvBefore = convertImageToCanvas("imgBefore");
    var cnvAfter = convertImageToCanvas("imgAfter");

    var ctxBefore = cnvBefore.getContext("2d");
    var ctxAfter = cnvAfter.getContext("2d");

    let imgDataBefore = ctxBefore.getImageData(0,0,cnvBefore.width, cnvBefore.height);
    let imgDataAfter = ctxAfter.getImageData(0,0, cnvAfter.width, cnvAfter.height);   

    const hght = imgDataBefore.height;
    const wdth = imgDataBefore.width;

    var imgDataOutput = new ImageData(wdth, hght);

    var numDiffPixels = pixelmatch(imgDataBefore.data, imgDataAfter.data, 
                        imgDataOutput, wdth, hght, {threshold: 0.1});

     // this line does not work
     writeResultToPage(imgDataOutput)

}

What does not work

  1. using the values from imgDataOutput to show the differences of the two images in a third image or on a canvas
  2. What is not working: either a black image is created or the output-canvas is empty

This is the code that does not produce the desired result

function writeResultToPage(imgDataOutput)
{
  var canvas = document.createElement("canvas"); //  new HTMLCanvasElement();
    var ctx = canvas.getContext("2d");
    ctx.putImageData(imgDataOutput, 0, 0);
    var result = document.getElementById("result");
    result.appendChild(ctx.canvas);
}

Question

Why is the output-canvas from writeResultToPage(imgDataOutput) empty? What do i have to change to put imgDataOutput on the page as either an <img> or as a <canvas>?

Here is my matching codepen

surfmuggle
  • 5,527
  • 7
  • 48
  • 77
  • I have an updated example using a newer version of pixelmatch in [Compare two Images in JavaScript](https://stackoverflow.com/a/71985143/6243352). – ggorlen Apr 24 '22 at 03:02

1 Answers1

3

The problem is that you need to add ".data" to imgDataOutput here:

var numDiffPixels = pixelmatch(imgDataBefore.data, imgDataAfter.data, 
                    imgDataOutput.data, wdth, hght, {threshold: 0.1});

I also added:

canvas.width = imgDataOutput.width;
canvas.height = imgDataOutput.height;

to writeResultToPage so that the canvas is the right size for the image.

Updated codepen: https://codepen.io/anon/pen/dEVNmv

aptriangle
  • 1,395
  • 1
  • 9
  • 11