Oi! Existe um comando do ImageMagick para remover da imagem tudo menos a cor desejada:
convert input.jpg -fill white -fuzz 20% +opaque "#E7482C" output.jpg
É possível obter o mesmo resultado com libvips?
Olá @nattfodd , em Ruby (por exemplo) você poderia fazer algo como:
require 'vips'
image = Vips::Image.new_from_file ARGV[0], access: :sequential
# the colour we search for as an RGB triple
match = [40, 100, 90]
# find euclidean distance between each RGB pixels in the input and our match
# colour
distance = Vips::Image.sum(((image - match) ** 2).bandsplit) ** 0.5
# swap pixels more than 50 away for white
image = (distance > 50).ifthenelse([255, 255, 255], image)
image.write_to_file ARGV[1]
Isso não é mais rápido do que o seu comando de IM, mas pelo menos usa menos memória.
Ou você pode usar o dE 1976:
require 'vips'
image = Vips::Image.new_from_file ARGV[0], access: :sequential
# the colour we search for as a CIELAB coordinate
match = [40, -20, 0]
# calculate dE 1976 colour difference
distance = image.dE76(image.new_from_image(match))
# swap pixels more than 50 away for white
image = (distance > 50).ifthenelse([255, 255, 255], image)
image.write_to_file ARGV[1]
Novamente, não mais rápido do que IM, mas trabalhar em CIELAB deve fornecer resultados visualmente mais consistentes.
... o estranho image.new_from_image(match)
é necessário porque .dE()
não suporta distância (imagem, constante), apenas distância (imagem, imagem). Portanto, ele cria uma imagem constante do tamanho de image
, em seguida, calcula a diferença entre as duas imagens.
Muito obrigado, @jcupitt ! Parece que a segunda maneira faz o que eu preciso!
OK, que bom que isso ajuda!
Claro que você pode pular o sqrt na versão 1 acima:
require 'vips'
image = Vips::Image.new_from_file ARGV[0], access: :sequential
# the colour we search for as an RGB triple
match = [40, 100, 90]
# find euclidean distance between each RGB pixels in the input and our match
# colour
distance = Vips::Image.sum(((image - match) ** 2).bandsplit)
# swap pixels more than 50 away for white
image = (distance > 50 ** 2).ifthenelse([255, 255, 255], image)
image.write_to_file ARGV[1]
O que o torna um pouco mais rápido do que o IM.