[Question]
  [
The RGB color value `#00FF00` is a rather important one: it is used to make movies, TV shows, weather announcements, and more. It is the famous "TV green" or "green screen" color.
## The Challenge
Your task is to write a program that takes two input images, both in PNG format (or in your image library's image object type) and of the same dimensions. One image can be any old image. The other one is the image that will have a background of the color `#00FF00`. The output image will consist of the second image overlaid over the first, with no `#00FF00` color present (except in the first image). Input and output may be done with files, a GUI, etc. You are allowed to take an array of RGB values as input, as seen [here](https://codegolf.stackexchange.com/a/132724/64706). You may assume that an image has only pixels of full opacity.
## Basically...
Make a program that takes every `#00FF00` pixel in one image and replace it with the corresponding pixel in the background image.
## Test Cases
Generously provided by @dzaima:
Background:  
[![my profile image](https://i.stack.imgur.com/qaraP.png)](https://i.stack.imgur.com/qaraP.png)  
Foreground:  
[![dennis](https://i.stack.imgur.com/Bc0s5.png)](https://i.stack.imgur.com/Bc0s5.png)  
Output:  
[![output](https://i.stack.imgur.com/svMKa.png)](https://i.stack.imgur.com/svMKa.png)
---
Of course, standard loopholes are *strictly forbidden*. This includes using an online resource to do it for you.  
This is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"), so may the shortest code win and the best programmer prosper...
  
[Answer]
# x86-64 (and x86-32) machine code, ~~13~~ ~~15~~ 13 bytes
changelog:
1. Bugfix: the first version was only checking G=0xff, not requiring R and B to be 0. I changed to modifying the background in place so I could use `lodsd` on the foreground to have fg pixels in `eax` for the short-form `cmp eax, imm32` encoding (5 bytes), instead of `cmp dh,0xff` (3 bytes).
2. Save 2 bytes: noticed that modifying the bg in place allowed using a memory operand for `cmov`, saving a 2-byte `mov` load (and saving a register, in case that matters).
---
This is a function following the x86-64 System V calling convention, callable directly from C or C++ (on x86-64 non-Windows systems) with this signature:
```
void chromakey_blend_RGB32(uint32_t *background /*rdi*/,
                     const uint32_t *foreground /*rsi*/,
                  int dummy, size_t pixel_count /*rcx*/);
```
**The image format is RGB0 32bpp, with the green component at the 2nd lowest memory address within each pixel.** The ~~foreground~~ background image is modified in-place. `pixel_count` is rows\*columns. It doesn't care about rows/columns; it just chromekey blends however many dwords of memory you specify.
RGBA (with A required to be 0xFF) would require using a different constant, but no change in function size. Foreground DWORDs are compared for exact equality against an arbitrary 32-bit constant stored in 4 bytes, so any pixel-order or chroma-key colour can be easily supported.
The same machine code also works in 32-bit mode. To assemble as 32-bit, change `rdi` to `edi` in the source. All other registers that become 64-bit are implicit (lodsd/stosd, and loop), and the other explicit regs stay 32-bit. But note that you'll need a wrapper to call from 32-bit C, because none of the standard x86-32 calling conventions use the same regs as x86-64 SysV.
NASM listing (machine-code + source), commented for asm beginners with descriptions of what the more complex instructions do. (Duplicating the instruction reference manual is bad style in normal usage.)
```
 1                       ;; inputs:
 2                       ;; Background image pointed to by RDI, RGB0 format  (32bpp)
 3                       ;; Foreground image pointed to by RSI, RGBA or RGBx (32bpp)
 4          machine      ;; Pixel count in RCX
 5          code         global chromakey_blend_RGB32
 6          bytes        chromakey_blend_RGB32:
 7 address               .loop:                      ;do {
 8 00000000 AD               lodsd                   ; eax=[rsi], esi+=4. load fg++
 9 00000001 3D00FF0000       cmp    eax, 0x0000ff00  ; check for chromakey
10 00000006 0F4407           cmove  eax, [rdi]       ; eax = (fg==key) ? bg : fg
11 00000009 AB               stosd                   ; [rdi]=eax, edi+=4. store into bg++
12 0000000A E2F4             loop .loop              ;} while(--rcx)
13                       
14 0000000C C3               ret
##  next byte starts at 0x0D, function length is 0xD = 13 bytes
```
To get the original NASM source out of this listing, strip the leading 26 characters of each line with `<chromakey.lst cut -b 26- > chromakey.asm`. I generated this with  
`nasm -felf64 chromakey-blend.asm -l /dev/stdout | cut -b -28,$((28+12))-`
NASM listings leave more blank columns than I want between the machine-code and source. To build an object file you can link with C or C++, use `nasm -felf64 chromakey.asm`. (Or `yasm -felf64 chromakey.asm`). To strip the addresses and line numbers as well, `cut -b16-30,41-` works well.
**untested**, but I'm pretty confident that the basic idea of load / load / cmov / store is sound, because it's so simple.
I could save 3 bytes if I could require the caller to pass the chroma-key constant (0x00ff00) as an extra arg, instead of hard-coding the constant into the function. I don't think the usual rules allow writing a more generic function that has the caller set up constants for it. But if it did, the 3rd arg (currently `dummy`) is passed in `edx` in the x86-64 SysV ABI. Just change `cmp eax, 0x0000ff00` (5B) to `cmp eax, edx` (2B).
---
With SSE4 or AVX, you might do this faster (but larger code size) with `pcmpeqd` and `blendvps` to do a 32-bit element size variable-blend controlled by the compare mask. (With `pand`, you could ignore the high byte). For packed RGB24, you might use `pcmpeqb` and then 2x `pshufb`+`pand` to get TRUE in bytes where all 3 components of that pixel match, then `pblendvb`.
(I know this is code-golf, but I did consider trying MMX before going with scalar integer.)
[Answer]
# Mathematica ~~57~~ 35 bytes
update: by default, a green background is removed using `RemoveBackground`. The first submission included the unnecessary second parameter, `{"Background",Green}".
---
```
#~ImageCompose~RemoveBackground@#2&
```
Removes the background of image 2 and composes the result with image 1.
---
**Example**
[![i1](https://i.stack.imgur.com/XFtX8.png)](https://i.stack.imgur.com/XFtX8.png)
The following, in prefix rather than infix form, shows more clearly how the code works.
[![i2](https://i.stack.imgur.com/jHzme.png)](https://i.stack.imgur.com/jHzme.png)
[Answer]
# [Python 3](https://docs.python.org/3/) + [numpy](http://www.numpy.org/), 59 bytes
```
lambda f,b:copyto(f,b,'no',f==[0,255,0])
from numpy import*
```
[Try it online!](https://tio.run/##bVAxDoMwEJvLK24DqhtCAgUq8ZI0A7QKrdSQKKIDr6d3iIFKnWzHTmwlLPPTT2odu9v67t3w6MHicL37sMw@I4rp5FO0XacFyqpCYfLERu9g@riwwMsFH@fzaqGDPsZ@ybTWhUSQFYIyCLokIhXCpWYl2KETYQwmJ33QZLYIfFWV/5KFYgehFb8uiaYmVSA0rTE0bzhuoSA5kmOM@yhGhHJ/milCta0lpK1MGRHqPcOUGthgpB1bMyEViK13pP@CIU9CfE1zZvP1Cw "Python 3 – Try It Online")
Input is given in the format of a `numpy` array, with integer triplets representing pixels (where `#00FF00` in hex color code is equivalent to `[0, 255, 0]`). The input array is modified in place, which is allowed [per meta](https://codegolf.meta.stackexchange.com/a/4942).
## Example Images
### Input (from the question)
Background:
[![ckjbgames' profile picture](https://i.stack.imgur.com/hI4PZ.png)](https://i.stack.imgur.com/hI4PZ.png)
Foreground:
[![Dennis' profile picture](https://i.stack.imgur.com/PW11T.png)](https://i.stack.imgur.com/PW11T.png)
Foreground image after running the function:
[![Merged image with #00FF00 replaced with background pixels](https://i.stack.imgur.com/2ohU0.png)](https://i.stack.imgur.com/2ohU0.png)
## Reference Implementation (uses `opencv` to read image files)
```
g = lambda f,b:copyto(f,b,'no',f==[0,255,0])
from numpy import*
import cv2
f = cv2.imread("fg.png")
b = cv2.imread("bg.png")
g(f, b)
cv2.imshow("Output", f)
cv2.imwrite("out.png", f)
```
Displays the image to the screen and writes it to an output file.
[Answer]
# Processing, ~~116~~ 99 bytes
```
PImage f(PImage b,PImage f){int i=0;for(int c:f.pixels){if(c!=#00FF00)b.pixels[i]=c;i++;}return b;}
```
Unfortunately, processing doesn't support java 8 stuff, like lambdas.
Example implementation: (saves image as `out.png` and also draws it on screen)
```
PImage bg;
void settings() {
  bg = loadImage("bg.png");
  size(bg.width,bg.height);
}
void setup() {
  image(f(bg, loadImage("fg.png")), 0, 0);
  save("out.png");
}
PImage f(PImage b,PImage f){int i=0;for(int c:f.pixels){if(c!=#00FF00)b.pixels[i]=c;i++;}return b;}
```
[Answer]
## Bash + ImageMagick, 45 bytes
```
convert $1 $2 -transparent lime -composite x:
```
Takes two images as arguments and displays the output on the screen. Change `x:` to `$3` to write to a third file argument instead. The method is simple: read the "background" image; read the "foreground" imagek; reinterpret the color "lime" (#00ff00) as transparency in the second image; then composite the second image onto the first and output.
## ImageMagick: 28 bytes?
I could have submitted this as [an ImageMagick answer](https://codegolf.meta.stackexchange.com/questions/8828/is-imagemagick-a-programming-language) but it's not clear how to deal with the arguments. If you want to posit that ImageMagick is a stack-based language (which is kinda sorta not really true but almost... it's weird) then `-transparent lime -composite` is a function that expects two images on the stack and leaves one merged image on the stack... maybe that's good enough to count?
[Answer]
# [MATL](https://github.com/lmendo/MATL), ~~40~~ ~~37~~ 31 bytes
```
,jYio255/]tFTF1&!-&3a*5M~b*+3YG
```
Example run with the offline interpreter. The images are input by their URL's (local filenames could also be provided).
[![enter image description here](https://i.stack.imgur.com/2s24A.gif)](https://i.stack.imgur.com/2s24A.gif)
### Explanation
```
,        % Do this twice
  j      %   Input string with URL or filename
  Yi     %   Read image as an M×N×3 uint8 array
  o      %  Convert to double
  255/   %   Divide by 255
]        % End
t        % Duplicate the second image
FTF      % Push 1×3 vector [0 1 0]
1&!      % Permute dimensions to give a 1×1×3 vector
-        % Subtract from the second image (M×N×3 array), with broadcast
&3a      % "Any" along 3rd dim. This gives a M×N mask that contains
         % 0 for pure green and 1 for other colours
*        % Mulltiply. This sets green pixels to zero
5M       % Push mask M×N again
~        % Negate
b        % Bubble up the first image
*        % Multiply. This sets non-green pixels to zero
+        % Add the two images
3YG      % Show image in a window
```
[Answer]
# [Pyth](https://github.com/isaacg1/pyth), 27 bytes
```
M?q(Z255Z)GHG.wmgVhded,V'E'
```
It takes quoted input. The input are the two paths of the image files. Output a file `o.png` Unfortunately that cannot be tested on the online interpreter for safety reason (`'` is disabled on it). You will need to get [Pyth](https://github.com/isaacg1/pyth) on your computer to test it.
**Explanation**
```
M?q(Z255Z)GHG                  # Define a function g which takes two tuples G and H and returns G if G != (0, 255, 0), H otherwise
                       V'E'    # Read the images. They are returned as lists of lists of colour tuples
                      ,        # Zip both images
               m  hded         # For each couple of lists in the zipped list...
                gV             # Zip the lists using the function g
             .w                # Write the resulting image to o.png
```
[Answer]
# Matlab 2016b and Octave, ~~62~~ 59 bytes
Input: A = MxNx3 unit8 foreground matrix, B = MxNx3 unit8 background matrix.
```
k=sum(A(:,:,2)-A(:,:,[1 3]),3)==510.*ones(1,1,3);A(k)=B(k);
```
Output: A = MxNx3 unit8 matrix
Sample use:
```
A = imread('foreground.png');
B = imread('backgroundimg.png');
k=sum(A(:,:,2)-A(:,:,[1 3]),3)==510.*ones(1,1,3);A(k)=B(k);
imshow(A)
```
[Answer]
# C++, 339 bytes
This uses CImg, and it can take files in other formats, too. The result is displayed in a window.
```
#include<CImg.h>
using namespace cimg_library;
int main(int g,char** v){CImg<unsigned char> f(v[1]),b(v[2]);for(int c=0;c<f.width();c++){for(int r=0;r<f.height();r++){if((f(c,r)==0)&&(f(c,r,0,1)==255)&&(f(c,r,0,2)==0)){f(c,r)=b(c,r);f(c,r,0,1)=b(c,r,0,1);f(c,r,0,2) = b(c,r,0,2);}}}CImgDisplay dis(f);while(!dis.is_closed()){dis.wait();}}
```
Compile with `g++ chromakey.cpp -g -L/usr/lib/i386-linux-gnu -lX11 -o chromakey -pthread`.
[Answer]
# R, 135 bytes
```
function(x,y,r=png::readPNG){a=r(x);m=apply(a,1:2,function(x)all(x==0:1));for(i in 1:4)a[,,i][m]=r(y)[,,i][m];png::writePNG(a,"a.png")}
```
Anonymous function, takes 2 png file paths as arguments and output a png picture called `a.png`.
Slightly ungolfed, with explanations:
```
function(x,y){
    library(png)
    # readPNG output a 3D array corresponding to RGBA values on a [0,1] scale:
    a = readPNG(x)
    # Logical mask, telling which pixel is equal to c(0, 1, 0, 1), 
    # i.e. #00FF00 with an alpha of 1:
    m = apply(a, 1:2, function(x) all(x==0:1))
    # For each RGB layer, replace that part with the equivalent part of 2nd png:
    for(i in 1:4) a[,,i][m] = readPNG(y)[,,i][m]
    writePNG(a,"a.png")
}
```
[Answer]
# SmileBASIC, 90 bytes whats the key
```
DEF C I,J
DIM T[LEN(I)]ARYOP.,T,I,16711936ARYOP 2,T,T,T
ARYOP 6,T,T,0,1ARYOP 5,I,I,J,T
END
```
`I` is the foreground and output, `J` is the background.
Both are integer arrays of pixels, in 32 bit ARGB format.
## Ungolfed
```
DEF C IMAGE,BACKGROUND 'function
 DIM TEMP[LEN(IMAGE)]  'create array "temp"
 ARYOP #AOPADD,TEMP,IMAGE,-RGB(0,255,0)    'temp = image - RGB(0,255,0)
 ARYOP #AOPCLP,TEMP,TEMP,-1,1              'temp = clamp(temp, -1, 1)
 ARYOP #AOPMUL,TEMP,TEMP,TEMP              'temp = temp * temp
 ARYOP #AOPLIP,IMAGE,IMAGE,BACKGROUND,TEMP 'image = linear_interpolate(image, background, temp)
END
```
## Explanation:
ARYOP is a function that applies a simple operation to every element in an array.  
It is called like `ARYOP mode, output_array, input_array_1, input_array_2, ...`
First, to determine which pixels in the image are green, `-16711936` (the RGBA representation of the green color) is subtracted from each pixel in the foreground image. This gives an array where `0` represents green pixels, and any other number represents non-green pixels.
To convert all nonzero values to `1`, they are squared (to remove negative numbers), then clamped to between `0` and `1`.
This results in an array with only `0`s and `1`s.  
`0`s represent green pixels in the foreground image, and should be replaced with pixels from the background.  
`1`s represent non-green pixels, and those will need to be replaced with pixels from the foreground.
This can easily be done using linear interpolation.
[Answer]
# PHP, 187 bytes
```
for($y=imagesy($a=($p=imagecreatefrompng)($argv[1]))-1,$b=$p($argv[2]);$x<imagesx($a)?:$y--+$x=0;$x++)($t=imagecolorat)($b,$x,$y)-65280?:imagesetpixel($b,$x,$y,$t($a,$x,$y));imagepng($b);
```
assumes 24bit PNG files; takes file names from command lines arguments, writes to stdout.  
Run with `-r`.
**breakdown**
```
for($y=imagesy(                                 # 2. set $y to image height-1
        $a=($p=imagecreatefrompng)($argv[1])    # 1. import first image to $a
    )-1,
    $b=$p($argv[2]);                            # 3. import second image to $b
    $x<imagesx($a)?:                            # Loop 1: $x from 0 to width-1
        $y--+$x=0;                              # Loop 2: $y from height-1 to 0
        $x++)
            ($t=imagecolorat)($b,$x,$y)-65280?:     # if color in $b is #00ff00
                imagesetpixel($b,$x,$y,$t($a,$x,$y));   # then copy pixel from $a to $b
imagepng($b);                                   # 5. output
```
[Answer]
# JavaScript (ES6), 290 bytes
```
a=>b=>(c=document.createElement`canvas`,w=c.width=a.width,h=c.height=a.height,x=c.getContext`2d`,x.drawImage(a,0,0),d=x.getImageData(0,0,w,h),o=d.data,o.map((_,i)=>i%4?0:o[i+3]=o[i++]|o[i++]<255|o[i]?255:0),x.drawImage(b,0,0),createImageBitmap(d).then(m=>x.drawImage(m,0,0)||c.toDataURL()))
```
Takes input as two `Image` objects (in currying syntax), which can be created with an HTML `<image>` element. Returns a Promise that resolves to the Base64 data URL of the resulting image, which can be applied to the `src` of an `<image>`.
The idea here was to set the alpha value for each `#00FF00` pixel to `0` and then paint the foreground, with its background keyed out, on top of the background.
## Test Snippet
Including the foreground and background by their data URLs was too large to post here, so it was moved to CodePen:
[Try it online!](https://codepen.io/justinm53/pen/rwEaQw)
[Answer]
# [OSL](https://github.com/imageworks/OpenShadingLanguage), 83 bytes
```
shader a(color a=0,color b=0,output color c=0){if(a==color(0,1,0)){c=b;}else{c=a;}}
```
Takes two inputs. The first is the foreground, and the second, the background.
[Answer]
# [C (gcc)](https://gcc.gnu.org/), ~~248~~ 245 bytes
*-3 bytes thanks to [@ceilingcat](https://codegolf.stackexchange.com/users/52904/ceilingcat)*
```
#define F(N)for(i=0;i<N;++i)
#define V x,y,z,w
*S="P%d %d %d %d ";V;v[6];main(i,f)int**f;{F(2)fscanf(f[i]=fopen(f[i+1],"r"),S,&x,&y,&z,&w);for(printf(S,V);~*v;x=0){F(3)x||putchar(i[!(*v|v[1]-255|v[2])*3+v]);F(3)v[i+3]=getc(*f),v[i]=getc(f[1]);}}
```
[Try it online!](https://tio.run/##PY5Bb4JAEIXv/gqKkewsY6IQe5nu1aNpQsKF7IGsjN1DV0Lpior967g0aZM5vJeZ974x65Mx07Q8NmxdE@3FAfjcCas2ZN8OlKYWFn/LMhrwije8LGSh4vfVMfqfmEry1aumz9o6YZHBul5KpvteZMBfpnYsuLJa8blt3CzTrca4iwELTAZMrpjcMLkAzfi2C3EWBZZAP9LToDYQmnIYxrH97s1HHV6sXoT0o6@2ep3tdkFkGmSeeg00n/qAyLU6Nb0RkgH9TP91HCJAj8c0PQE "C (gcc) – Try It Online")
]