Nilai warna RGB #00FF00
agak penting: digunakan untuk membuat film, acara TV, pengumuman cuaca, dan banyak lagi. Ini adalah warna "TV hijau" atau "layar hijau" yang terkenal.
Tantangan
Tugas Anda adalah menulis sebuah program yang mengambil dua gambar input, baik dalam format PNG (atau dalam tipe objek gambar pustaka gambar Anda) dan dengan dimensi yang sama. Satu gambar bisa berupa gambar lama. Yang lainnya adalah gambar yang akan memiliki latar belakang warna #00FF00
. Gambar output akan terdiri dari gambar kedua yang dilapis di atas gambar pertama, tanpa ada #00FF00
warna (kecuali pada gambar pertama). Input dan output dapat dilakukan dengan file, GUI, dll. Anda diizinkan untuk mengambil array nilai RGB sebagai input, seperti yang terlihat di sini . Anda dapat berasumsi bahwa suatu gambar hanya memiliki piksel opacity penuh.
Pada dasarnya ...
Buat program yang mengambil setiap #00FF00
piksel dalam satu gambar dan ganti dengan piksel yang sesuai di gambar latar belakang.
Uji Kasus
Bermurah hati disediakan oleh @dzaima: Latar Belakang:
Foreground:
Output:
Tentu saja, celah standar dilarang keras . Ini termasuk menggunakan sumber daya online untuk melakukannya untuk Anda.
Ini adalah kode-golf , jadi semoga kode terpendek menang dan programmer terbaik ...
sumber
Jawaban:
kode mesin x86-64 (dan x86-32),
131513 bytechangelog:
Perbaikan bug: versi pertama hanya memeriksa G = 0xff, tidak memerlukan R dan B menjadi 0. Saya mengubah untuk memodifikasi latar di tempat sehingga saya dapat menggunakan
lodsd
di latar depan untuk memiliki fg piksel dalameax
untukcmp eax, imm32
pengkodean bentuk pendek (5 byte) ), alih-alihcmp dh,0xff
(3 byte).Simpan 2 byte: perhatikan bahwa memodifikasi bg pada tempatnya diizinkan menggunakan operan memori untuk
cmov
, menghematmov
beban 2-byte (dan menyimpan register, jika perlu).Ini adalah fungsi yang mengikuti konvensi pemanggilan Sistem V x86-64, dapat dipanggil langsung dari C atau C ++ (pada sistem x86-64 non-Windows) dengan tanda tangan ini:
Format gambar adalah RGB0 32bpp, dengan komponen hijau di alamat memori terendah ke-2 dalam setiap piksel. Gambar
latarlatardepandimodifikasi di tempat.pixel_count
adalah baris * kolom. Itu tidak peduli tentang baris / kolom; itu hanya campuran chromekey namun banyak memori yang Anda tentukan.RGBA (dengan A harus 0xFF) akan membutuhkan menggunakan konstanta yang berbeda, tetapi tidak ada perubahan dalam ukuran fungsi. DWORD foreground dibandingkan untuk kesetaraan tepat terhadap konstanta 32-bit yang sewenang-wenang yang disimpan dalam 4 byte, sehingga warna urutan-pixel atau warna kunci-kroma dapat dengan mudah didukung.
Kode mesin yang sama juga berfungsi dalam mode 32-bit. Untuk berkumpul sebagai 32-bit, ubah
rdi
keedi
dalam sumber. Semua register lain yang menjadi 64-bit adalah implisit (lodsd / stosd, dan loop), dan regs eksplisit lainnya tetap 32-bit. Tetapi perhatikan bahwa Anda memerlukan pembungkus untuk menelepon dari 32-bit C, karena tidak ada konvensi pemanggilan x86-32 standar yang menggunakan regs yang sama dengan SysV x86-64.Daftar NASM (kode mesin + sumber), dikomentari untuk pemula ASM dengan deskripsi tentang apa yang dilakukan instruksi yang lebih kompleks. (Menggandakan manual referensi instruksi adalah gaya yang buruk dalam penggunaan normal.)
Untuk mengeluarkan sumber NASM asli dari daftar ini, hapus 26 karakter utama dari setiap baris
<chromakey.lst cut -b 26- > chromakey.asm
. Saya membuat ini dengannasm -felf64 chromakey-blend.asm -l /dev/stdout | cut -b -28,$((28+12))-
daftar NASM meninggalkan lebih banyak kolom kosong daripada yang saya inginkan antara kode mesin dan sumber. Untuk membuat file objek, Anda dapat menautkannya dengan C atau C ++, gunakannasm -felf64 chromakey.asm
. (Atauyasm -felf64 chromakey.asm
).belum diuji , tapi saya cukup yakin bahwa ide dasar load / load / cmov / store adalah suara, karena sangat sederhana.
Saya bisa menghemat 3 byte jika saya bisa meminta penelepon untuk meneruskan kunci chroma-key (0x00ff00) sebagai argumen tambahan, alih-alih mengkodekan konstanta ke dalam fungsi. Saya tidak berpikir aturan yang biasa memungkinkan penulisan fungsi yang lebih umum yang membuat pemanggil mengatur konstanta untuk itu. Tetapi jika itu terjadi, arg ke-3 (saat ini
dummy
) diteruskan dalamedx
SysV ABI x86-64. Ubahcmp eax, 0x0000ff00
(5B) menjadicmp eax, edx
(2B).Dengan SSE4 atau AVX, Anda mungkin melakukan ini lebih cepat (tetapi ukuran kode lebih besar) dengan
pcmpeqd
danblendvps
untuk melakukan campuran variabel ukuran elemen ukuran 32-bit yang dikendalikan oleh topeng pembanding. (Denganpand
, Anda dapat mengabaikan byte tinggi). Untuk RGB24 yang dikemas, Anda dapat menggunakanpcmpeqb
dan kemudian 2xpshufb
+pand
untuk mendapatkan TRUE dalam byte di mana ketiga komponen piksel itu cocok, lalupblendvb
.(Saya tahu ini adalah kode-golf, tapi saya sempat mempertimbangkan mencoba MMX sebelum menggunakan skalar integer.)
sumber
nasm -felf32
. (Untuk 32-bit, Anda juga perlu fungsi pembungkus untuk memanggil dari C, karena masih menggunakan register yang sama dengan SysV ABI x86-64.)Mathematica
5735 bytepembaruan: secara default, latar belakang hijau dihapus menggunakan
RemoveBackground
. Kiriman pertama termasuk parameter kedua yang tidak perlu, `{" Background ", Green}".Menghapus latar belakang gambar 2 dan menyusun hasilnya dengan gambar 1.
Contoh
Berikut ini, dalam bentuk awalan dan bukan infiks, menunjukkan lebih jelas bagaimana kode bekerja.
sumber
Python 3 + numpy , 59 byte
Cobalah online!
Input diberikan dalam format
numpy
array, dengan triplet bilangan bulat mewakili piksel (#00FF00
di mana dalam kode warna hex setara dengan[0, 255, 0]
). Array input diubah pada tempatnya, yang diizinkan per meta .Contoh Gambar
Masukan (dari pertanyaan)
Latar Belakang:
Latar depan:
Gambar latar depan setelah menjalankan fungsi:
Implementasi Referensi (digunakan
opencv
untuk membaca file gambar)Menampilkan gambar ke layar dan menulisnya ke file output.
sumber
lambda f,b:[x[list(x[0])==[0,255,0]]for x in zip(f,b)]
. Jika daftar daftar bilangan bulat sebenarnya dapat diterima juga maka Anda bisa melakukannya di 48 denganlambda f,b:[x[x[0]==[0,255,0]]for x in zip(f,b)]
G == 255
, nilai akan diganti bahkan jika R dan B bukan nol yang mengarah ke titik merah. Ini juga terjadi untuk band-band lain bahkan yang tangguh yang kurang terlihat. Jadi ia melakukan pengecekan logika secara independen satu sama lain dan menukar saluran tunggal meskipun hanya satu syarat terpenuhi. Misalnya jika pixel adalah[0 255 37]
pita merah dan hijau akan diganti.Memproses,
11699 byteSayangnya, pemrosesan tidak mendukung hal-hal java 8, seperti lambdas.
Contoh implementasi: (menyimpan gambar sebagai
out.png
dan juga menggambarnya di layar)sumber
settings()
dansetup()
fungsi dan hanya menjalankan kode secara langsung.#ff00
atau0xff00
sama seperti#00ff00
dalam Memproses?0x0000FF00
apakah pola bit yang Anda cari?Bash + ImageMagick, 45 byte
Mengambil dua gambar sebagai argumen dan menampilkan output di layar. Ubah
x:
menjadi$3
menulis ke argumen file ketiga sebagai gantinya. Metode ini sederhana: baca gambar "latar belakang"; baca imagek "foreground"; menafsirkan kembali warna "kapur" (# 00ff00) sebagai transparansi pada gambar kedua; kemudian gabungkan gambar kedua ke yang pertama dan hasilkan.ImageMagick: 28 byte?
Saya bisa mengirimkan ini sebagai jawaban ImageMagick tetapi tidak jelas bagaimana cara menangani argumen. Jika Anda ingin menyatakan bahwa ImageMagick adalah bahasa berbasis tumpukan (yang agak agak tidak benar tetapi hampir ... itu aneh) maka
-transparent lime -composite
adalah fungsi yang mengharapkan dua gambar pada tumpukan dan meninggalkan satu gambar yang digabungkan pada tumpukan .. mungkin itu cukup baik untuk dihitung?sumber
MATL ,
403731 byteContoh dijalankan dengan penerjemah offline. Gambar-gambar dimasukkan oleh URL-nya (nama file lokal juga dapat disediakan).
Penjelasan
sumber
Pyth , 27 byte
Dibutuhkan input yang dikutip. Input adalah dua jalur file gambar. Keluaran file
o.png
Sayangnya itu tidak dapat diuji pada juru bahasa online karena alasan keamanan ('
dinonaktifkan di dalamnya). Anda harus mendapatkan Pyth di komputer Anda untuk mengujinya.Penjelasan
sumber
Matlab 2016b dan Oktaf,
6259 byteInput: A = MxNx3 unit8 foreground matrix, B = MxNx3 unit8 background matrix.
Output: A = MxNx3 unit8 matrix
Penggunaan sampel:
sumber
C ++, 339 byte
Ini menggunakan CImg, dan dapat mengambil file dalam format lain juga. Hasilnya ditampilkan di jendela.
Kompilasi dengan
g++ chromakey.cpp -g -L/usr/lib/i386-linux-gnu -lX11 -o chromakey -pthread
.sumber
R, 135 byte
Fungsi anonim, mengambil jalur file 2 png sebagai argumen dan menampilkan gambar png yang disebut
a.png
.Sedikit ungolfed, dengan penjelasan:
sumber
SmileBASIC, 90 byte whats the key
I
adalah latar depan dan output,J
adalah latar belakang. Keduanya adalah array integer piksel, dalam format ARGB 32 bit.Tidak disatukan
Penjelasan:
ARYOP adalah fungsi yang menerapkan operasi sederhana untuk setiap elemen dalam array.
Ini disebut seperti
ARYOP mode, output_array, input_array_1, input_array_2, ...
Pertama, untuk menentukan piksel mana dalam gambar yang berwarna hijau,
-16711936
(representasi RGBA dari warna hijau) dikurangi dari setiap piksel dalam gambar latar depan. Ini memberikan array di mana0
mewakili piksel hijau, dan angka lainnya mewakili piksel non-hijau.Untuk mengkonversi semua nilai bukan nol, nilai
1
tersebut dikuadratkan (untuk menghapus angka negatif), lalu dijepit di antara0
dan1
.Ini menghasilkan array dengan hanya
0
s dan1
s.0
s mewakili piksel hijau pada gambar latar depan, dan harus diganti dengan piksel dari latar belakang.1
s mewakili piksel non-hijau, dan piksel tersebut perlu diganti dengan piksel dari latar depan.Ini dapat dengan mudah dilakukan dengan menggunakan interpolasi linier.
sumber
PHP, 187 byte
mengasumsikan file PNG 24bit; mengambil nama file dari argumen baris perintah, menulis ke stdout.
Jalankan dengan
-r
.kerusakan
sumber
JavaScript (ES6), 290 byte
Mengambil input sebagai dua
Image
objek (dalam sintaks currying), yang dapat dibuat dengan<image>
elemen HTML . Mengembalikan Janji yang memutuskan ke URL data Base64 dari gambar yang dihasilkan, yang dapat diterapkan kesrc
a<image>
.Idenya di sini adalah mengatur nilai alpha untuk setiap
#00FF00
piksel0
dan kemudian mengecat latar depan, dengan latar belakangnya dikunci, di atas latar belakang.Cuplikan Tes
Termasuk latar depan dan latar belakang dengan URL data mereka terlalu besar untuk dikirim di sini, jadi itu dipindahkan ke CodePen:
Cobalah online!
sumber
OSL , 83 byte
Mengambil dua input. Yang pertama adalah latar depan, dan yang kedua, latar belakang.
sumber