рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЖрдкрдиреЗ рдирдИ
рдЫрд╡рд┐ рджреЗрдЦрдиреЗ рдХреЗ рддрд░реАрдХреЗ рджреЗрдЦреЗ рдЬреЛ рдкрд┐рдЫрд▓реЗ рдорд╣реАрдиреЗ рдЧрд┐рдердм рдиреЗ рд▓реБрдврд╝рдХреЗред рдпрд╣ рдПрдХ рддрд╕реНрд╡реАрд░ рдХреЗ рджреЛ рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдХреЗ рдмреАрдЪ рдЕрдВрддрд░ рджрд┐рдЦрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдмрд╣реБрдд рд╕рд╛рдл рддрд░реАрдХрд╛ рд╣реИред рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ, рдореИрдВ рдпрд╣ рд╕рдордЭрд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реВрдВрдЧрд╛ рдХрд┐ рдЖрдк рдХреЗрд╡рд▓ рд░реВрдмреА рдФрд░
рдЪрдВрдХреАрдкреАрдПрдирдЬреА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЫрд╡рд┐рдпреЛрдВ рдХреА рддреБрд▓рдирд╛ рдХреИрд╕реЗ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рд╕рдмрд╕реЗ рд╕рд░рд▓ рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ, рдЕрдВрддрд░ рдХреА рдЦреЛрдЬ рдкрд╣рд▓реА рддрд╕реНрд╡реАрд░ рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рдкрд┐рдХреНрд╕реЗрд▓ рдХреЛ рдкреАрдЫреЗ рд╣рдЯрд╛рдиреЗ рдФрд░ рдпрд╣ рдЬрд╛рдВрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдЖрддреА рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдпрд╣ рдкрд┐рдХреНрд╕реЗрд▓ рджреВрд╕рд░реЗ рдореЗрдВ рд╣реИред рдПрдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦ рд╕рдХрддрд╛ рд╣реИ:
require 'chunky_png' images = [ ChunkyPNG::Image.from_file('1.png'), ChunkyPNG::Image.from_file('2.png') ] diff = [] images.first.height.times do |y| images.first.row(y).each_with_index do |pixel, x| diff << [x,y] unless pixel == images.last[x,y] end end puts "pixels (total): #{images.first.pixels.length}" puts "pixels changed: #{diff.length}" puts "pixels changed (%): #{(diff.length.to_f / images.first.pixels.length) * 100}%" x, y = diff.map{ |xy| xy[0] }, diff.map{ |xy| xy[1] } images.last.rect(x.min, y.min, x.max, y.max, ChunkyPNG::Color.rgb(0,255,0)) images.last.save('diff.png')
рдХреЛрдб: GistрджреЛ рдЫрд╡рд┐рдпреЛрдВ рдХреЛ рд▓реЛрдб рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдо рдкрд╣рд▓реЗ рдкреНрд░рддреНрдпреЗрдХ рдкрд┐рдХреНрд╕реЗрд▓ рдХреЗ рдЪрд╛рд░реЛрдВ рдУрд░ рдЬрд╛рддреЗ рд╣реИрдВ, рдФрд░ рдпрджрд┐ рдпрд╣ рджреВрд╕рд░реЗ рдореЗрдВ рдореМрдЬреВрдж рд╣реИ, рддреЛ рдЗрд╕реЗ рдЕрд▓рдЧ рд╕рд░рдгреА рдореЗрдВ рдЬреЛрдбрд╝реЗрдВред рдЙрд╕рдХреЗ рдмрд╛рдж, рдЙрд╕ рдХреНрд╖реЗрддреНрд░ рдХреЗ рдЪрд╛рд░реЛрдВ рдУрд░ рдПрдХ рдлреНрд░реЗрдо рдмрдирд╛рдПрдВ рдЬрд┐рд╕рдореЗрдВ рдорддрднреЗрдж рд╣реИрдВ:



рдпрд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ! рдЕрдВрддрд┐рдо рдЫрд╡рд┐ рдореЗрдВ, рдЯреЛрдкреА рдХреЗ рдЪрд╛рд░реЛрдВ рдУрд░ рдПрдХ рдлреНрд░реЗрдо рд╣реИ, рдЬрд┐рд╕реЗ рд╣рдордиреЗ рдлреЛрдЯреЛ рдореЗрдВ рдЬреЛрдбрд╝рд╛ рд╣реИ рдФрд░ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рд╣рдо рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рдлреЛрдЯреЛ рдореЗрдВ рд▓рдЧрднрдЧ 9% рдкрд┐рдХреНрд╕рд▓ рдиреЗ рдЕрдкрдирд╛ рдореВрд▓реНрдп рдмрджрд▓ рджрд┐рдпрд╛ рд╣реИред
pixels (total): 16900
pixels changed: 1502
pixels changed (%): 8.887573964497042%
рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЗ рд╕рд╛рде рд╕рдорд╕реНрдпрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдпрд╣ рдХреЗрд╡рд▓ рдЙрдиреНрд╣реЗрдВ
рдорд╛рдкрдиреЗ рдХреЗ рдмрд┐рдирд╛ рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреА
рдкрд╣рдЪрд╛рди рдХрд░рддрд╛ рд╣реИред рдХреЛрдИ рдЕрдВрддрд░ рдирд╣реАрдВ рд╣реИ, рдкрд┐рдХреНрд╕реЗрд▓ рдХреЗрд╡рд▓ рдереЛрдбрд╝рд╛ рдЧрд╣рд░рд╛ рд╣реЛ рдЧрдпрд╛ рд╣реИ, рдпрд╛ рдЗрд╕рдХрд╛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЕрд▓рдЧ рд░рдВрдЧ рд╣реИред рдпрджрд┐ рд╣рдо рдЗрд╕ рдХреЛрдб рдХреЛ рдлрд╝реЛрдЯреЛ рдХреЗ рдереЛрдбрд╝реЗ рдХрд╛рд▓реЗ рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдкрд░рд┐рдгрд╛рдо рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрд╛рдИ рджреЗрдЧрд╛:



pixels (total): 16900
pixels changed: 16900
pixels changed (%): 100.0%
рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рд╣реИ рдХрд┐ рджреЛ рддрд╕реНрд╡реАрд░реЗрдВ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЕрд▓рдЧ рд╣реИрдВ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдЖрдВрдЦ рд╕реЗ рд╡реЗ рд▓рдЧрднрдЧ рд╕рдорд╛рди рд╣реИрдВред рдЕрдзрд┐рдХ рд╕рдЯреАрдХ рдкрд░рд┐рдгрд╛рдо рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдкрд┐рдХреНрд╕реЗрд▓ рдореВрд▓реНрдпреЛрдВ рдХреЗ рдмреАрдЪ рдЕрдВрддрд░ рдХреЛ рдорд╛рдкрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
рд░рдВрдЧ рдЕрдВрддрд░ рдХреА рдЧрдгрдирд╛
рд░рдВрдЧ рдореЗрдВ рдЕрдВрддрд░ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдореАрдЯреНрд░рд┐рдХ (E
* ("рдбреЗрд▓реНрдЯрд╛ рдИ") рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред рдЗрд╕ рдореАрдЯреНрд░рд┐рдХ рдХреЗ рд▓рд┐рдП рддреАрди рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╕реВрддреНрд░ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╣рдо рдкрд╣рд▓реЗ рдПрдХ (
CIE76 ) рдХреЛ
рд▓реЗрдВрдЧреЗ , рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рд╕рдмрд╕реЗ рд╕рд░рд▓ рд╣реИ, рдФрд░ рд╣рдореЗрдВ рдХреБрдЫ рдЧрд░реНрднрдкрд╛рдд рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред ColorE * рдореАрдЯреНрд░рд┐рдХ рд▓рдм
рд░рдВрдЧ рдЕрдВрддрд░рд┐рдХреНрд╖ рдХреЗ рд▓рд┐рдП рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рдерд╛, рдЬреЛ рдорд╛рдирд╡ рджреГрд╖реНрдЯрд┐ рдХреЗ рд╕рд╛рде рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рд╕реБрд╕рдВрдЧрдд рд╣реИред рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рд╣рдо рд░рдВрдЧреЛрдВ рдХреЛ LAB рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗ, рд▓реЗрдХрд┐рди рдмрд╕ RGB рд░рдВрдЧ рд╕реНрдерд╛рди рдореЗрдВ рдХрд╛рдо рдХрд░реЗрдВ (рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдЗрд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд░рд┐рдгрд╛рдо рдЗрддрдиреЗ рд╕рдЯреАрдХ рдирд╣реАрдВ рд╣реЛрдВрдЧреЗ)ред рдпрджрд┐ рдЖрдк рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдЙрддреНрд╕реБрдХ рд╣реИрдВ рдХрд┐ рд╡рд┐рднрд┐рдиреНрди рд░рдВрдЧ рд╕реНрдерд╛рди рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╣реИрдВ, рддреЛ
рдЗрд╕ рдбреЗрдореЛ рдХреЛ рджреЗрдЦреЗрдВ ред
рдкрд╣рд▓реЗ рдХреА рддрд░рд╣, рд╣рдо рдЫрд╡рд┐рдпреЛрдВ рдореЗрдВ рд╕рднреА рдкрд┐рдХреНрд╕реЗрд▓ рд╕реЗ рдЧреБрдЬрд░реЗрдВрдЧреЗред рдпрджрд┐ рд╡реЗ рдЕрд▓рдЧ рд╣реИрдВ, рддреЛ рд╣рдо рдореАрдЯреНрд░рд┐рдХ metE * рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдкрд░рд┐рдгрд╛рдо рдХреЛ рдЕрд▓рдЧ рд╕рд░рдгреА рдореЗрдВ рд╕рд╣реЗрдЬрддреЗ рд╣реИрдВред рд╣рдо рдЗрд╕ рдкрд░рд┐рдгрд╛рдо рдХреЛ рдЧреНрд░реЗ рдореВрд▓реНрдп рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рднреА рд▓рд╛рдЧреВ рдХрд░реЗрдВрдЧреЗ рдЬреЛ рдЕрдВрддрд┐рдо рддреБрд▓рдирд╛рддреНрдордХ рдЪрд┐рддреНрд░ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
require 'chunky_png' include ChunkyPNG::Color images = [ ChunkyPNG::Image.from_file('1.png'), ChunkyPNG::Image.from_file('2.png') ] output = ChunkyPNG::Image.new(images.first.width, images.last.width, WHITE) diff = [] images.first.height.times do |y| images.first.row(y).each_with_index do |pixel, x| unless pixel == images.last[x,y] score = Math.sqrt( (r(images.last[x,y]) - r(pixel)) ** 2 + (g(images.last[x,y]) - g(pixel)) ** 2 + (b(images.last[x,y]) - b(pixel)) ** 2 ) / Math.sqrt(MAX ** 2 * 3) output[x,y] = grayscale(MAX - (score * MAX).round) diff << score end end end puts "pixels (total): #{images.first.pixels.length}" puts "pixels changed: #{diff.length}" puts "image changed (%): #{(diff.inject {|sum, value| sum + value} / images.first.pixels.length) * 100}%" output.save('diff.png')
рдХреЛрдб: GistрдЕрдм рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдорддрднреЗрджреЛрдВ рдХреА рдЕрдзрд┐рдХ рд╕рдЯреАрдХ рддрд╕реНрд╡реАрд░ рд╣реИред рдпрджрд┐ рдЖрдк рдкрд░рд┐рдгрд╛рдо рдХреЛ рджреЗрдЦрддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рджреЗрдЦреЗрдВрдЧреЗ рдХрд┐ 3% рд╕реЗ рдХрдо рдлреЛрдЯреЛ рдмрджрд▓ рдЧрдпрд╛ рд╣реИред
pixels (total): 16900
pixels changed: 1502
image changed (%): 2.882157784948056%
рдлрд┐рд░, рд╣рдо рдкрд░рд┐рдгрд╛рдо рдмрдЪрд╛рддреЗ рд╣реИрдВ - рдФрд░ рдЗрд╕ рдмрд╛рд░ рдпрд╣ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЧреНрд░реЗ рдХреЗ рд░рдВрдЧреЛрдВ рдореЗрдВ рдЕрдВрддрд░ рджрд┐рдЦрд╛рддрд╛ рд╣реИред рдордЬрдмреВрдд рдмрджрд▓рд╛рд╡реЛрдВ рдореЗрдВ рдЧрд╣рд░рд╛ рд░рдВрдЧ рд╣реЛрддрд╛ рд╣реИред



рдЕрдм, рдЖрдЗрдП рдЙрди рджреЛ рдЪрд┐рддреНрд░реЛрдВ рдХреЛ рдЖрдЬрд╝рдорд╛рдПрдВ рдЬрд┐рдирдореЗрдВ рджреВрд╕рд░рд╛ рдереЛрдбрд╝рд╛ рдЧрд╣рд░рд╛ рдерд╛ред
pixels (total): 16900
pixels changed: 16900
image changed (%): 5.4418255392228945%



рдмрд╣реБрдд рдмрдврд╝рд┐рдпрд╛ред рдЕрдм рд╣рдорд╛рд░рд╛ рдХрд╛рд░реНрдпрдХреНрд░рдо рдЬрд╛рдирддрд╛ рд╣реИ рдХрд┐ рддрд╕реНрд╡реАрд░реЗрдВ рдХреЗрд╡рд▓ рдереЛрдбрд╝реА рдЕрд▓рдЧ рд╣реИрдВ, рдФрд░ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЕрд▓рдЧ рдирд╣реАрдВ рд╣реИрдВред рдпрджрд┐ рдЖрдк рдзреНрдпрд╛рди рд╕реЗ рджреЗрдЦрддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдЙрди рдЧреБрдкреНрдд рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЛ рднреА рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд╣рд╛рдБ рдЫрд╡рд┐ рдЕрд▓рдЧ рд╣реИред
рдЧреАрдереВрдм рдХреНрдпрд╛ рдХрд░рддрд╛ рд╣реИ?
рдЧрд┐рдердм
рдПрдХ рддрд╛рдирд╡рд╛рд▓рд╛ рдЕрдВрддрд░ рдореЛрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛
рд╣реИ рдЬреЛ рдлрд╝реЛрдЯреЛ рдПрдбрд┐рдЯрд░ рдЬреИрд╕реЗ рдлрд╝реЛрдЯреЛрд╢реЙрдк рд╕реЗ тАЛтАЛрдкрд░рд┐рдЪрд┐рдд рд╣реИред рдпрд╣ рдПрдХ рдХрд╛рдлреА рд╕рд░рд▓ рд╡рд┐рдзрд┐ рд╣реИред рд╣рдо рджреЛ рдЫрд╡рд┐рдпреЛрдВ рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рдкрд┐рдХреНрд╕реЗрд▓ рдХреЗ рдЖрд╕рдкрд╛рд╕ рдЬрд╛рддреЗ рд╣реИрдВ рдФрд░ RGB рдЪреИрдирд▓реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЙрдирдХреЗ рдЕрдВрддрд░ рдХреА рдЧрдгрдирд╛ рдХрд░рддреЗ рд╣реИрдВ:
require 'chunky_png' include ChunkyPNG::Color images = [ ChunkyPNG::Image.from_file('1.png'), ChunkyPNG::Image.from_file('2.png') ] images.first.height.times do |y| images.first.row(y).each_with_index do |pixel, x| images.last[x,y] = rgb( r(pixel) + r(images.last[x,y]) - 2 * [r(pixel), r(images.last[x,y])].min, g(pixel) + g(images.last[x,y]) - 2 * [g(pixel), g(images.last[x,y])].min, b(pixel) + b(images.last[x,y]) - 2 * [b(pixel), b(images.last[x,y])].min ) end end images.last.save('diff.png')
рдХреЛрдб: GistрдЗрд╕ рдкрджреНрдзрддрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП, рдмрд╛рдИрдВ рдУрд░ рджреЛ рддрд╕реНрд╡реАрд░реЛрдВ рдХреА рддреБрд▓рдирд╛ рдХрд░рдиреЗ рд╕реЗ рджрд╛рдИрдВ рдУрд░ рдХреА рдЫрд╡рд┐ рдореЗрдВ рдЕрдВрддрд░ рдХреА рдПрдХ рддрд╕реНрд╡реАрд░ рдорд┐рд▓рддреА рд╣реИ, рдЬреЛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдкрд░рд┐рд╡рд░реНрддрди рджрд┐рдЦрд╛рддреА рд╣реИ:



рдЪреВрдБрдХрд┐ рд░рдВрдЧреЛрдВ рдХреА рддреБрд▓рдирд╛ рдЪреИрдирд▓реЛрдВ (R, G, рдФрд░ B) рд╕реЗ рдХреА рдЬрд╛рддреА рд╣реИ, рдПрдХ рд╣реА рд░рдВрдЧ рдХреЗ рдмрдЬрд╛рдп, рддреАрди рдорд╛рди рд▓реМрдЯрд╛рдП рдЬрд╛рддреЗ рд╣реИрдВред рдЗрд╕рдХрд╛ рдорддрд▓рдм рдпрд╣ рд╣реИ рдХрд┐ рдкрд░рд┐рдгрд╛рдореА рддрд╕реНрд╡реАрд░ рд░рдВрдЧ рд╣реИ, рд▓реЗрдХрд┐рди рдкреНрд░рддреНрдпреЗрдХ рдЪреИрдирд▓ рдХреЗ рд▓рд┐рдП рдЕрд▓рдЧ рд╕реЗ рдЗрд╕ рддрд░рд╣ рдХреА рддреБрд▓рдирд╛ рдкрд░рд┐рдгрд╛рдо рдХреА рд╕рдЯреАрдХрддрд╛ рдкрд░ рдкреНрд░рддрд┐рдХреВрд▓ рдкреНрд░рднрд╛рд╡ рдбрд╛рд▓ рд╕рдХрддреА рд╣реИред