Skip to main content

JRuby Image Comparison

Working on a project to validate some images and I thought this would be a good opportunity to show a simple way to compare 2 images to see if they are equal.

First we need to declare some library's. We will be using JRuby for these examples. If you want to use Java this will look simular.

require 'java'

java_import 'java.awt.event.InputEvent'
java_import 'java.awt.image.BufferedImage'
java_import 'javax.imageio.ImageIO'

Now we need to make a function that will allow us to open an image as a bufferedImage

def get_image(filename)
  file = java::io::File.new(filename)
  return ImageIO::read(file)
end

Lets start figuring out if the images are the same. A good place to start is to define a function that with tell us whether the width and height are the same. If they are equal then the images could be the same.

def compare_size(img1, img2)
  if (img1.getWidth == img2.getWidth && img1.getHeight == img2.getHeight)
    return true
  else
    return false
  end
end

Now we are cooking with grease. The compare_size function above will get the width and height of both images and compare them. If they are equal the function will return a true value. Now that we know that both the images are possibly the same size we need to validate if the images are identical. With buffered images this is not as simple as the example below.

if (img1 == img2)
  puts "Equal"
else
  puts "Not Equal"
end

Nice try!! This don't work. For a simple mundane way of checking images we need to comapre them pixel by pixel with the RGB value.

def compare_pixels(img1, img2)
  (0..img1.getWidth-1).each do |x|
    (0..img1.getHeight-1).each do |y|
      if(img1.getRGB(x, y) != img2.getRGB(x, y))
          return false
      end
    end
  end
  return true
end

Now you have a function to fully check if 2 images are the same pixel by pixel. Please note that if the images have different color profiles or use alpha color this function could still fail. We'll save that lesson for another time.

Lets string these in order to finish the simple program up.

img1 = get_image('example1.png')
img2 = get_image('example2.png')

if (compare_size(img1, img2))
  if (compare_pixels(img1, img2))
    puts "Images are Equal"
  else
    puts "Images are Different"
  end
else
  puts "Images are Not Same Size"
end

Want to download the whole script checkout Github

Comments

Popular posts from this blog

JSON Schema testing with Postman

Postman is becoming quite the popular tool for accessing and testing REST api services. One of the cool features is that you can write some Javascript tests on your responses. Built into Postman is also the Tiny Validator v4 and Cheerio. Cheerio is a small core JQuery like implementation. The problem I have is that there is no way to import a schema file from a remote place or a file. This will be about how I get around that issue.Pre-request Script var uri='http://someUrl.com'; $.get(uri + '/someFolder/schema.json', function(schema) { postman.setEnvironmentVariable('schema', JSON.stringify(schema)); }); This Pre-request script is what saves the day. There are a couple of timing issues that are present due to async processing. If you were to put this in your test script your chances of it not completing in time are very high and you would get inconsistent results. If you are familiar with JQuery the $.get should look familiar as a ajax call that d…

Mock HTTP calls with Angular and Protractor

One of the benefits using AngularJS is also using some test tools like Protractor. Protractor is a tool that was made for Angular testing. Many times when testing you will need to mock some data so that you can see if your application responds in the correct manner. Let us assume that we have the following HTML file running our application.
<!doctype html> <html ng-app="demo"> <head> <title>Hello</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular-mocks.js"></script> <script src="hello.js"></script> </head> <body> <div ng-controller="Hello"> <p>Hello <span id="gname">{{exampleResponse.name}}</span></p> </div> …

Remote API useful tricks for Docker on Mac OS X

Install SocatSocat allow you to forward ports to a variety of things. For Docker forwarding a port to the docker.sock file makes a quick way to get access to the Docker remote api. Docker also allow a way to open up that TCP port however on Mac it is temperamental and hard to usebrew install socat socat -d TCP-LISTEN:2375,reuseaddr,fork UNIX:/var/run/docker.sock & Create an IP aliasRunning Docker containers locally is a fairly common thing. Interconnectivity between containers works naturally. However, sometimes you may also want a container to connect back to the Docker Remote API. If you are constantly on the go changing networks you do not want to have to change that IP address every time. A great use case for this is running Jenkins and using docker slavessudo ifconfig lo0 alias 192.168.99.50 Remote API There are also some interesting endpoints you can use for informationcurl http://localhost:2375 curl http://localhost:2375/containers/json curl http://localhost:2375/image…