image_difference.sf 1.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. #!/usr/bin/ruby
  2. #
  3. ## https://rosettacode.org/wiki/Percentage_difference_between_images
  4. #
  5. require('Imager')
  6. func img_diff(a, b) {
  7. func from_file(name) {
  8. %O<Imager>.new(file => name)
  9. }
  10. func size(img) {
  11. (img.getwidth, img.getheight)
  12. }
  13. func pixel_diff(p1, p2) {
  14. [p1.rgba] »-« [p2.rgba] -> sum_by { .abs }
  15. }
  16. func read_pixel(img, x, y) {
  17. img.getpixel(x => x, y => y)
  18. }
  19. func read_line(img, y) {
  20. img.getscanline(y => y)
  21. }
  22. var(img1, img2) = (from_file(a), from_file(b))
  23. var(w1, h1) = size(img1)
  24. var(w2, h2) = size(img2)
  25. if ((w1 != w2) || (h1 != h2)) {
  26. return nil
  27. }
  28. var sum = 0
  29. for y in (^h1) {
  30. var *line1 = read_line(img1, y)
  31. var *line2 = read_line(img2, y)
  32. [line1, line2].zip {|p1, p2|
  33. sum += pixel_diff(p1, p2)
  34. }
  35. }
  36. sum / (w1 * h1 * 255 * 3)
  37. }
  38. if (ARGV.len != 2) {
  39. say "usage: #{File(__MAIN__).basename} [img1] [img2]"
  40. Sys.exit(1)
  41. }
  42. say 100*img_diff(ARGV[0], ARGV[1])