Qiang Blog

Just another zhangjingqiang's blog.

How to bulk compare images by imagemagick with python and ruby?

If we want to compare all images in two different path, we can save them into two files and bulk compare them by batch script.

For example:

# old
1.png
2.png
# new
1.png
2.png( - Different image)

Then run the python or ruby script:

#!/usr/bin/python
# coding: UTF-8

import os
import sys
import subprocess
from termcolor import colored

reload(sys)
sys.setdefaultencoding('utf8')

def main():
    if len(sys.argv) == 3 and os.path.isfile(sys.argv[1]) and os.path.isfile(sys.argv[2]):
        compare()
    else:
        print 'Please input regular files'

def compare():
    list1 = [line.rstrip() for line in open(sys.argv[1])]
    list2 = [line.rstrip() for line in open(sys.argv[2])]
    for i in range(len(list1)):
        os.system("composite -compose difference {0} {1} {2}".format(list1[i], list2[i], '/tmp/diff.png'))
        pipe = subprocess.Popen("identify -format %[mean] {0}".format('/tmp/diff.png'), shell=True, stdout=subprocess.PIPE).stdout
        value = pipe.read()
        if float(value) > 0:
            os.system("cp /tmp/diff.png {0}".format(str(i) + '.png'))
            print colored("{0}{1} Diff - {2}".format('[' + str(i) + ']', float(value), list2[i]), 'red')
        else:
            print colored("{0}{1} Same - {2}".format('[' + str(i) + ']', value, list2[i]), 'green')

if __name__ == "__main__":
    print 'Compare by python:'
    main()
#!/usr/bin/ruby

require 'colorize'

class CompareImages
  def initialize()
    puts "Compare by ruby:"
  end

  def read_put
    list1 = File.readlines(ARGV[0]).map{|x| x.strip}
    list2 = File.readlines(ARGV[1]).map{|x| x.strip}
    (0..list1.length - 1).each do |i|
      `composite -compose difference #{list1[i]} #{list2[i]} /tmp/diff.png`
      value = `identify -format %[mean] /tmp/diff.png`
      if value.to_i > 0
        `cp /tmp/diff.png #{i}.png`
        puts "[#{i}]#{value} Diff - #{list2[i]}".red
      else
        puts "[#{i}]#{value} Same - #{list2[i]}".green
      end
    end
  end
end

ci = CompareImages.new
ci.read_put
$ python ci.py old new
$ ruby ci.rb old new

It can also output the messages with color in the terminal!

imagemagick python ruby