Percentage difference between images: Difference between revisions

"Ada" section: Correct reference to "Left.G" to "Right.G".
("Ada" section: Correct reference to "Left.G" to "Right.G".)
 
(60 intermediate revisions by 36 users not shown)
Line 12:
|[[Image:Lenna50.jpg|200px]]
|[[Image:Lenna100.jpg|200px]]
|-
|[http://rosettacode.org/mw/images/3/3c/Lenna50.jpg link to full size 50% image]
|[http://rosettacode.org/mw/images/b/b6/Lenna100.jpg link to full size 100% image]
|}
 
Line 17 ⟶ 20:
 
=={{header|Ada}}==
<langsyntaxhighlight lang="ada">type Count is mod 2**64;</langsyntaxhighlight>
[[wp:Distance|1-norm distance]] in the luminance space:
<langsyntaxhighlight lang="ada">function "-" (Left, Right : Luminance) return Count is
begin
if Left > Right then
Line 26 ⟶ 29:
return Count (Right) - Count (Left);
end if;
end "-";</langsyntaxhighlight>
1-norm distance in the color space multiplied to 3:
<langsyntaxhighlight lang="ada">function "-" (Left, Right : Pixel) return Count is
begin
return (Left.R - Right.R) + (Left.G - LeftRight.G) + (Left.B - Right.B);
end "-";</langsyntaxhighlight>
Mean of 1-norm distances. Constraint_Error is propagated when images have different size.
<langsyntaxhighlight lang="ada">function Diff (Left, Right : Image) return Float is
Offs_I : constant Integer := Right'First (1) - Left'First (1);
Offs_J : constant Integer := Right'First (2) - Left'First (2);
Line 47 ⟶ 50:
end loop;
return Float (Sum) / (3.0 * Float (Left'Length (1) * Left'Length (2)));
end Diff;</langsyntaxhighlight>
Example of use:
<langsyntaxhighlight lang="ada"> F1, F2 : File_Type;
begin
Open (F1, In_File, "city.ppm");
Line 55 ⟶ 58:
Ada.Text_IO.Put_Line ("Diff" & Float'Image (Diff (Get_PPM (F1), Get_PPM (F2))));
Close (F1);
Close (F2);</langsyntaxhighlight>
 
=={{header|AutoHotkey}}==
{{works with | AutoHotkey_L}}
uses [http://www.autohotkey.com/forum/topic32238.html gdip.ahk]
<langsyntaxhighlight AutoHotkeylang="autohotkey">startup()
dibSection := getPixels("lenna100.jpg")
dibSection2 := getPixels("lenna50.jpg") ; ("File-Lenna100.jpg")
Line 136 ⟶ 140:
 
DllCall("SelectObject", "Uint", mDCo, "Uint", oBM)
DllCall("ReleaseDCDeleteDC", "Uint", 0, "Uint", mDCi)
DllCall("ReleaseDCDeleteDC", "Uint", 0, "Uint", mDCo)
Gdip_DisposeImage(pBitmapFile1)
DllCall("DeleteObject", "Uint", hBMi)
Line 144 ⟶ 148:
}
#Include Gdip.ahk ; Thanks to tic (Tariq Porter) for his GDI+ Library
</syntaxhighlight>
</lang>
 
=={{header|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
I would have preferred to calculate the RMS difference but it would be inconsistent with other results.
<syntaxhighlight lang="bbcbasic"> hbm1% = FNloadimage("C:lenna50.jpg")
hbm2% = FNloadimage("C:lenna100.jpg")
SYS "CreateCompatibleDC", @memhdc% TO hdc1%
SYS "CreateCompatibleDC", @memhdc% TO hdc2%
SYS "SelectObject", hdc1%, hbm1%
SYS "SelectObject", hdc2%, hbm2%
diff% = 0
FOR y% = 0 TO 511
FOR x% = 0 TO 511
SYS "GetPixel", hdc1%, x%, y% TO rgb1%
SYS "GetPixel", hdc2%, x%, y% TO rgb2%
diff% += ABS((rgb1% AND &FF) - (rgb2% AND &FF))
diff% += ABS((rgb1% >> 8 AND &FF) - (rgb2% >> 8 AND &FF))
diff% += ABS((rgb1% >> 16) - (rgb2% >> 16))
NEXT
NEXT y%
PRINT "Image difference = "; 100 * diff% / 512^2 / 3 / 255 " %"
SYS "DeleteDC", hdc1%
SYS "DeleteDC", hdc2%
SYS "DeleteObject", hbm1%
SYS "DeleteObject", hbm2%
END
DEF FNloadimage(file$)
LOCAL iid{}, hbm%, pic%, ole%, olpp%, text%
DIM iid{a%,b%,c%,d%}, text% LOCAL 513
iid.a% = &7BF80980 : REM. 128-bit iid
iid.b% = &101ABF32
iid.c% = &AA00BB8B
iid.d% = &AB0C3000
SYS "MultiByteToWideChar", 0, 0, file$, -1, text%, 256
SYS "LoadLibrary", "OLEAUT32.DLL" TO ole%
SYS "GetProcAddress", ole%, "OleLoadPicturePath" TO olpp%
IF olpp%=0 THEN = 0
SYS olpp%, text%, 0, 0, 0, iid{}, ^pic% : REM. OleLoadPicturePath
IF pic%=0 THEN = 0
SYS !(!pic%+12), pic%, ^hbm% : REM. IPicture::get_Handle
SYS "FreeLibrary", ole%
= hbm%</syntaxhighlight>
'''Output:'''
<pre>
Image difference = 1.6255931 %
</pre>
 
=={{header|C}}==
Line 150 ⟶ 210:
The <tt>read_image</tt> function is from [[Read image file through a pipe|here]].
 
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
#include <math.h>
Line 194 ⟶ 254:
free_img(im1);
free_img(im2);
}</langsyntaxhighlight>
 
The output on Lenna is:
Line 201 ⟶ 261:
1.625587
</pre>
 
=={{header|C sharp|C#}}==
 
<syntaxhighlight lang="csharp">using System;
using System.Drawing;
 
class Program
{
static void Main()
{
Bitmap img1 = new Bitmap("Lenna50.jpg");
Bitmap img2 = new Bitmap("Lenna100.jpg");
 
if (img1.Size != img2.Size)
{
Console.Error.WriteLine("Images are of different sizes");
return;
}
 
float diff = 0;
 
for (int y = 0; y < img1.Height; y++)
{
for (int x = 0; x < img1.Width; x++)
{
Color pixel1 = img1.GetPixel(x, y);
Color pixel2 = img2.GetPixel(x, y);
 
diff += Math.Abs(pixel1.R - pixel2.R);
diff += Math.Abs(pixel1.G - pixel2.G);
diff += Math.Abs(pixel1.B - pixel2.B);
}
}
 
Console.WriteLine("diff: {0} %", 100 * (diff / 255) / (img1.Width * img1.Height * 3));
}
}</syntaxhighlight>
 
=={{header|C++}}==
 
based upon C version, using Qt 4.4
<langsyntaxhighlight Cpplang="cpp">#include <QImage>
#include <cstdlib>
#include <QColor>
Line 239 ⟶ 336:
int gSecond = qGreen( pixelSecond ) ;
int bSecond = qBlue( pixelSecond ) ;
totaldiff += std::abs( rFirst - rSecond ) / 255.0 ;
totaldiff += std::abs( gFirst - gSecond ) / 255.0 ;
totaldiff += std::abs( bFirst -bSecond ) / 255.0 ;
}
}
Line 247 ⟶ 344:
(totaldiff * 100) / (w * h * 3) << " % !\n" ;
return 0 ;
}</langsyntaxhighlight>
 
output on pictures given;
Line 258 ⟶ 355:
This is based upon the C version. Strangely enough, the percentage is 1.77% which is off by about a tenth of a percent.
 
<langsyntaxhighlight lang="lisp">(require 'cl-jpeg)
;;; the JPEG library uses simple-vectors to store data. this is insane!
(defun compare-images (file1 file2)
Line 271 ⟶ 368:
 
CL-USER> (* 100 (compare-images "Lenna50.jpg" "Lenna100.jpg"))
1.774856467652165d0</langsyntaxhighlight>
 
=={{header|D}}==
{{trans|Python}}
<syntaxhighlight lang="d">import std.stdio, std.exception, std.range, std.math, bitmap;
 
void main() {
Image!RGB i1, i2;
i1 = i1.loadPPM6("Lenna50.ppm");
i2 = i2.loadPPM6("Lenna100.ppm");
 
enforce(i1.nx == i2.nx && i1.ny == i2.ny, "Different sizes.");
 
real dif = 0.0;
foreach (p, q; zip(i1.image, i2.image))
dif += abs(p.r - q.r) + abs(p.g - q.g) + abs(p.b - q.b);
 
immutable nData = i1.nx * i1.ny * 3;
writeln("Difference (percentage): ",
(dif / 255.0 * 100) / nData);
}</syntaxhighlight>
{{out}}
<pre>Difference (percentage): 1.62559</pre>
 
=={{header|E}}==
Line 277 ⟶ 396:
By dividing only at the end, we work with integers only as the sum and avoid floating-point error from adding small numbers (per-pixel difference) to large ones (sum of differences).
 
<langsyntaxhighlight lang="e">def imageDifference(a, b) {
require(a.width() == b.width())
require(a.height() == b.height())
Line 305 ⟶ 424:
def d := imageDifference(a, b)
println(`${d * 100}% different.`)
}</langsyntaxhighlight>
 
The result on the provided images is 1.6255930981604882%.
 
=={{header|F_Sharp|F#}}==
<syntaxhighlight lang="fsharp">
//Percentage difference between 2 images. Nigel Galloway April 18th., 2018
let img50 = new System.Drawing.Bitmap("Lenna50.jpg")
let img100 = new System.Drawing.Bitmap("Lenna100.jpg")
let diff=Seq.cast<System.Drawing.Color*System.Drawing.Color>(Array2D.init img50.Width img50.Height (fun n g->(img50.GetPixel(n,g),img100.GetPixel(n,g))))|>Seq.fold(fun i (e,l)->i+abs(int(e.R)-int(l.R))+abs(int(e.B)-int(l.B))+abs(int(e.G)-int(l.G))) 0
printfn "%f" ((float diff)*100.00/(float(img50.Height*img50.Width)*255.0*3.0))</syntaxhighlight>
{{out}}
<pre>
1.774691
</pre>
 
=={{header|Forth}}==
<langsyntaxhighlight lang="forth">: pixel-diff ( pixel1 pixel2 -- n )
over 255 and over 255 and - abs >r 8 rshift swap 8 rshift
over 255 and over 255 and - abs >r 8 rshift swap 8 rshift
Line 326 ⟶ 457:
 
: .bdiff ( bmp1 bmp2 -- )
cr bdiff 100e f* f. ." percent different" ;</langsyntaxhighlight>
 
=={{header|Fortran}}==
 
<langsyntaxhighlight lang="fortran">program ImageDifference
 
use RCImageBasic
Line 361 ⟶ 492:
call free_img(lenna2)
 
end program ImageDifference</langsyntaxhighlight>
 
This gives 1.6555154.
 
=={{header|Frink}}==
==Haskell==
 
<syntaxhighlight lang="frink">
img1 = new image["file:Lenna50.jpg"]
img2 = new image["file:Lenna100.jpg"]
 
[w1, h1] = img1.getSize[]
[w2, h2] = img2.getSize[]
 
sum = 0
for x=0 to w1-1
for y=0 to h1-1
{
[r1,g1,b1] = img1.getPixel[x,y]
[r2,g2,b2] = img2.getPixel[x,y]
sum = sum + abs[r1-r2] + abs[g1-g2] + abs[b1-b2]
}
 
errors = sum / (w1 * h1 * 3)
println["Error is " + (errors->"percent")]
</syntaxhighlight>
 
This gives an error of approximately 1.625593 percent.
 
=={{header|Go}}==
Using standard image library:
<syntaxhighlight lang="go">package main
 
import (
"fmt"
"image/jpeg"
"os"
"log"
"image"
)
 
func loadJpeg(filename string) (image.Image, error) {
f, err := os.Open(filename)
if err != nil {
return nil, err
}
defer f.Close()
 
img, err := jpeg.Decode(f)
if err != nil {
return nil, err
}
 
return img, nil
}
 
func diff(a, b uint32) int64 {
if a > b {
return int64(a - b)
}
return int64(b - a)
}
 
func main() {
i50, err := loadJpeg("Lenna50.jpg")
if err != nil {
log.Fatal(err)
}
 
i100, err := loadJpeg("Lenna100.jpg")
if err != nil {
log.Fatal(err)
}
 
if i50.ColorModel() != i100.ColorModel() {
log.Fatal("different color models")
}
 
b := i50.Bounds()
if !b.Eq(i100.Bounds()) {
log.Fatal("different image sizes")
}
 
var sum int64
for y := b.Min.Y; y < b.Max.Y; y++ {
for x := b.Min.X; x < b.Max.X; x++ {
r1, g1, b1, _ := i50.At(x, y).RGBA()
r2, g2, b2, _ := i100.At(x, y).RGBA()
sum += diff(r1, r2)
sum += diff(g1, g2)
sum += diff(b1, b2)
}
}
 
nPixels := (b.Max.X - b.Min.X) * (b.Max.Y - b.Min.Y)
fmt.Printf("Image difference: %f%%\n",
float64(sum*100)/(float64(nPixels)*0xffff*3))
}</syntaxhighlight>
Output:
<pre>
Image difference: 1.774785%
</pre>
Using code from bitmap task:
<syntaxhighlight lang="go">package main
 
// Files required to build supporting package raster are found in:
// * Bitmap
// * Read a PPM file
 
import (
"fmt"
"io"
"os/exec"
"raster"
)
 
func readJpeg(j string) (b *raster.Bitmap, err error) {
c := exec.Command("convert", j, "ppm:-")
var pipe io.Reader
pipe, err = c.StdoutPipe()
if err != nil {
return
}
err = c.Start()
if err != nil {
return
}
return raster.ReadPpmFrom(pipe)
}
 
func main() {
b1, err := readJpeg("Lenna50.jpg")
if err != nil {
fmt.Println(err)
return
}
b2, err := readJpeg("Lenna100.jpg")
if err != nil {
fmt.Println(err)
return
}
b1c, b1r := b1.Extent()
b2c, b2r := b2.Extent()
if b1c != b2c || b1r != b2r {
fmt.Println("image extents not the same")
return
}
var sum int64
for y := 0; y < b1r; y++ {
for x := 0; x < b1c; x++ {
p1, _ := b1.GetPx(x, y)
p2, _ := b2.GetPx(x, y)
d := int64(p1.R) - int64(p2.R)
if d < 0 {
sum -= d
} else {
sum += d
}
d = int64(p1.G) - int64(p2.G)
if d < 0 {
sum -= d
} else {
sum += d
}
d = int64(p1.B) - int64(p2.B)
if d < 0 {
sum -= d
} else {
sum += d
}
}
}
fmt.Printf("Image difference: %f%%\n",
float64(sum)*100/(float64(b1c*b1r)*255*3))
}</syntaxhighlight>
Output:
<pre>
Image difference: 1.625593%
</pre>
 
=={{header|Haskell}}==
 
This implementation takes PPMs as input. It uses modules defined in [[Basic bitmap storage]] and [[Write ppm file]].
 
<langsyntaxhighlight lang="haskell">import Bitmap
import Bitmap.Netpbm
import Bitmap.RGB
Line 394 ⟶ 700:
toEnum (3 * 255 * length i1)
where (RGB (r1, g1, b1)) `minus` (RGB (r2, g2, b2)) =
abs (r1 - r2) + abs (g1 - g2) + abs (b1 - b2)</langsyntaxhighlight>
 
=={{header|Icon}} and {{header|Unicon}}==
The images are opened as hidden windows and directly queried for their size and pixel contents. RGB colour intensities range from 0-65535 and all calculations are done with large integers and converted to real at the end.
The Icon and Unicon graphics facilities are under documented with respect to some features. Unicon can support reading and writing to a number of additional image formats. I'm not sure if this will run under Icon or not. Some minor reworking of the open would be the minimum requirement; however, Icon may not have read support for jpg files.
 
<syntaxhighlight lang="unicon">link printf # for main only
=={{header|Mathematica}}==
 
<lang Mathematica>img50 = ImageData@Import[NotebookDirectory[] <> "Lenna50.jpg"];
procedure main() # % difference between images
fn1 := "Lenna100.jpg"
fn2 := "Lenna50.jpg"
printf("%%difference of files %i & %i = %r\n",fn1,fn2,ImageDiff(fn1,fn2))
end
procedure ImageDiff(fn1,fn2) #: return % difference of two images
img1 := open(1,"g","canvas=hidden","image="||fn1) | stop("Open failed ",fn1)
img2 := open(2,"g","canvas=hidden","image="||fn2) | stop("Open failed ",fn2)
if WAttrib(img1,"width") ~= WAttrib(img2,"width") |
WAttrib(img1,"height") ~= WAttrib(img2,"height") then
stop("Images must be the same size")
 
pix1 := create Pixel(img1) # access pixels one at a time
pix2 := create Pixel(img2) # ... facilitate interleaved access
 
sum := pix := 0
while pix +:= 1 & p1 := csv2l(@pix1) & p2 := csv2l(@pix2) do
every sum +:= abs(p1[i := 1 to *p1] - p2[i])
every close(img1|img2)
return sum / (pix * 3 * 65535 / 100. )
end
 
procedure csv2l(p) #: return a list from a comma separated string
L := []
p ? until pos(0) do {
put(L,tab(find(",")|0))
move(1)
}
return L
end</syntaxhighlight>
 
Output:<pre>%difference of files "Lenna100.jpg" & "Lenna50.jpg" = 1.625587</pre>
 
=={{header|J}}==
<syntaxhighlight lang="j"> require 'media/image3'
'Lenna50.jpg' (+/@,@:|@:- % 2.55 * */@$@])&read_image 'Lenna100.jpg'
1.62559</syntaxhighlight>
 
=={{header|Java}}==
 
<syntaxhighlight lang="java">import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
 
public enum ImgDiffPercent {
;
 
public static void main(String[] args) throws IOException {
// https://rosettacode.org/mw/images/3/3c/Lenna50.jpg
// https://rosettacode.org/mw/images/b/b6/Lenna100.jpg
BufferedImage img1 = ImageIO.read(new File("Lenna50.jpg"));
BufferedImage img2 = ImageIO.read(new File("Lenna100.jpg"));
 
double p = getDifferencePercent(img1, img2);
System.out.println("diff percent: " + p);
}
 
private static double getDifferencePercent(BufferedImage img1, BufferedImage img2) {
int width = img1.getWidth();
int height = img1.getHeight();
int width2 = img2.getWidth();
int height2 = img2.getHeight();
if (width != width2 || height != height2) {
throw new IllegalArgumentException(String.format("Images must have the same dimensions: (%d,%d) vs. (%d,%d)", width, height, width2, height2));
}
 
long diff = 0;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
diff += pixelDiff(img1.getRGB(x, y), img2.getRGB(x, y));
}
}
long maxDiff = 3L * 255 * width * height;
 
return 100.0 * diff / maxDiff;
}
 
private static int pixelDiff(int rgb1, int rgb2) {
int r1 = (rgb1 >> 16) & 0xff;
int g1 = (rgb1 >> 8) & 0xff;
int b1 = rgb1 & 0xff;
int r2 = (rgb2 >> 16) & 0xff;
int g2 = (rgb2 >> 8) & 0xff;
int b2 = rgb2 & 0xff;
return Math.abs(r1 - r2) + Math.abs(g1 - g2) + Math.abs(b1 - b2);
}
}</syntaxhighlight>
 
=={{header|JavaScript}}==
 
<syntaxhighlight lang="javascript">function getImageData(url, callback) {
var img = document.createElement('img');
var canvas = document.createElement('canvas');
 
img.onload = function () {
canvas.width = img.width;
canvas.height = img.height;
var ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0);
callback(ctx.getImageData(0, 0, img.width, img.height));
};
 
img.src = url;
}
 
function compare(firstImage, secondImage, callback) {
getImageData(firstImage, function (img1) {
getImageData(secondImage, function (img2) {
if (img1.width !== img2.width || img1.height != img2.height) {
callback(NaN);
return;
}
 
var diff = 0;
for (var i = 0; i < img1.data.length / 4; i++) {
diff += Math.abs(img1.data[4 * i + 0] - img2.data[4 * i + 0]) / 255;
diff += Math.abs(img1.data[4 * i + 1] - img2.data[4 * i + 1]) / 255;
diff += Math.abs(img1.data[4 * i + 2] - img2.data[4 * i + 2]) / 255;
}
 
callback(100 * diff / (img1.width * img1.height * 3));
});
});
}
 
compare('Lenna50.jpg', 'Lenna100.jpg', function (result) {
console.log(result);
});</syntaxhighlight>
 
=={{header|Julia}}==
<syntaxhighlight lang="julia">using Images, FileIO, Printf
 
absdiff(a::RGB{T}, b::RGB{T}) where T = sum(abs(col(a) - col(b)) for col in (red, green, blue))
function pctdiff(A::Matrix{Color{T}}, B::Matrix{Color{T}}) where T
size(A) != size(B) && throw(ArgumentError("images must be same-size"))
s = zero(T)
for (a, b) in zip(A, B)
s += absdiff(a, b)
end
return 100s / 3prod(size(A))
end
 
img50 = load("data/lenna50.jpg") |> Matrix{RGB{Float64}};
img100 = load("data/lenna100.jpg") |> Matrix{RGB{Float64}};
 
d = pctdiff(img50, img100)
@printf("Percentage difference: %.4f%%\n", d)</syntaxhighlight>
 
{{out}}
<pre>Percentage difference: 1.6247%</pre>
 
=={{header|Kotlin}}==
{{trans|Java}}
<syntaxhighlight lang="scala">// version 1.2.10
 
import java.awt.image.BufferedImage
import java.io.File
import javax.imageio.ImageIO
import kotlin.math.abs
 
fun getDifferencePercent(img1: BufferedImage, img2: BufferedImage): Double {
val width = img1.width
val height = img1.height
val width2 = img2.width
val height2 = img2.height
if (width != width2 || height != height2) {
val f = "(%d,%d) vs. (%d,%d)".format(width, height, width2, height2)
throw IllegalArgumentException("Images must have the same dimensions: $f")
}
var diff = 0L
for (y in 0 until height) {
for (x in 0 until width) {
diff += pixelDiff(img1.getRGB(x, y), img2.getRGB(x, y))
}
}
val maxDiff = 3L * 255 * width * height
return 100.0 * diff / maxDiff
}
 
fun pixelDiff(rgb1: Int, rgb2: Int): Int {
val r1 = (rgb1 shr 16) and 0xff
val g1 = (rgb1 shr 8) and 0xff
val b1 = rgb1 and 0xff
val r2 = (rgb2 shr 16) and 0xff
val g2 = (rgb2 shr 8) and 0xff
val b2 = rgb2 and 0xff
return abs(r1 - r2) + abs(g1 - g2) + abs(b1 - b2)
}
 
fun main(args: Array<String>) {
val img1 = ImageIO.read(File("Lenna50.jpg"))
val img2 = ImageIO.read(File("Lenna100.jpg"))
 
val p = getDifferencePercent(img1, img2)
println("The percentage difference is ${"%.6f".format(p)}%")
}</syntaxhighlight>
 
{{out}}
<pre>
The percentage difference is 1.625593%
</pre>
 
=={{header|Lua}}==
Using the Bitmap class from [[Bitmap/Bresenham%27s_line_algorithm#Lua|here]] and ImageMagick to preprocess jpg->ppm to simplify loading:
<syntaxhighlight lang="lua">Bitmap.loadPPM = function(self, filename)
local fp = io.open( filename, "rb" )
if fp == nil then return false end
local head, width, height, depth, tail = fp:read("*line", "*number", "*number", "*number", "*line")
self.width, self.height = width, height
self:alloc()
self:clear( {0,0,0} )
for y = 1, self.height do
for x = 1, self.width do
self.pixels[y][x] = { string.byte(fp:read(1)), string.byte(fp:read(1)), string.byte(fp:read(1)) }
end
end
fp:close()
return true
end
 
Bitmap.percentageDifference = function(self, other)
if self.width ~= other.width or self.height ~= other.height then return end
local dif, abs, spx, opx = 0, math.abs, self.pixels, other.pixels
for y = 1, self.height do
for x = 1, self.width do
local sp, op = spx[y][x], opx[y][x]
dif = dif + abs(sp[1]-op[1]) + abs(sp[2]-op[2]) + abs(sp[3]-op[3])
end
end
return dif/255/self.width/self.height/3*100
end
 
local bm50 = Bitmap(0,0)
bm50:loadPPM("Lenna50.ppm")
 
local bm100 = Bitmap(0,0)
bm100:loadPPM("Lenna100.ppm")
 
print("%diff:", bm100:percentageDifference(bm50))</syntaxhighlight>
{{out}}
<pre>%diff: 1.6255930981605</pre>
 
=={{header|Liberty BASIC}}==
LB uses here a DLL to allow loading the jpgs. I get the 'other' result if I use LB's native bmp load and convert the jpgs to bmp with the Gimp!
The GUI shows the 'difference image'. [http://www.diga.me.uk/right.gif SceenDisplay]
<syntaxhighlight lang="lb">
now =time$( "seconds")
nomainwin
 
WindowWidth = 1620
WindowHeight = 660
 
open "jpeg.dll" for dll as #j ' "JPEG.DLL copyright Alyce Watson, 2003. "
 
open "RC Image Comparison- difference shown as 20 times abs( pixel_difference." for graphics_nf_nsb as #1
#1 "trapclose [quit]"
#1 "down ; fill black"
 
hW =hwnd( #1)
calldll #user32,"GetDC", hW as ulong, hdc as ulong
 
jname1$ ="Lenna50.jpg"
hPic1 =LoadImageFile( hW, jname1$)
if hPic1 =0 then notice "Function failed.": wait
loadbmp "demo1", hPic1
hDemo1 =hbmp( "demo1")
#1 "drawbmp demo1 10 10 ; flush"
 
jname2$ ="Lenna100.jpg"
hPic2 =LoadImageFile( hW, jname2$)
if hPic2 =0 then notice "Function failed.": wait
loadbmp "demo2", hPic2
hDemo1 =hbmp( "demo2")
#1 "drawbmp demo2 550 10 ; flush"
 
c1 =16777216
c2 = 65536
c3 = 256
x1 =10
y1 =10
x2 =550
y2 =10
 
for y =0 to 511
for x =0 to 511
pixel1 =( GetPixel( hdc, x1 +x, y1 +y) + c1) mod c1
b1 = int( pixel1 /c2)
g1 = int(( pixel1 -b1 *c2) /c3)
r1 = int( pixel1 -b1 *c2 -g1 *c3)
 
pixel2 =( GetPixel( hdc, x2 +x, y2 +y) + c1) mod c1
b2 = int( pixel2 /c2)
g2 = int(( pixel2 -b2 *c2) /c3)
r2 = int( pixel2 -b2 *c2 -g2 *c3)
 
totalDiff =totalDiff +abs( r1 -r2) +abs( g1 -g2)+ abs( b1 -b2)
 
#1 "color "; 20 *abs( r2 -r1); " "; 20 *abs( g2 -g1); " "; 20 *abs( b2 -b1)
#1 "set "; 1090 +x; " "; 10 +y
scan
next x
next y
 
#1 "place 90 575 ; color white ; backcolor black"
#1 "font courier 9 bold"
#1 "\"; " Difference between images ="; using( "#.#####", 100.0 *totalDiff / 512 /512 /3 /255); "%."
#1 "\"; " Rosetta Code for these two images =1.62125%."; " Time taken ="; time$( "seconds") -now; " seconds."
#1 "flush"
 
wait
 
function LoadImageFile( hWnd, file$)
calldll #j, "LoadImageFile", hWnd as ulong, file$ as ptr, LoadImageFile as ulong
end function
 
function GetPixel( hDC, x, y)
calldll #gdi32, "GetPixel", hDC As uLong, x As long, y As long, GetPixel As long
end function
 
[quit]
if hPic1 <>0 then calldll #gdi32, "DeleteObject", hPic1 as long, re as long
if hPic2 <>0 then calldll #gdi32, "DeleteObject", hPic2 as long, re as long
if hDemo1 <>0 then unloadbmp "demo1"
if hDemo2 <>0 then unloadbmp "demo2"
close #1
close #j
end
</syntaxhighlight>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<syntaxhighlight lang="mathematica">img50 = ImageData@Import[NotebookDirectory[] <> "Lenna50.jpg"];
img100 = ImageData@Import[NotebookDirectory[] <> "Lenna100.jpg"];
diff = img50 - img100;
Print["Total Difference between both Lenas = ",
Total@Abs@Flatten@diff/Times @@ Dimensions@img50*100, "%"]</langsyntaxhighlight>
 
'''Output'''
<pre>Total Difference between both Lenas = 1.62559%</pre>
 
=={{header|MATLAB}}==
<syntaxhighlight lang="matlab">
% Percentage difference between images
function p = PercentageDifferenceBetweenImages(im1,im2)
if numel(im1)~=numel(im2),
error('Error: images have to be the same size');
end
 
d = abs(single(im1) - single(im2))./255;
p = sum(d(:))./numel(im1)*100;
 
disp(['Percentage difference between images is: ', num2str(p), '%'])</syntaxhighlight>
 
'''Output'''
<pre>Percentage difference between images is: 1.6256%</pre>
 
=={{header|MAXScript}}==
<langsyntaxhighlight lang="maxscript">fn diffImages =
(
local img1 = selectBitmap caption:"Select Image 1"
Line 428 ⟶ 1,087:
)
format "Diff: %\%\n" (totalDiff / ((img1.width * img1.height * 3) as float) * 100)
)</langsyntaxhighlight>
 
=={{header|JNim}}==
{{libheader|imageman}}
<lang j> require 'media/image3'
We use the procedure <code>loadImage</code> which sets default values for JPEG decoding parameters. With these parameters, the difference between the images is about 1.7747 %. Using the less convenient procedure <code>readImage</code> which works on an open file, it is possible to change the parameters in order to get the smaller difference of 1.6256 %.
'Lenna50.jpg' (+/@,@:|@:- % 2.55 * */@$@])&read_image 'Lenna100.jpg'
<syntaxhighlight lang="nim">import strformat
1.62559</lang>
import imageman
 
var img50, img100: Image[ColorRGBU]
try:
img50 = loadImage[ColorRGBU]("Lenna50.jpg")
img100 = loadImage[ColorRGBU]("Lenna100.jpg")
except IOError:
echo getCurrentExceptionMsg()
quit QuitFailure
 
let width = img50.width
let height = img50.height
if img100.width != width or img100.height != height:
quit "Images have different sizes.", QuitFailure
 
var sum = 0
for x in 0..<height:
for y in 0..<width:
let color1 = img50[x, y]
let color2 = img100[x, y]
for i in 0..2:
sum += abs(color1[i].int - color2[i].int)
 
echo &"Image difference: {sum * 100 / (width * height * 3 * 255):.4f} %"</syntaxhighlight>
 
{{out}}
<pre>Image difference: 1.7747 %</pre>
 
=={{header|OCaml}}==
{{libheader|glMLite}}
 
<langsyntaxhighlight lang="ocaml">#! /usr/bin/env ocaml
#directory "+glMLite/"
#load "jpeg_loader.cma"
Line 473 ⟶ 1,159:
let diff_percent = !sum /. float !num in
Printf.printf " diff: %f percent\n" diff_percent;
;;</langsyntaxhighlight>
 
=={{header|Perl}}==
<syntaxhighlight lang="perl">use Image::Imlib2;
 
my $img1 = Image::Imlib2->load('Lenna50.jpg') || die;
my $img2 = Image::Imlib2->load('Lenna100.jpg') || die;
 
my $w = $img1->width;
my $h = $img1->height;
 
my $sum = 0;
 
for my $x (0..$w-1) {
for my $y (0..$h-1) {
my ($r1, $g1, $b1) = $img1->query_pixel($x, $y);
my ($r2, $g2, $b2) = $img2->query_pixel($x, $y);
$sum += abs($r1-$r2) + abs($g1-$g2) + abs($b1-$b2);
}
}
 
printf "%% difference = %.4f\n", 100 * $sum / ($w * $h * 3 * 255);</syntaxhighlight>
{{out}}
<pre>% difference = 1.7747</pre>
 
Alternative solution:
<syntaxhighlight lang="perl">use Imager;
use List::AllUtils qw(sum pairwise);
 
sub img_diff {
my ($file1, $file2) = @_;
 
my $img1 = Imager->new(file => $file1);
my $img2 = Imager->new(file => $file2);
 
my ($w1, $h1) = ($img1->getwidth, $img1->getheight);
my ($w2, $h2) = ($img2->getwidth, $img2->getheight);
 
if ($w1 != $w2 or $h1 != $h2) {
die "Can't compare images of different sizes";
}
 
my $sum = 0;
foreach my $y (0 .. $h1 - 1) {
foreach my $x (0 .. $w1 - 1) {
my @rgba1 = $img1->getpixel(x => $x, y => $y)->rgba;
my @rgba2 = $img2->getpixel(x => $x, y => $y)->rgba;
$sum += sum(pairwise { abs($a - $b) } @rgba1, @rgba2);
}
}
 
$sum / ($w1 * $h1 * 255 * 3);
}
 
printf "difference = %f%%\n", 100 * img_diff('Lenna50.jpg', 'Lenna100.jpg');</syntaxhighlight>
{{out}}
<pre>
difference = 1.625593%
</pre>
 
=={{header|Phix}}==
<!--<syntaxhighlight lang="phix">(notonline)-->
<span style="color: #000080;font-style:italic;">-- demo\rosetta\Percentage_difference_between_images.exw</span>
<span style="color: #008080;">without</span> <span style="color: #008080;">js</span> <span style="color: #000080;font-style:italic;">-- (file i/o)</span>
<span style="color: #008080;">include</span> <span style="color: #000000;">ppm</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">split_colour</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #7060A8;">sq_div</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">sq_and_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">#FF0000</span><span style="color: #0000FF;">,</span><span style="color: #000000;">#FF00</span><span style="color: #0000FF;">,</span><span style="color: #000000;">#FF</span><span style="color: #0000FF;">}),</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">#010000</span><span style="color: #0000FF;">,</span><span style="color: #000000;">#0100</span><span style="color: #0000FF;">,</span><span style="color: #000000;">#01</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">percentage_diff</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">img1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">img2</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">img1</span><span style="color: #0000FF;">)!=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">img2</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">or</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">img1</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">])!=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">img2</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">then</span>
<span style="color: #008080;">return</span> <span style="color: #008000;">"sizes do not match"</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">diff</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">img1</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">img1</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">r1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">g1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">b1</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">split_colour</span><span style="color: #0000FF;">(</span><span style="color: #000000;">img1</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]),</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">r2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">g2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">b2</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">split_colour</span><span style="color: #0000FF;">(</span><span style="color: #000000;">img2</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #000000;">j</span><span style="color: #0000FF;">])</span>
<span style="color: #000000;">diff</span> <span style="color: #0000FF;">+=</span> <span style="color: #7060A8;">abs</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r1</span><span style="color: #0000FF;">-</span><span style="color: #000000;">r2</span><span style="color: #0000FF;">)+</span><span style="color: #7060A8;">abs</span><span style="color: #0000FF;">(</span><span style="color: #000000;">g1</span><span style="color: #0000FF;">-</span><span style="color: #000000;">g2</span><span style="color: #0000FF;">)+</span><span style="color: #7060A8;">abs</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b1</span><span style="color: #0000FF;">-</span><span style="color: #000000;">b2</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">100</span><span style="color: #0000FF;">*</span><span style="color: #000000;">diff</span><span style="color: #0000FF;">/(</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">img1</span><span style="color: #0000FF;">)*</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">img1</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]))/</span><span style="color: #000000;">3</span><span style="color: #0000FF;">/</span><span style="color: #000000;">255</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">img1</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">read_ppm</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Lenna50.ppm"</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">img2</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">read_ppm</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Lenna100.ppm"</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">percentage_diff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">img1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">img2</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">wait_key</span><span style="color: #0000FF;">()</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
1.625593098
</pre>
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(call "convert" "Lenna50.jpg" (tmp "Lenna50.ppm"))
(call "convert" "Lenna100.jpg" (tmp "Lenna100.ppm"))
 
Line 489 ⟶ 1,271:
255 ) )
(inc 'Total) ) ) )
(prinl "Difference is " (format (*/ Diff Total) 4) " percent") )</langsyntaxhighlight>
Output:
<pre>Difference is 1.6256 percent</pre>
 
=={{header|PureBasic}}==
This program downloads both jpg files, decodes them & saves them in 2D-arrays for simple comparison which part is comparable with the other languages.
<langsyntaxhighlight PureBasiclang="purebasic">#URL1="http://rosettacode.org/mw/images/3/3c/Lenna50.jpg"
#URL2="http://rosettacode.org/mw/images/b/b6/Lenna100.jpg"
Line 545 ⟶ 1,328:
Next x
MessageRequester("Result","Diff= "+StrD(100*totalDiff/(255*w*h*3),3)+" %")</langsyntaxhighlight>
 
=={{header|Python}}==
You must install the [httphttps://wwwpillow.pythonwarereadthedocs.com/products/pilio/ Python Imaging Library] to use this example. [https://pypi.org/project/Pillow/ Install with pip] : pip install Pillow
 
{{works with|python version 3.x}}
<syntaxhighlight lang="python">from PIL import Image
 
i1 = Image.open("image1.jpg")
i2 = Image.open("image2.jpg")
assert i1.mode == i2.mode, "Different kinds of images."
assert i1.size == i2.size, "Different sizes."
 
pairs = zip(i1.getdata(), i2.getdata())
if len(i1.getbands()) == 1:
# for gray-scale jpegs
dif = sum(abs(p1-p2) for p1,p2 in pairs)
else:
dif = sum(abs(c1-c2) for p1,p2 in pairs for c1,c2 in zip(p1,p2))
 
ncomponents = i1.size[0] * i1.size[1] * 3
print ("Difference (percentage):", (dif / 255.0 * 100) / ncomponents)</syntaxhighlight>
 
{{works with|python version 2.x}}
<langsyntaxhighlight lang="python">from itertools import izip
import Image
 
Line 566 ⟶ 1,368:
 
ncomponents = i1.size[0] * i1.size[1] * 3
print "Difference (percentage):", (dif / 255.0 * 100) / ncomponents</langsyntaxhighlight>
 
=={{header|Racket}}==
For some reason, the result is around 1.77% and I can't wrap my head about why. (Tom)
Note: On OS X I get 1.6192% as the result. (soegaard)
 
<syntaxhighlight lang="racket">#lang racket
(require racket/draw)
 
(define (percentage-difference bitmap1 bitmap2)
(define width (send bitmap1 get-width))
(define height (send bitmap1 get-height))
(define buffer1 (make-bytes (* width height 4)))
(define buffer2 (make-bytes (* width height 4)))
(send (send bitmap1 make-dc) get-argb-pixels 0 0 width height buffer1)
(send (send bitmap2 make-dc) get-argb-pixels 0 0 width height buffer2)
(/ (* 100.0
(for/fold ((difference 0))
((i (in-naturals)) (x1 (in-bytes buffer1)) (x2 (in-bytes buffer2)))
(if (zero? (remainder i 4))
difference
(+ difference (abs (- x1 x2))))))
width height 3 256))
 
(define lenna50 (read-bitmap "lenna50.jpg"))
(define lenna100 (read-bitmap "lenna100.jpg"))
 
(percentage-difference lenna50 lenna100) ;-> 1.7749329408009846</syntaxhighlight>
 
=={{header|Raku}}==
(formerly Perl 6)
 
Using [https://modules.raku.org/search/?q=GD%3A%3ARaw GD::Raw from the Raku ecosystem].
<syntaxhighlight lang="raku" line>use GD::Raw;
 
my $fh1 = fopen('./Lenna50.jpg', "rb") or die;
my $img1 = gdImageCreateFromJpeg($fh1);
my $fh2 = fopen('./Lenna100.jpg', "rb") or die;
my $img2 = gdImageCreateFromJpeg($fh2);
 
my $img1X = gdImageSX($img1);
my $img1Y = gdImageSY($img1);
my $img2X = gdImageSX($img2);
my $img2Y = gdImageSY($img2);
 
($img1X == $img2X and $img1Y == $img2Y) or die "Image dimensions must match.";
 
my $diff = 0;
my ($px1, $px2);
loop (my $i = 0; $i < $img1X; $i++) {
loop (my $j = 0; $j < $img1Y; $j++) {
 
$px1 = gdImageGetPixel($img1, $i, $j);
$px2 = gdImageGetPixel($img2, $i, $j);
 
$diff += abs(gdImageRed($img1, $px1) - gdImageRed($img2, $px2));
$diff += abs(gdImageGreen($img1, $px1) - gdImageGreen($img2, $px2));
$diff += abs(gdImageBlue($img1, $px1) - gdImageBlue($img2, $px2));
}
}
 
say "%difference = ", $diff/($img1X*$img1Y*3*255)*100;
 
gdImageDestroy($img1);
gdImageDestroy($img2);
</syntaxhighlight>
{{out}}
<pre>
%difference = 1.625593098
</pre>
 
=={{header|REBOL}}==
<langsyntaxhighlight REBOLlang="rebol">REBOL [
Title: "Percent Image Difference"
Author: oofoe
Date: 2009-12-31
URL: http://rosettacode.org/wiki/Percentage_of_difference_between_2_images
]
Line 620 ⟶ 1,489:
button "b" #"b" [flip 'b]
button "difference" #"d" [flip 'diff]
]</langsyntaxhighlight>
 
Output:
Line 632 ⟶ 1,501:
=={{header|Ruby}}==
uses the <code>[[Raster graphics operations/Ruby|raster_graphics]]</code> library
<langsyntaxhighlight lang="ruby">require 'raster_graphics'
 
class RGBColour
Line 658 ⟶ 1,527:
lenna100 = Pixmap.open_from_jpeg('Lenna100.jpg')
 
puts "difference: %.5f%%" % (100.0 * (lenna50 - lenna100))</langsyntaxhighlight>
 
produces:
<pre>difference: 1.62559%</pre>
 
=={{header|Rust}}==
<syntaxhighlight lang="rust">extern crate image;
 
use image::{GenericImageView, Rgba};
 
fn diff_rgba3(rgba1 : Rgba<u8>, rgba2 : Rgba<u8>) -> i32 {
(rgba1[0] as i32 - rgba2[0] as i32).abs()
+ (rgba1[1] as i32 - rgba2[1] as i32).abs()
+ (rgba1[2] as i32 - rgba2[2] as i32).abs()
}
 
fn main() {
let img1 = image::open("Lenna100.jpg").unwrap();
let img2 = image::open("Lenna50.jpg").unwrap();
let mut accum = 0;
let zipper = img1.pixels().zip(img2.pixels());
for (pixel1, pixel2) in zipper {
accum += diff_rgba3(pixel1.2, pixel2.2);
}
println!("Percent difference {}", accum as f64 * 100.0/ (255.0 * 3.0 * (img1.width() * img1.height()) as f64));
}</syntaxhighlight>
 
produces:
<pre>Percent difference 1.6260633281632966</pre>
 
=={{header|Sidef}}==
<syntaxhighlight lang="ruby">require('Imager')
 
func img_diff(a, b) {
 
func from_file(name) {
%s|Imager|.new(file => name)
}
 
func size(img) {
(img.getwidth, img.getheight)
}
 
func pixel_diff(p1, p2) {
[p1.rgba] »-« [p2.rgba] -> map { .abs }.sum
}
 
func read_pixel(img, x, y) {
img.getpixel(x => x, y => y)
}
 
var(img1, img2) = (from_file(a), from_file(b))
 
var(w1, h1) = size(img1)
var(w2, h2) = size(img2)
 
if ((w1 != w2) || (h1 != h2)) {
return nil
}
 
var sum = 0
for y,x in (^h1 ~X ^w1) {
sum += pixel_diff(read_pixel(img1, x, y), read_pixel(img2, x, y))
}
 
sum / (w1 * h1 * 255 * 3)
}
 
say 100*img_diff('Lenna50.jpg', 'Lenna100.jpg')</syntaxhighlight>
{{out}}
<pre>
1.62559309816048815359477124183007
</pre>
 
=={{header|Swift}}==
<syntaxhighlight lang="swift">func pixelValues(fromCGImage imageRef: CGImage?) -> [UInt8]?
{
var width = 0
var height = 0
var pixelValues: [UInt8]?
if let imageRef = imageRef {
width = imageRef.width
height = imageRef.height
let bitsPerComponent = imageRef.bitsPerComponent
let bytesPerRow = imageRef.bytesPerRow
let totalBytes = height * bytesPerRow
let bitmapInfo = imageRef.bitmapInfo
let colorSpace = CGColorSpaceCreateDeviceRGB()
var intensities = [UInt8](repeating: 0, count: totalBytes)
let contextRef = CGContext(data: &intensities,
width: width,
height: height,
bitsPerComponent: bitsPerComponent,
bytesPerRow: bytesPerRow,
space: colorSpace,
bitmapInfo: bitmapInfo.rawValue)
contextRef?.draw(imageRef, in: CGRect(x: 0.0, y: 0.0, width: CGFloat(width), height: CGFloat(height)))
pixelValues = intensities
}
return pixelValues
}
 
func compareImages(image1: UIImage, image2: UIImage) -> Double? {
guard let data1 = pixelValues(fromCGImage: image1.cgImage),
let data2 = pixelValues(fromCGImage: image2.cgImage),
data1.count == data2.count else {
return nil
}
let width = Double(image1.size.width)
let height = Double(image1.size.height)
return zip(data1, data2)
.enumerated()
.reduce(0.0) {
$1.offset % 4 == 3 ? $0 : $0 + abs(Double($1.element.0) - Double($1.element.1))
}
* 100 / (width * height * 3.0) / 255.0
}
 
let image1 = UIImage(named: "Lenna50")
let image2 = UIImage(named: "Lenna100")
 
compareImages(image1: image1, image2: image2)
 
</syntaxhighlight>
 
=={{header|Tcl}}==
{{libheader|Tk}}
This version uses the '''Img''' package, but only to provide a convenient JPEG loader; it's utterly unnecessary for the process of actually computing the difference.
<langsyntaxhighlight lang="tcl">package require Tk
 
proc imageDifference {img1 img2} {
Line 691 ⟶ 1,687:
image create photo lenna100 -file lenna100.jpg
puts "difference is [expr {[imageDifference lenna50 lenna100]*100.}]%"
exit ;# Need explicit exit here; don't want a GUI</langsyntaxhighlight>
It produces this output:
difference is 1.6255930981604882%
Line 698 ⟶ 1,694:
This implementation compares two BMP images.
 
<langsyntaxhighlight lang="vedit">Chdir("|(USER_MACRO)\Rosetta\data")
File_Open("Lenna50.bmp", BROWSE)
#10 = Buf_Num // #10 = buffer for 1st image
Line 727 ⟶ 1,723:
 
Buf_Switch(#10) Buf_Quit(OK)
Buf_Switch(#20) Buf_Quit(OK)</langsyntaxhighlight>
 
Output, when comparing the Lenna images that were converted to BMP:
Line 736 ⟶ 1,732:
</pre>
 
=={{header|Wren}}==
{{trans|Kotlin}}
{{libheader|DOME}}
<syntaxhighlight lang="wren">import "graphics" for Canvas, Color, ImageData
import "dome" for Window
 
class PercentageDifference {
construct new(width, height, image1, image2) {
Window.title = "Perecentage difference between images"
Window.resize(width, height)
Canvas.resize(width, height)
_img1 = ImageData.loadFromFile(image1)
_img2 = ImageData.loadFromFile(image2)
// display images side by side
_img1.draw(0, 0)
_img2.draw(550, 0)
Canvas.print(image1, 200, 525, Color.white)
Canvas.print(image2, 750, 525, Color.white)
}
 
init() {
var dpc = (getDifferencePercent(_img1, _img2) * 1e5).round / 1e5
System.print("Percentage difference between images: %(dpc)\%")
}
 
getDifferencePercent(img1, img2) {
var width = img1.width
var height = img1.height
var width2 = img2.width
var height2 = img2.height
if (width != width2 || height != height2) {
var f = "(%(width), %(height)) vs. (%(width2), %(height2))"
Fiber.abort("Images must have the same dimensions: %(f)")
}
var diff = 0
for (y in 0...height) {
for (x in 0...width) {
diff = diff + pixelDiff(img1.pget(x, y), img2.pget(x, y))
}
}
var maxDiff = 3 * 255 * width * height
return 100 * diff / maxDiff
}
 
pixelDiff(c1, c2) { (c1.r - c2.r).abs + (c1.g - c2.g).abs + (c1.b - c2.b).abs }
 
update() {}
 
draw(alpha) {}
}
 
var Game = PercentageDifference.new(1100, 550, "Lenna50.jpg", "Lenna100.jpg")</syntaxhighlight>
 
{{out}}
<pre>
Percentage difference between images: 1.62607%
</pre>
 
=={{header|zkl}}==
Uses the PPM class from http://rosettacode.org/wiki/Bitmap/Bresenham%27s_line_algorithm#zkl
<syntaxhighlight lang="zkl">fcn imageDiff(img1,img2){
if(img1.w!=img2.w or img1.h!=img2.h)
throw(Exception.ValueError("width/height of the images must match!"));
img1.data.howza(0).walker().zip(img2.data.howza(0)) // lazy bytes, not strings
.reduce(fcn(totalDiff,[(a,b)]){ totalDiff + (a - b).abs() },0)
.toFloat()/img1.w/img1.h/3/255; // or: .toFloat()/img1.data.len()/255
}</syntaxhighlight>
Take the bytes in each image, zip them together [lazily], sum the differences between each byte and normalize.
<syntaxhighlight lang="zkl">fcn readJPG2PPM(fileName){
p:=System.popen("convert \"%s\" ppm:-".fmt(fileName),"r");
img:=PPM.readPPM(p);
p.close();
img
}</syntaxhighlight>
Use the convert utility from ImageMagick to convert a JPEG image to PPM.
<syntaxhighlight lang="zkl">imageDiff(readJPG2PPM("lenna50.jpg"),readJPG2PPM("lenna100.jpg")) :
"Image difference = %f%%".fmt(_*100).println();</syntaxhighlight>
Compute the diff between the two Lennas, format and print it. More conventionally, this would be written as
<syntaxhighlight lang="zkl">println("Image difference = %f%%".fmt(
imageDiff(readJPG2PPM("lenna50.jpg"),readJPG2PPM("lenna100.jpg")) * 100)
);</syntaxhighlight>
{{out}}
<pre>
512 512 # verbiage from convert
512 512
Image difference = 1.624730%
</pre>
 
{{omit from|AWK}}
{{omit from|GUISS}}
{{omit from|Lotus 123 Macro Scripting}}
{{omit from|PARI/GP}}
6

edits