กุญแจสู่ความสำเร็จ


23

ค่าสี RGB #00FF00นั้นค่อนข้างสำคัญ: ใช้สำหรับสร้างภาพยนตร์รายการทีวีการประกาศสภาพอากาศและอื่น ๆ มันเป็นสี "TV เขียว" หรือ "หน้าจอสีเขียว" ที่มีชื่อเสียง

ความท้าทาย

งานของคุณคือการเขียนโปรแกรมที่รับภาพอินพุตสองภาพทั้งในรูปแบบ PNG (หรือในประเภทอิมเมจของอิมเมจไลบรารีภาพ) และขนาดที่เท่ากัน ภาพหนึ่งภาพสามารถเป็นภาพเก่าได้ #00FF00ส่วนอีกคนหนึ่งเป็นภาพที่จะมีพื้นหลังของสีที่ ภาพที่ส่งออกจะประกอบด้วยภาพที่สองที่ซ้อนทับในภาพแรกโดยไม่มี#00FF00สี (ยกเว้นในภาพแรก) เข้าและส่งออกอาจจะทำกับไฟล์เป็น GUI ฯลฯ คุณจะได้รับอนุญาตให้ใช้อาร์เรย์ของค่า RGB เป็น input เท่าที่เห็นนี่ คุณอาจคิดว่าภาพมีความทึบแสงเต็มพิกเซลเท่านั้น

โดยทั่วไป ...

สร้างโปรแกรมที่ใช้ทุก#00FF00พิกเซลในภาพเดียวและแทนที่ด้วยพิกเซลที่สอดคล้องกันในภาพพื้นหลัง

กรณีทดสอบ

มีให้โดย @dzaima: พื้นหลัง: เบื้องหน้า: เอาต์พุต:
ภาพโปรไฟล์ของฉัน

เดนนิส

เอาท์พุต


แน่นอนว่าช่องโหว่มาตรฐานต้องห้ามอย่างเคร่งครัด ซึ่งรวมถึงการใช้แหล่งข้อมูลออนไลน์เพื่อทำเพื่อคุณ
นี่คือดังนั้นอาจเป็นรหัสที่สั้นที่สุดและโปรแกรมเมอร์ที่ดีที่สุดจะประสบความสำเร็จ ...


2
เราจะนำวัตถุภาพในรูปแบบดั้งเดิมของภาษา / ไลบรารีเป็นอินพุตหรือไม่หรือเราต้องอ่านภาพผ่านชื่อไฟล์หรือไม่?
notjagan

@notjagan คุณอาจใช้วัตถุรูปภาพเป็นอินพุต
ckjbgames

3
I / O ของอาร์เรย์ของอาร์เรย์ของจำนวนเต็มเป็นที่ยอมรับหรือจริง ๆ แล้วเรา จำกัด ไว้ที่ I / O รูปภาพชุดอื่นหรือไม่?
Jonathan Allan

1
@PeterCordes ฉันจะอนุญาตให้
ckjbgames

1
@PeterCordes ok
ckjbgames

คำตอบ:


14

รหัสเครื่อง x86-64 (และ x86-32), 13 15 13 ไบต์

การเปลี่ยนแปลง:

  1. แก้ไขข้อผิดพลาด: รุ่นแรกเพียงตรวจสอบ G = 0xff ไม่ต้องการ R และ B เป็น 0 ฉันเปลี่ยนเป็นการปรับเปลี่ยนพื้นหลังในสถานที่เพื่อให้ฉันสามารถใช้lodsdในเบื้องหน้าเพื่อมีพิกเซล fg ในeaxการcmp eax, imm32เข้ารหัสแบบสั้น(5 ไบต์ ) แทนcmp dh,0xff(3 ไบต์)

  2. บันทึก 2 ไบต์: สังเกตว่าการแก้ไข bg ในสถานที่อนุญาตให้ใช้ตัวถูกดำเนินการหน่วยความจำสำหรับcmovการบันทึกmovโหลด2 ไบต์(และบันทึกการลงทะเบียนในกรณีที่มีความสำคัญ)


นี่คือฟังก์ชั่นต่อไปนี้ x86-64 System V การเรียกแบบแผนเรียกได้โดยตรงจาก C หรือ C ++ (บน x86-64 ไม่ใช่ระบบ Windows) ด้วยลายเซ็นนี้:

void chromakey_blend_RGB32(uint32_t *background /*rdi*/,
                     const uint32_t *foreground /*rsi*/,
                  int dummy, size_t pixel_count /*rcx*/);

รูปแบบภาพคือ RGB0 32bpp โดยองค์ประกอบสีเขียวที่อยู่หน่วยความจำต่ำสุดที่ 2 ภายในแต่ละพิกเซล เบื้องหน้าภาพพื้นหลังที่มีการแก้ไขในสถานที่ pixel_countคือคอลัมน์ * แถว ไม่สนใจแถว / คอลัมน์ มันเป็นเพียง chromekey ผสมอย่างไรก็ตามหลายหน่วยความจำที่คุณระบุ

RGBA (ด้วย A ที่จำเป็นต้องเป็น 0xFF) จะต้องใช้ค่าคงที่ที่แตกต่างกัน แต่ไม่มีการเปลี่ยนแปลงขนาดฟังก์ชั่น Foreground DWORD ถูกนำมาเปรียบเทียบเพื่อความเท่าเทียมกันอย่างแน่นอนกับค่าคงที่ 32- บิตที่เก็บไว้ใน 4 ไบต์โดยพลการดังนั้นสีใด ๆ ของพิกเซลหรือลำดับสีของโคร - คีย์สามารถรองรับได้อย่างง่ายดาย

รหัสเครื่องเดียวกันยังทำงานในโหมด 32 บิต ในการประกอบเป็น 32 บิตให้เปลี่ยนrdiเป็นediในแหล่งที่มา รีจิสเตอร์อื่นทั้งหมดที่กลายเป็น 64- บิตจะเป็นค่าปริยาย (lodsd / stosd และ loop) และเรจิสอื่น ๆ จะอยู่ที่ 32- บิต แต่โปรดทราบว่าคุณจะต้องใช้ wrapper ในการโทรจาก 32-bit C เพราะไม่มีมาตรฐานการประชุมที่เรียกว่า x86-32 ใช้ regs เดียวกับ x86-64 SysV

รายชื่อ NASM (รหัสเครื่อง + แหล่งที่มา) แสดงความคิดเห็นสำหรับผู้เริ่มต้น asm พร้อมคำอธิบายสิ่งที่คำแนะนำที่ซับซ้อนมากขึ้นทำ (การทำซ้ำคู่มืออ้างอิงคำสั่งเป็นรูปแบบที่ไม่ดีในการใช้งานปกติ)

 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

เพื่อให้ได้แหล่ง NASM เดิมออกจากรายการนี้ตัด 26 <chromakey.lst cut -b 26- > chromakey.asmตัวชั้นนำของแต่ละบรรทัด ฉันสร้างสิ่งนี้ด้วย
nasm -felf64 chromakey-blend.asm -l /dev/stdout | cut -b -28,$((28+12))- รายชื่อ NASM ทำให้มีคอลัมน์ว่างมากกว่าที่ฉันต้องการระหว่างรหัสเครื่องและแหล่งที่มา ในการสร้างไฟล์วัตถุคุณสามารถเชื่อมโยงกับ C หรือ C ++ nasm -felf64 chromakey.asmใช้ (หรือyasm -felf64 chromakey.asm)

ยังไม่ทดลองแต่ฉันค่อนข้างมั่นใจว่าแนวคิดพื้นฐานของ load / load / cmov / store นั้นเป็นเสียงเพราะมันง่ายมาก

ฉันสามารถบันทึกได้ 3 ไบต์หากฉันต้องการให้ผู้โทรส่งค่าคงที่สี (0x00ff00) ให้เป็นค่า ARG พิเศษแทนการเข้ารหัสค่าคงที่ลงในฟังก์ชันอย่างหนัก ฉันไม่คิดว่ากฎปกติอนุญาตให้เขียนฟังก์ชั่นทั่วไปที่มีผู้เรียกตั้งค่าคงที่สำหรับมัน แต่ถ้าเป็นเช่นนั้น ARG ตัวที่ 3 (ปัจจุบันdummy) จะถูกส่งเข้ามาedxใน x86-64 SysV ABI เพียงแค่เปลี่ยนcmp eax, 0x0000ff00(5B) เป็นcmp eax, edx(2B)


ด้วย SSE4 หรือ AVX คุณอาจทำสิ่งนี้ได้เร็วขึ้น (แต่มีขนาดรหัสใหญ่กว่า) ด้วยpcmpeqdและblendvpsเพื่อทำการผสมผสานตัวแปรขนาดองค์ประกอบ 32 บิตที่ควบคุมโดยมาสก์เปรียบเทียบ (ด้วยpandคุณสามารถละเว้นไบต์สูง) สำหรับ RGB24 บรรจุคุณอาจใช้pcmpeqbแล้ว 2x pshufb+ pandที่จะได้รับ TRUE ไบต์ซึ่งทั้ง 3 pblendvbองค์ประกอบของการจับคู่พิกเซลที่แล้ว

(ฉันรู้ว่านี่คือโค้ดกอล์ฟ แต่ฉันลองใช้ MMX ก่อนที่จะไปด้วยจำนวนสเกลาร์)


คุณสามารถส่งแฟ้มที่ปฏิบัติการด้วยรหัสเครื่องนี้ให้ฉันได้ไหม
ckjbgames

โปรด x86_32
ckjbgames

@ckjbgames: ฉันยังไม่ได้เขียนผู้เรียกที่โหลด / บันทึกภาพเพียงส่วนที่แก้ไขพิกเซลในสถานที่ ฉันต้องทำก่อนที่มันจะทำให้รู้สึกถึงการสร้างปฏิบัติการ แต่ถ้าฉันทำสิ่งที่ชนิดของการปฏิบัติการ? Windows PE32 Linux ELF32 ใช่ไหม FreeBSD ??
Peter Cordes

ELF32 ถ้าคุณต้องการ
ckjbgames

@ckjbgames: ถ้าฉันหาเวลาฉันจะหาห้องสมุดที่โหลดภาพและเขียนอะไรบางอย่าง ฉันเพิ่มย่อหน้าเกี่ยวกับวิธีเปลี่ยนรายชื่อกลับเป็นรหัสที่คุณสามารถรวบรวมnasm -felf32ได้ (สำหรับ 32 บิตคุณจะต้องใช้ฟังก์ชั่น wrapper ในการโทรจาก C เพราะมันยังใช้ register เหมือนกันกับ x86-64 SysV ABI)
Peter Cordes

13

Mathematica 57 35 ไบต์

UPDATE: RemoveBackgroundโดยค่าเริ่มต้นพื้นหลังสีเขียวจะถูกลบออกโดยใช้ การส่งครั้งแรกรวมถึงพารามิเตอร์ที่สองที่ไม่จำเป็น `{" พื้นหลัง ", สีเขียว}"


#~ImageCompose~RemoveBackground@#2&

ลบพื้นหลังของภาพ 2 และเขียนผลลัพธ์ด้วยรูปภาพ 1


ตัวอย่าง

i1

ต่อไปนี้ในคำนำหน้ามากกว่ารูปแบบมัดแสดงให้เห็นชัดเจนยิ่งขึ้นว่ารหัสทำงานอย่างไร

i2


4
สิ่งนี้ใช้ได้กับรูปภาพที่ไม่ใช่ "พื้นหลัง" ที่เป็นสีเขียวหรือไม่ (ดูเหมือนว่าจะมีสีเขียวปะอยู่เล็กน้อยในผลลัพธ์ของคุณ)
DBS

หากมี "เกาะ" สีเขียวในภาพจะต้องมีพารามิเตอร์เพิ่มเติม `{" พื้นหลัง ", สีเขียว}" ซึ่งจะเพิ่มจำนวนทั้งหมด 57 ไบต์นั่นคือการส่งครั้งแรกของฉันเพราะฉันไม่เห็นสีเขียว แยกไว้ที่ด้านหน้าของรูปภาพพารามิเตอร์นั้นถูกทิ้ง
DavidC

11

งูหลาม 3 + numpy 59 ไบต์

lambda f,b:copyto(f,b,'no',f==[0,255,0])
from numpy import*

ลองออนไลน์!

อินพุตถูกกำหนดในรูปแบบของnumpyอาเรย์โดยมีจำนวนเต็มสามเท่าแทนพิกเซล (โดยที่#00FF00โค้ดสีฐานสิบหกเทียบเท่า[0, 255, 0]) อาร์เรย์การป้อนข้อมูลที่มีการแก้ไขในสถานที่ซึ่งได้รับอนุญาตต่อเมตา

ภาพตัวอย่าง

อินพุต (จากคำถาม)

พื้นหลัง:

ckjbgames' profile picture

เบื้องหน้า:

Dennis' profile picture

ภาพเบื้องหน้าหลังจากเรียกใช้ฟังก์ชัน:

Merged image with #00FF00 replaced with background pixels

การใช้งานอ้างอิง (ใช้opencvเพื่ออ่านไฟล์ภาพ)

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)

แสดงภาพไปยังหน้าจอและเขียนลงในไฟล์เอาต์พุต


17
มีจุดสีแดงทั้งหมดในภาพที่ได้อย่างไร
Yytsi

1
ฉันถามเกี่ยวกับ I / O - สิ่งนี้ดูเหมือนจะสอดคล้องกับถ้อยคำปัจจุบัน (เช่น "ห้องสมุดของคุณ") ถ้าเป็นเช่นนั้น cv2 เองต้องการการนำเข้าที่มีจำนวนมากหรือไม่ ถ้าไม่ได้คุณสามารถทำมันใน 54 โดยไม่ได้ใช้ฟังก์ชั่น numpy ใด ๆ และไม่ได้นำเข้า lambda f,b:[x[list(x[0])==[0,255,0]]for x in zip(f,b)]numpy: หากรายการของจำนวนเต็มเป็นที่ยอมรับเช่นกันคุณก็สามารถทำได้ใน 48 ด้วยlambda f,b:[x[x[0]==[0,255,0]]for x in zip(f,b)]
Jonathan Allan

ความเป็นจริง ..in แม้ว่า numpy จะจำเป็นสำหรับ CV2 เพื่อดำเนินการแปลงผมยังคิดว่าคุณสามารถทำรุ่น 54 ไบต์เนื่องจากเราไม่จำเป็นต้องนำเข้า CV2 สำหรับความท้าทาย
Jonathan Allan

5
หาก G == 255ค่าถูกแทนที่แม้ว่า R และ B จะไม่เป็นศูนย์ซึ่งจะนำไปสู่จุดสีแดง สิ่งนี้จะเกิดขึ้นกับวงอื่นด้วย ดังนั้นจึงทำการตรวจสอบลอจิกเป็นอิสระจากกันและแลกเปลี่ยนช่องสัญญาณเดี่ยวแม้ว่าจะมีเงื่อนไขเพียงข้อเดียวเท่านั้น เช่นถ้าพิกเซลเป็น[0 255 37]แถบสีแดงและสีเขียวจะถูกแทนที่
Leander Moesinger

2
@ LeanderMoesinger: เห็นดี ฉันมีข้อผิดพลาดในของฉันเช่นกัน>. <; IDK เหตุใดฉันจึงคิดว่าการตรวจสอบเพียงสีเขียว = 0xFF ในขณะที่ละเว้น R และ B นั้นถูกต้อง!
Peter Cordes

9

กำลังประมวลผล116 99 ไบต์

PImage f(PImage b,PImage f){int i=0;for(int c:f.pixels){if(c!=#00FF00)b.pixels[i]=c;i++;}return b;}

น่าเสียดายที่การประมวลผลไม่รองรับจาวา 8 สิ่งเช่น lambdas

ตัวอย่างการนำไปใช้: (บันทึกภาพเป็นout.pngและวาดลงบนหน้าจอ)

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;}

คุณสามารถกำจัดsettings()และsetup()ฟังก์ชั่นและเพียงแค่เรียกใช้รหัสโดยตรง
Kevin Workman

@KevinWorkman ฉันมีการตั้งค่าและการตั้งค่าที่นั่นดังนั้นมันจึงจะแสดงภาพบนหน้าจอซึ่งเป็นไปไม่ได้อีกต่อไป
dzaima

เป็น#ff00หรือ0xff00เป็นเช่นเดียวกับ#00ff00ในการประมวลผล?
Peter Cordes

@PeterCordes # FF00 ให้ข้อผิดพลาดทางไวยากรณ์เศร้าและ # 00FF00 == 0xFF00FF00 ดังนั้น 0xFF00 ไม่ทำงานเมื่อตรวจสอบค่าอัลฟา 0
dzaima

@dzaima: คุณสามารถถ่ายภาพในรูปแบบ RGB0 ได้หรือไม่ซึ่ง0x0000FF00เป็นรูปแบบบิตที่คุณต้องการ
Peter Cordes

6

Bash + ImageMagick ขนาด 45 ไบต์

convert $1 $2 -transparent lime -composite x:

ถ่ายภาพสองภาพเป็นอาร์กิวเมนต์และแสดงผลลัพธ์บนหน้าจอ เปลี่ยนx:เป็น$3เขียนไฟล์อาร์กิวเมนต์ที่สามแทน วิธีการง่าย: อ่านภาพ "พื้นหลัง"; อ่าน imagek ​​"เบื้องหน้า"; ตีความสี "มะนาว" อีกครั้ง (# 00ff00) เป็นความโปร่งใสในภาพที่สอง จากนั้นประกอบภาพที่สองเข้ากับภาพแรกและภาพออก

ImageMagick: 28 ไบต์?

ฉันสามารถส่งสิ่งนี้เป็นคำตอบของ ImageMagickแต่ยังไม่ชัดเจนว่าจะจัดการกับข้อโต้แย้งอย่างไร ถ้าคุณต้องการที่จะวางตัว ImageMagick เป็นภาษาที่ใช้กองซ้อน (ซึ่งเป็น kinda sorta ไม่จริงจริง แต่เกือบ ... มันแปลก) จากนั้น-transparent lime -compositeเป็นฟังก์ชั่นที่คาดว่าสองภาพในกองซ้อนและออกจากภาพที่ผสานหนึ่งในกอง .. บางทีมันก็ดีพอที่จะนับ?


3

MATL , 40 37 31 ไบต์

,jYio255/]tFTF1&!-&3a*5M~b*+3YG

ตัวอย่างทำงานกับล่ามออฟไลน์ ภาพที่ป้อนโดย URL ของพวกเขา (ชื่อไฟล์ท้องถิ่นสามารถให้)

enter image description here

คำอธิบาย

,        % 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

3

Pyth , 27 ไบต์

M?q(Z255Z)GHG.wmgVhded,V'E'

มันใช้เวลาที่ยกมาใส่ อินพุตเป็นสองเส้นทางของไฟล์ภาพ ส่งออกไฟล์o.pngน่าเสียดายที่ไม่สามารถทดสอบกับล่ามออนไลน์ได้เพื่อความปลอดภัย ( 'ปิดการใช้งานไว้) คุณจะต้องใช้Pythบนคอมพิวเตอร์เพื่อทดสอบ

คำอธิบาย

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

ฟังก์ชั่นการผสมผสานปุ่มสีด้วยตัวมันเองคือ 13 ไบต์เช่นเดียวกับคำตอบรหัสเครื่อง x86 ของฉัน ก่อนหน้านี้ฉันไม่เคยรู้มาก่อนเลยว่านี่เป็นอิมเมจการส่งโปรแกรมแบบ I / O ที่สมบูรณ์เช่นกัน
Peter Cordes

2

Matlab 2016b และ Octave, 62 59 ไบต์

อินพุต: เมทริกซ์โฟร์กราวน์เบื้องหน้า M = MxNx3 unit8, B = เมทริกซ์แบคกราวน์ MxNx3 unit8

k=sum(A(:,:,2)-A(:,:,[1 3]),3)==510.*ones(1,1,3);A(k)=B(k);

เอาท์พุท: A = MxNx3 unit8 เมทริกซ์

ตัวอย่างการใช้งาน:

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)

1

C ++, 339 ไบต์

สิ่งนี้ใช้ CImg และสามารถใช้ไฟล์ในรูปแบบอื่นได้เช่นกัน ผลลัพธ์จะปรากฏขึ้นในหน้าต่าง

#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();}}

g++ chromakey.cpp -g -L/usr/lib/i386-linux-gnu -lX11 -o chromakey -pthreadคอมไพล์ด้วย


1

R, 135 ไบต์

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")}

ฟังก์ชั่นไม่ระบุชื่อใช้พา ธ ไฟล์ 2 png เป็นอาร์กิวเมนต์และส่งออกรูปภาพ png ที่เรียกว่า a.pngที่เรียกว่า

ungolfed เล็กน้อยพร้อมคำอธิบาย:

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")
}

1

SmileBASIC 90 ไบต์สำคัญกับอะไร

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 เป็นส่วนหน้าและผลลัพธ์ Jเป็นพื้นหลัง ทั้งสองเป็นอาร์เรย์จำนวนเต็มพิกเซลในรูปแบบ ARGB 32 บิต

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

คำอธิบาย:

ARYOP เป็นฟังก์ชันที่ใช้การดำเนินการอย่างง่ายกับทุกองค์ประกอบในอาร์เรย์
มันถูกเรียกว่าเหมือนARYOP mode, output_array, input_array_1, input_array_2, ...

ขั้นแรกเพื่อพิจารณาว่าพิกเซลใดในภาพที่เป็นสีเขียว-16711936(การแทน RGBA ของสีเขียว) จะถูกลบออกจากแต่ละพิกเซลในรูปภาพเบื้องหน้า สิ่งนี้จะช่วยให้อาร์เรย์ที่0แสดงถึงพิกเซลสีเขียวและหมายเลขอื่น ๆ แสดงถึงพิกเซลที่ไม่ใช่สีเขียว

เพื่อแปลงค่าที่ไม่ใช่ศูนย์ทั้งหมดเป็น 1ที่พวกเขาจะยกกำลังสอง (เพื่อลบตัวเลขที่ติดลบ) ยึดไปแล้วระหว่างและ01

ผลลัพธ์นี้ในอาร์เรย์ที่มีเพียง0s และ1s เท่านั้น
0s แทนพิกเซลสีเขียวในภาพเบื้องหน้าและควรแทนที่ด้วยพิกเซลจากพื้นหลัง
1s แทนพิกเซลที่ไม่ใช่สีเขียวและสิ่งเหล่านั้นจะต้องถูกแทนที่ด้วยพิกเซลจากเบื้องหน้า

สามารถทำได้อย่างง่ายดายโดยใช้การแก้ไขเชิงเส้น


0

PHP, 187 ไบต์

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);

ถือว่าไฟล์ PNG 24 บิต; ใช้ชื่อไฟล์จากอาร์กิวเมนต์บรรทัดคำสั่งเขียนไปยัง stdout
ทำงานด้วย-rทำงานด้วย

ทำให้พังถล่ม

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

0

JavaScript (ES6), 290 ไบต์

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()))

รับอินพุตเป็นสองImageวัตถุ (ในรูปแบบ currying) ซึ่งสามารถสร้างได้ด้วย<image>องค์ประกอบHTML ส่งคืนสัญญาที่แก้ไข URL ฐานข้อมูล 64 ของอิมเมจผลลัพธ์ซึ่งสามารถนำไปใช้กับsrcของ<image>ของ

แนวคิดในการตั้งค่าอัลฟ่าสำหรับแต่ละ#00FF00พิกเซลเป็น0แล้วทาสีพื้นหน้าโดยให้พื้นหลังของแป้นพิมพ์อยู่ด้านบนของพื้นหลัง

ตัวอย่างการทดสอบ

การรวมส่วนหน้าและพื้นหลังโดย URL ข้อมูลของพวกเขานั้นใหญ่เกินกว่าจะโพสต์ได้ที่นี่ดังนั้นจึงถูกย้ายไปที่ CodePen:

ลองออนไลน์!


0

OSL , 83 ไบต์

shader a(color a=0,color b=0,output color c=0){if(a==color(0,1,0)){c=b;}else{c=a;}}

ใช้สองอินพุต แรกคือเบื้องหน้าและที่สองพื้นหลัง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.