El valor de color RGB #00FF00
es bastante importante: se utiliza para hacer películas, programas de televisión, anuncios meteorológicos y más. Es el famoso color "TV verde" o "pantalla verde".
El reto
Su tarea es escribir un programa que tome dos imágenes de entrada, tanto en formato PNG (o en el tipo de objeto de imagen de su biblioteca de imágenes) como de las mismas dimensiones. Una imagen puede ser cualquier imagen antigua. La otra es la imagen que tendrá un fondo del color #00FF00
. La imagen de salida consistirá en la segunda imagen superpuesta sobre la primera, sin #00FF00
color presente (excepto en la primera imagen). La entrada y la salida se pueden hacer con archivos, una GUI, etc. Se le permite tomar una matriz de valores RGB como entrada, como se ve aquí . Puede suponer que una imagen solo tiene píxeles de opacidad total.
Básicamente...
Haga un programa que tome cada #00FF00
píxel en una imagen y reemplácelo con el píxel correspondiente en la imagen de fondo.
Casos de prueba
Proporcionado generosamente por @dzaima: Fondo:
Primer plano:
Salida:
Por supuesto, las lagunas estándar están estrictamente prohibidas . Esto incluye el uso de un recurso en línea para hacerlo por usted.
Este es el código de golf , por lo que puede ganar el código más corto y prosperar el mejor programador ...
fuente
Respuestas:
Código de máquina x86-64 (y x86-32),
131513 bytesregistro de cambios:
Corrección de errores: la primera versión solo verificaba G = 0xff, no requería que R y B fueran 0. Cambié a modificar el fondo en su lugar para poder usar
lodsd
en primer plano para tener píxeles fgeax
para lacmp eax, imm32
codificación de forma corta (5 bytes ), en lugar decmp dh,0xff
(3 bytes).Guardar 2 bytes: noté que modificar el bg en su lugar permitía usar un operando de memoria para
cmov
, guardar unamov
carga de 2 bytes (y guardar un registro, en caso de que sea importante).Esta es una función que sigue la convención de llamadas del Sistema V x86-64, que se puede llamar directamente desde C o C ++ (en sistemas x86-64 que no son Windows) con esta firma:
El formato de imagen es RGB0 32bpp, con el componente verde en la segunda dirección de memoria más baja dentro de cada píxel. La imagen de fondo en
primerplano se modifica in situ.pixel_count
es filas * columnas. No le importan las filas / columnas; solo combina chromekey sin importar la cantidad de palabras de memoria que especifique.RGBA (con A requerido para ser 0xFF) requeriría el uso de una constante diferente, pero ningún cambio en el tamaño de la función. Las DWORD en primer plano se comparan para una igualdad exacta frente a una constante arbitraria de 32 bits almacenada en 4 bytes, por lo que cualquier orden de píxeles o color de clave de croma puede ser fácilmente compatible.
El mismo código de máquina también funciona en modo de 32 bits. Para ensamblar como 32 bits, cambie
rdi
aedi
en la fuente. Todos los demás registros que se convierten en 64 bits son implícitos (lodsd / stosd y loop), y los otros registros explícitos permanecen en 32 bits. Pero tenga en cuenta que necesitará un contenedor para llamar desde C de 32 bits, porque ninguna de las convenciones de llamadas estándar x86-32 usa los mismos registros que SysV x86-64.Listado NASM (código de máquina + fuente), comentado para principiantes de ASM con descripciones de lo que hacen las instrucciones más complejas. (Duplicar el manual de referencia de instrucciones es un mal estilo en uso normal).
Para obtener la fuente NASM original de esta lista, elimine los 26 caracteres principales de cada línea con
<chromakey.lst cut -b 26- > chromakey.asm
. Generé esto connasm -felf64 chromakey-blend.asm -l /dev/stdout | cut -b -28,$((28+12))-
listados NASM, dejando más columnas en blanco de las que quiero entre el código de máquina y la fuente. Para crear un archivo de objeto que pueda vincular con C o C ++, usenasm -felf64 chromakey.asm
. (Oyasm -felf64 chromakey.asm
)no probado , pero estoy bastante seguro de que la idea básica de load / load / cmov / store es sólida, porque es muy simple.
Podría ahorrar 3 bytes si pudiera requerir que la persona que llama pase la constante de clave de croma (0x00ff00) como un argumento adicional, en lugar de codificar la constante en la función. No creo que las reglas habituales permitan escribir una función más genérica que tenga las llamadas configuradas constantes para ello. Pero si lo hizo, el tercer argumento (actualmente
dummy
) se pasaedx
en el x86-64 SysV ABI. Simplemente cambiecmp eax, 0x0000ff00
(5B) acmp eax, edx
(2B).Con SSE4 o AVX, puede hacerlo más rápido (pero con un tamaño de código más grande) con
pcmpeqd
yblendvps
para hacer una combinación variable de tamaño de elemento de 32 bits controlada por la máscara de comparación. (Conpand
, podrías ignorar el byte alto). Para RGB24 empaquetado, puede usarpcmpeqb
y luego 2xpshufb
+pand
para obtener VERDADERO en bytes donde coinciden los 3 componentes de ese píxelpblendvb
.(Sé que esto es código-golf, pero consideré probar MMX antes de usar un entero escalar).
fuente
nasm -felf32
. (Para 32 bits, también necesitará una función de contenedor para llamar desde C, porque todavía está utilizando los mismos registros que el x86-64 SysV ABI.)Mathematica
5735 bytesactualización: de forma predeterminada, se elimina un fondo verde con
RemoveBackground
. La primera presentación incluyó el segundo parámetro innecesario, `{" Fondo ", Verde}".Elimina el fondo de la imagen 2 y compone el resultado con la imagen 1.
Ejemplo
Lo siguiente, en forma de prefijo en lugar de infijo, muestra más claramente cómo funciona el código.
fuente
Python 3 + numpy , 59 bytes
Pruébalo en línea!
La entrada se da en el formato de una
numpy
matriz, con tripletes enteros que representan píxeles (donde el#00FF00
código de color hexadecimal es equivalente a[0, 255, 0]
). La matriz de entrada se modifica en su lugar, lo que está permitido por meta .Imágenes de ejemplo
Entrada (de la pregunta)
Fondo:
Primer plano:
Imagen de primer plano después de ejecutar la función:
Implementación de referencia (se usa
opencv
para leer archivos de imagen)Muestra la imagen en la pantalla y la escribe en un archivo de salida.
fuente
lambda f,b:[x[list(x[0])==[0,255,0]]for x in zip(f,b)]
. Si la lista de listas de enteros también es realmente aceptable, entonces podría hacerlo en 48 conlambda f,b:[x[x[0]==[0,255,0]]for x in zip(f,b)]
G == 255
, el valor se reemplaza incluso si R y B no son cero, lo que conduce a los puntos rojos. Esto también sucede para las otras bandas incluso duras que son menos visibles. Por lo tanto, realiza las verificaciones lógicas de forma independiente y cambia canales individuales incluso si solo se cumple una de las condiciones. Por ejemplo, si un píxel es,[0 255 37]
las bandas rojas y verdes serán reemplazadas.Procesamiento,
11699 bytesDesafortunadamente, el procesamiento no admite cosas de Java 8, como lambdas.
Implementación de ejemplo: (guarda la imagen como
out.png
y también la dibuja en la pantalla)fuente
settings()
y lassetup()
funciones y basta con ejecutar el código directamente.#ff00
o0xff00
lo mismo que#00ff00
en el procesamiento?0x0000FF00
es el patrón de bits que estás buscando?Bash + ImageMagick, 45 bytes
Toma dos imágenes como argumentos y muestra la salida en la pantalla. Cambie
x:
a$3
para escribir en un tercer argumento de archivo en su lugar. El método es simple: lea la imagen de "fondo"; lea la imagen "en primer plano"; reinterprete el color "lima" (# 00ff00) como transparencia en la segunda imagen; luego componga la segunda imagen en la primera y envíela.ImageMagick: 28 bytes?
Podría haber enviado esto como una respuesta de ImageMagick, pero no está claro cómo lidiar con los argumentos. Si desea plantear que ImageMagick es un lenguaje basado en la pila (que es algo así como cierto, pero casi ... es extraño), entonces
-transparent lime -composite
es una función que espera dos imágenes en la pila y deja una imagen fusionada en la pila. tal vez eso es lo suficientemente bueno como para contar?fuente
MATL ,
403731 bytesEjemplo ejecutado con el intérprete fuera de línea. Las imágenes son ingresadas por sus URL (también se pueden proporcionar nombres de archivos locales).
Explicación
fuente
Pyth , 27 bytes
Se necesita entrada citada. La entrada son las dos rutas de los archivos de imagen. Salida de un archivo
o.png
Desafortunadamente, no se puede probar en el intérprete en línea por razones de seguridad ('
está deshabilitado en él). Necesitarás tener Pyth en tu computadora para probarlo.Explicación
fuente
Matlab 2016b y Octave,
6259 bytesEntrada: A = matriz de primer plano de la unidad8 MxNx3, B = matriz de fondo de la unidad8 MxNx3.
Salida: A = MxNx3 unit8 matrix
Uso de la muestra:
fuente
C ++, 339 bytes
Esto usa CImg, y también puede tomar archivos en otros formatos. El resultado se muestra en una ventana.
Compilar con
g++ chromakey.cpp -g -L/usr/lib/i386-linux-gnu -lX11 -o chromakey -pthread
.fuente
R, 135 bytes
Función anónima, toma 2 rutas de archivos png como argumentos y genera una imagen png llamada
a.png
.Ligeramente no golfista, con explicaciones:
fuente
SmileBASIC, 90 bytes, ¿cuál es la clave?
I
es el primer plano y la salida,J
es el fondo. Ambos son conjuntos enteros de píxeles, en formato ARGB de 32 bits.Sin golf
Explicación:
ARYOP es una función que aplica una operación simple a cada elemento de una matriz.
Se llama como
ARYOP mode, output_array, input_array_1, input_array_2, ...
Primero, para determinar qué píxeles en la imagen son verdes,
-16711936
(la representación RGBA del color verde) se resta de cada píxel en la imagen en primer plano. Esto proporciona una matriz donde0
representa píxeles verdes, y cualquier otro número representa píxeles no verdes.Para convertir todos los valores distintos de cero a
1
, que se elevan al cuadrado (para eliminar los números negativos), entonces sujeta a entre0
y1
.Esto da como resultado una matriz con solo
0
sy1
s.0
s representan píxeles verdes en la imagen de primer plano y deben reemplazarse con píxeles del fondo.1
s representan píxeles no verdes, y estos deberán ser reemplazados por píxeles del primer plano.Esto se puede hacer fácilmente usando interpolación lineal.
fuente
PHP, 187 bytes
asume archivos PNG de 24 bits; toma nombres de archivos de argumentos de líneas de comando, escribe en stdout.
Corre con
-r
.Descompostura
fuente
JavaScript (ES6), 290 bytes
Toma la entrada como dos
Image
objetos (en sintaxis curry), que se pueden crear con un<image>
elemento HTML . Devuelve una promesa que se resuelve en la URL de datos Base64 de la imagen resultante, que se puede aplicar a lasrc
de un<image>
.La idea aquí era establecer el valor alfa para cada
#00FF00
píxel0
y luego pintar el primer plano, con su fondo borrado, encima del fondo.Fragmento de prueba
Incluir el primer plano y el fondo por sus URL de datos era demasiado grande para publicarlo aquí, por lo que se movió a CodePen:
Pruébalo en línea!
fuente
OSL , 83 bytes
Toma dos entradas. El primero es el primer plano, y el segundo, el fondo.
fuente