แฮคเกอร์สองภาพขาวดำ


28

ท้าทาย:

ใช้อินพุตของภาพขาวดำ (ขาวดำ) สองภาพและ xor แต่ละพิกเซลของภาพแรกด้วยแต่ละพิกเซลที่สองเพิ่มภาพเหล่านั้นลงในภาพใหม่และส่งภาพใหม่

คำอธิบายบางอย่าง:

ขนาดของรูปภาพไม่สำคัญ รูปแบบส่วนขยาย / รูปภาพไม่สำคัญ คุณสามารถทำให้มันรับอินพุตส่วนขยายใด ๆ และเอาท์พุทส่วนขยายใด ๆ ตราบเท่าที่ส่วนขยายจะใช้ในการจัดเก็บภาพดิจิตอล นอกจากนี้คุณยังสามารถใช้กราฟิกเพื่อวาดผลลัพธ์เช่น: กล่องภาพถ้าคุณต้องการ มิฉะนั้นให้บันทึกผลลัพธ์เป็นไฟล์ อินพุตสามารถใช้เป็นเส้นทางไปยังรูปภาพหรือ URL

สิ่งหนึ่งที่คุณไม่สามารถทำได้คืออาร์เรย์ I / O เช่น ของ triplets (R, G, B)

ไม่ยุ่งเกี่ยวกับอัลฟา ไม่ควร xored ควรเป็น 255 (ค่าสูงสุด) สำหรับทุกพิกเซล

คุณหมายถึง xor แต่ละพิกเซล

คุณไม่ต้องทำแบบนี้ แต่ทางเดียวที่จะทำให้ xor สองพิกเซลคือการใช้ค่า RGB และ xor R1 กับ R2, G1 กับ G2, B1 กับ B2 และรับผลลัพธ์ซึ่งเป็นสีใหม่ของคุณ

เนื่องจากเรามีเพียงสองสีอย่างชัดเจนเมื่อสีเหมือนกันผลลัพธ์จะเป็น (0,0,0) และเมื่อพวกมันแตกต่างกัน (สีขาวคือ 255,255,255 และสีดำเป็น 0,0,0) ในกรณีนี้ผลลัพธ์จะ เท่ากับ 255,255,255

ดังนั้นเมื่อสองพิกเซลแตกต่างกันผลลัพธ์จะเป็นพิกเซลสีขาวหรือเป็นพิกเซลสีดำ

ตัวอย่าง I / O:


อินพุต 1: อินพุต 2:

Input 1 Input 2


เอาท์พุท:

Output


นี่คือเพื่อให้ได้รหัสที่สั้นที่สุด


เราสามารถใช้รูปใส่เป็น URL ได้หรือไม่?
Kritixi Lithos

@KritixiLithos yup ฉันได้แก้ไขมันในความท้าทายสำหรับผู้ชมเพิ่มเติม
P. Ktinos

5
ความท้าทายโบนัส: i.imgur.com/a0M6o9e.pngและi.imgur.com/bP1TsjQ.png
orlp


@ orlp ฉันได้รับรหัส QR
Kritixi Lithos

คำตอบ:


20

ภาษา Expression Fx (ImageMagick) 8 4 ไบต์

การแก้ไข

  • ง่ายกว่าถึงu!=v-4 ไบต์

เนื่องจาก"Fx Expression Language"เห็นได้ชัดว่าทัวริงสมบูรณ์ฉันได้ทำโปรไฟล์คำตอบใหม่อีกครั้ง (Unix Shell + Image Magick)

แข็งแรงเล่นกอล์ฟ

u!=v

Fxไม่รองรับ bitor XORหรือ bitwise NOTดังนั้นฉันจึงใช้!=แทน (ซึ่งใช้งานได้ดีกับภาพ BW ล้วนๆ)

u=> stands for "first image in list"
v=> "second image in list"

อินพุตและเอาต์พุตเป็นค่าปริยาย (ควบคุมโดยล่าม)

การใช้

ImageMagick แปลงยูทิลิตี้ทำหน้าที่เป็นล่าม "Fx Expression Language" เมื่อถูกเรียกด้วย-fxดังแสดงด้านล่าง:

convert $1 $2 -fx u!=v $3

ข้อโต้แย้งคือ:

  1. ภาพที่นำเข้า
  2. ใส่ภาพB
  3. รูปภาพเอาต์พุตO (A ^ B)

ตัวอย่างผลลัพธ์

convert a.png b.png -fx u!=v o.png

enter image description here


15

Mathematica, 37 34 15 ไบต์

ขอบคุณ Ian Miller ที่ตัดจำนวนไบต์มากกว่าครึ่ง!

ImageDifference

ในท้ายที่สุดมีตัวในตัวเสมอ ฟังก์ชั่นนี้ใช้สองภาพเป็นอินพุทและเอาท์พุทภาพ; มันทำอะไรที่ซับซ้อนกว่าสำหรับภาพสี แต่สำหรับขาวดำมันคือแฮคเกอร์

การส่งก่อนหน้า:

ขอบคุณ JungHwan Min สำหรับการบันทึก 3 ไบต์!

Image[BitXor@@Chop[ImageData/@#]]&

ฟังก์ชั่นที่ไม่มีชื่อที่ใช้คู่ของภาพที่สั่งซื้อ (ขนาดที่เข้ากันได้) เป็นอินพุตและส่งกลับภาพที่แสดง ImageDataรับเฉพาะข้อมูลพิกเซลโดยไม่ต้องมีตัวครอบ / เมตาดาต้าทั้งหมด โชคไม่ดีที่มันคืนค่าจำนวนจริงดังนั้นจึงChopจำเป็นที่จะต้องปฏิบัติต่อพวกมันเป็นจำนวนเต็ม BitXorทำสิ่งที่ตรงกับที่บอกไว้ในกระป๋อง (และเธรดเหนือรายการที่ซ้อนกัน) และImageเปลี่ยน RGB ที่เป็นผลลัพธ์กลับเป็นรูปภาพ

การส่งดั้งเดิมซึ่งใช้ URL ที่สั่งซื้อหรือใส่ชื่อไฟล์เป็นอินพุต:

Image[BitXor@@(#~Import~"Data"&/@#)]&

4
สำหรับภาพไบนารีคุณสามารถใช้ ImageDifference[#,#2]&
Ian Miller

10

Java, 336 335 328 ไบต์

import static javax.imageio.ImageIO.*;import java.io.*;public class M{static void main(String[]y)throws Exception{java.awt.image.BufferedImage a=read(new File("a.png"));for(int i=0,j;i<a.getHeight();i++)for(j=0;j<a.getWidth();)a.setRGB(j,i,a.getRGB(j,i)^read(new File("b.png")).getRGB(j++,i));write(a,"png",new File("c.png"));}}

Ungolfed:

import static javax.imageio.ImageIO.*;

import java.io.*;

class M {
    public static void main(String[]y) throws Exception {
        java.awt.image.BufferedImage a = read(new File("a.png"));
        for (int i = 0, j; i < a.getHeight(); i++)
            for (j = 0; j < a.getWidth(); ) a.setRGB(j, i, a.getRGB(j, i) ^ read(new File("b.png")).getRGB(j++, i));
        write(a, "png", new File("c.png"));
    }
}

1
String[] yคุณสามารถบันทึกไบต์โดยการลบช่องว่างระหว่าง เพียงเล็กน้อยกอล์ฟ
HyperNeutrino

Oh dang you're right. Haven't been golfing much lately, totally overlooked that one. Cheers.
Marv

3
You can remove the public from public class M to save 7 bytes
Kritixi Lithos

The file extension .png shouldn't be necessary
Huntro

You can save a byte by doing ..."i++ < a.getHeight();)"
Tatarize

9

Python, 64 60 57 bytes

I'm new to golfing so have some mercy!

from cv2 import*
r=imread;lambda a,b:imshow('c',r(a)^r(b))

Thanks to @Blender and @FlipTack for saving me 7 bytes!


1
Using from cv2 import* should shave off 4 characters.
Blender

1
Here, unnamed lambdas are allowed for function answers, so you can drop the d= :) also, doing r=imread and then using r twice might be shorter
FlipTack

7

Octave, 43 38 34 bytes

@(a,b)imshow(imread(a)~=imread(b))

Thanks to flawr saved me 5 bytes.

Thanks to Luis Mendo saved me 4 bytes suggested to use a~=b instead of xor(a,b).

A function that takes as input file name of the two input images a,b and shows the result.

Previous answer that writes to a file:

@(a,b,c)imwrite(imread(a)~=imread(b),c)

A function that takes as input file name of the two input images a,b and file name of the output image c.

Usage:

#two test images that used in the question
#https://i.stack.imgur.com/UbbfM.png
#https://i.stack.imgur.com/YyZG2.png
A = "UbbfM.png"; 
B = "YyZG2.png"; 
C = "out.png";
(@(a,b,c)imwrite(imread(a)~=imread(b),c))(A,B,C)

Result is saved in out.png


1
Couldn't you use imshow() instead of imwrite()?
flawr

@flawr Of course that will save some bytes:)
rahnema1

1
Can't you use imread(a)~=imread(b) (or +(imread(a)~=imread(b)) if logical input is not allowed by imshow) instead of xor(...)?
Luis Mendo

1
@LuisMendo Thanks, I always learn from your comments!
rahnema1

7

JavaScript (ES6), 333 320 308 299 297 bytes

- 12 20 bytes saved by Ismael Miguel
- 2 bytes saved by user2428118

Expects already loaded images, takes the first input's size as output size and returns a canvas element.

(i,j)=>{c=i=>{with(document.createElement(C='canvas')){width=i.width,height=i.height;return getContext`2d`}},g=i=>{x=c(i);x.drawImage(i,0,0);return x.getImageData(0,0,i.width,i.height)},a=g(i),b=g(j).data,d=a.data,r=c(i);d.forEach((e,i)=>{d[i]=i%4>2?255:e^b[i]});r.putImageData(a,0,0);return r[C]}

let func = (i,j)=>{c=i=>{with(document.createElement(C='canvas')){width=i.width,height=i.height;return getContext`2d`}},g=i=>{x=c(i);x.drawImage(i,0,0);return x.getImageData(0,0,i.width,i.height)},a=g(i),b=g(j).data,d=a.data,r=c(i);d.forEach((e,i)=>{d[i]=i%4>2?-1:e^b[i]});r.putImageData(a,0,0);return r[C]}

window.onload =_=>{
  document.body.appendChild(func(img1, img2));
  }
<img id="img1" crossOrigin="anonymous" src="https://dl.dropboxusercontent.com/s/nnfkzpvabk77pnl/UbbfM.png">
<img id="img2" crossOrigin="anonymous" src="https://dl.dropboxusercontent.com/s/58euf43vcb9pvpa/YyZG2.png">

Ungolfed

(i, j) => {
  c = i => { // an helper to create a canvas object
      with(document.createElement(C='canvas')) {
        width= i.width,
        height= i.height;
        return getContext`2d`
      }
    },
    g = i => { // an helper to get an imageData object
      x = c(i);
      x.drawImage(i, 0, 0);
      return x.getImageData(0, 0, i.width, i.height)
    },
    a = g(i),
    b = g(j).data,
    d = a.data,
    r = c(i);
  d.forEach((e, i) => { // loop through all rgba values
    d[i] = i % 4 > 2 ? 255 : e ^ b[i] // we need to avoid alpha channel...
  });
  r.putImageData(a, 0, 0);
  return r[C]
}

Ps: First time at code-golf, so it can probably be golfed more and my count might be erroneous.

PPs: canvas 2D context has an xor [compositing mode(https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation), but it works on alpha values...

Could be even further golfed (251 bytes) with a fixed 300*150px size (all remaining is black) as in the Processing answer

(i,j)=>{c=i=>{return document.createElement(C='canvas').getContext('2d')},g=i=>{x=c(i);x.drawImage(i,0,0);return x.getImageData(0,0,W=300,W)},a=g(i),b=g(j).data,d=a.data,r=c(i);d.forEach((e,i)=>{d[i]=i%4>2?W:e^b[i]});r.putImageData(a,0,0);return r[C]}


1
Replace the function c with c=i=>{with(document.createElement('canvas')){width=i.width,height=i.height;return getContext`2d`}} and you save 16 bytes.
Ismael Miguel

Can you not xor a black rectangle over the xor of the two images to get back to 255 alpha?
Neil

@IsmaelMiguel, thanks, Not used to use with but seems quite good for golfing ;-) Also, forgot the template literal saves 2 bytes...
Kaiido

@Neil, I'm not sure, here we've got an 8bit array, maybe with a 32bits, that could do it, but it will take more chars...
Kaiido

1
บันทึก 4 ไบต์:(i,j)=>{c=i=>{with(document.createElement(C='canvas')){width=i.width,height=i.height;return getContext`2d`}},g=i=>{x=c(i);x.drawImage(i,0,0);return x.getImageData(0,0,i.width,i.height)},a=g(i),b=g(j).data,d=a.data,r=c(i);d.forEach((e,i)=>{d[i]=i%4>2?255:e^b[i]});r.putImageData(a,0,0);return r[C]}
2428118

7

กำลังประมวลผล, 124 118 117 ไบต์

void m(PImage a,PImage q){for(int i=0,j;i<400;i++)for(j=0;j<400;point(i,j++))stroke((a.get(i,j)^q.get(i,j))<9?0:-1);}

การใช้งาน:

หมายเหตุ:รหัสนี้สามารถรองรับภาพได้สูงสุด400px(ด้วยการแก้ไขสามารถรองรับสูงถึง 999 สำหรับจำนวนไบต์เดียวกัน) พื้นที่ "เหลือ" ใด ๆ จะเป็นสีดำดังนั้นเพื่อผลลัพธ์ที่ดีที่สุดขนาดภาพควรเป็นขนาดเดียวกับขนาดในรหัส (รวมถึงsize()ความต้องการที่จะเปลี่ยนแปลงด้วยขนาดที่อัปเดต)

m(loadImage("http://i.imgur.com/a0M6o9e.png"),loadImage("http://i.imgur.com/bP1TsjQ.png"));

enter image description here

m(loadImage("https://i.stack.imgur.com/UbbfM.png"),loadImage("https://i.stack.imgur.com/YyZG2.png"));

enter image description here

Ungolfed

void Q106945(PImage a,PImage q){     // takes two images as input
  for(int i=0,j;i<400;i++)           // looping through the x-coordinates
    for(j=0;j<400;point(i,j++))      // looping through the y-coordinates
      stroke((a.get(i,j)^q.get(i,j))<9?0:-1);
/*
Here we have to colour the point according to the xor. So we do a simple 
a.get(i,j)^q.get(i,j). But since the alpha gets xored, instead of outputting white, this
outputs a colour with alpha 0 (completely invisible). So to fix this I have a ternary that
checks the value and changes the colour accordingly. At the end of all this, the third 
statement of the for-loop with j gets triggered since all this code is in this for-loop. 
Now we draw a point over the coordinate with the colour we have chosen before.
*/
}

7

MATL 10 ไบต์

YiiYiY~1YG

คำอธิบาย

นี่เป็นคำตอบเดียวกับโซลูชัน Octaveที่มีอยู่เดิม: ใช้ชื่อไฟล์หรือ URL ของรูปภาพทั้งสองเป็นอินพุตและแสดงผลลัพธ์บนหน้าจอ

Yi    % Read first image from the URL or filename (implicit input)
i     % Get the second URL or filename as input
Yi    % Read that second image
Y~    % XOR the two images
1     % Push 1 (needed to make YG act as imagesc)
YG    % Display result using the MATLAB imagesc function

การใช้

>> matl
 > YiiYiY~1YG
 > 
> 'https://i.stack.imgur.com/UbbfM.png'
> 'https://i.stack.imgur.com/YyZG2.png'

1
นี่คือ 10 ไบต์
Erik the Outgolfer

3

Perl, 260 ไบต์

251 ไบต์ของรหัส + 9 -MImagerไบต์

($i,$j)=map{new Imager(file,pop)}0,1;$p=getpixel;for$x(0..$i->getwidth()-1){$i->setpixel(x=>$x,y=>$_,color=>[map{($j->$p(%t)->rgba)[$c++%3]^$_?0:255}($i->$p(%t=(x=>$x,y=>$_,type=>'8bit'))->rgba)[0..2]])for 0..$i->getheight()-1}$i->write(file=>'a.png')

ฉันไม่แน่ใจว่า Perl เป็นภาษาที่ดีที่สุดสำหรับความท้าทายนี้ แต่ฉันอยากรู้ว่าภาพความคิดเห็นของ @ orlp คืออะไร และมันทำให้ฉันใช้โมดูลกราฟิกเล็กน้อยนั่นเป็นเรื่องดี และฉันสนุกกับการเขียนโปรแกรมมัน!

รุ่นที่อ่านได้มากขึ้น:

use Imager;
$img1 = new Imager( file => $ARGV[1] );
$img2 = new Imager( file => $ARGV[0] );

for $x ( 0 .. $img1->getwidth()-1 ) {
    for $y ( 0 .. $img1->getheight()-1 ) {
    ($r1, $g1, $b1) = $img1->getpixel( x => $x, y => $y, type => "8bit" )->rgba();
    ($r2, $g2, $b2) = $img2->getpixel( x => $x, y => $y, type => "8bit" )->rgba();
    $r = $r1 ^ $r2 ? 0 : 255 ;
    $g = $g1 ^ $g2 ? 0 : 255 ;
    $b = $b1 ^ $b2 ? 0 : 255 ;
    $img1->setpixel( x => $x, y => $y , color => [ $r, $g, $b] );
    }
}
$img1->write( file => 'a.png' )

You'll need to install Imager if you want to try it, but it's quite simple: just run (echo y;echo) | perl -MCPAN -e 'install Imager' in your terminal.


3

LÖVE2D, 199 bytes

u,c=... i=love.image.newImageData a=math.abs X=i(u)Y=i(c)Z=i(X:getDimensions())Z:mapPixel(function(x,y)r,g,b=X:getPixel(x,y)R,G,B=Y:getPixel(x,y)return a(r-R),a(g-G),a(b-B)end)Z:encode("png","Z")

Simple enough, takes two image files on the command line, outputs a file called "Z" to the Love directory. Also works for full colour images!


1
@MDXF love2d.org
ATaco

2

J, 54 bytes

load'bmp'
'o'writebmp~256#.255*~:&*&((3#256)#:readbmp)

Takes two arguments where each is the path to an input image in bmp format. Each image is read as a matrix of 24-bit RGB integers and parsed into a triplet of 8-bit RGB values, the sign of each is taken, and the two matrices are XOR'd together. The result is then scaled by 255, converted back from a triplet of base 256 numbers into an integer, and written to an output bmp file named o.


2

C, 189 bytes

#include<stdio.h>
s,t[9];
#define o(f,p)int*f=fopen(p,"ab+");
#define f(p,q,r)o(a,p)o(b,q)o(c,r)fscanf(a,"%*s %*d %*d %n",&s);for(fwrite(t,1,fread(t,1,s,b),c);s=~getc(a);putc(~s^getc(b),c))

Operates on PBM images. Call f(a, b, out) with the names of both input files and the output file.

Assumptions:

  • Both input image headers are identical (whitespace included), and are less than 9 * sizeof(int) characters.

  • We're on a nice OS that flushes and closes leaked files.

  • EOF == -1

Ungolfed and explained: (backslashes omitted)

// Scratch variable and "big enough" buffer
s, t[9];

// Opens a file in read/append binary mode
#define o(f,p)int*f=fopen(p,"ab+");

#define f(p, q, r)

    // Open the three file pointers a, b, c from the paths p, q, r
    o(a, p)
    o(b, q)
    o(c, r)

    // Read from a to locate the end of the PBM header
    fscanf(a, "%*s %*d %*d %n", &s);

    for(
        // Read the header from b into the buffer,
        // then write it back from the buffer to c
        fwrite(t, 1, fread(t, 1, s, b), c);

        // Loop condition: get the next byte from a
        // and check for EOF with a bitwise-not
        // (Assumes that EOF == -1)
        s = ~getc(a);

        // Loop increment: get the next byte from b,
        // flip s back, xor and write to c
        putc(~s ^ getc(b), c)

    ) // Snatch the semicolon from the call syntax :)

C (spec-bending), 149 bytes

#include<stdio.h>
t[7];
#define o(f,p,u)int*f=fopen(p,"ab+");u(t,1,7,f);
#define f(p,q,r)o(a,p,fread)o(b,q,fread)o(c,r,fwrite)putc(getc(a)^getc(b),c)

Still uses PBM files, but now:

  • The image has to be one pixel high and 8 pixels wide or less, because PBM packs 8 pixels in a byte.

  • The header has to be 7 bytes (e.g. P4 8 1 with a trailing space).

Both files are seeked forwards while filling t with their header, then the last bytes are read, xor'd and written back. Takes advantage of fread and fwrite having similar parameter lists to factor all three operations on the header behind the same macro.


2

R, 45 bytes

p=png::readPNG;plot(as.raster(+(p(a)!=p(b))))

aand b represent the file names of the two image files.

Example:

a <- "YyZG2.png"
b <- "UbbfM.png"
p=png::readPNG;plot(as.raster(+(p(a)!=p(b))))

Output:

enter image description here


2

Processing, 82 bytes

void x(PImage a,PImage b){int x=b.width;b.blend(a,0,0,x,x,0,0,x,x,32);set(0,0,b);}

Abuses Processing's extensive drawing functions to avoid actually doing any XORing. Blends the two images together with DIFFERENCE mode and draws them to the screen.

Usage

x(loadImage("http://i.imgur.com/a0M6o9e.png"),loadImage("http://i.imgur.com/bP1TsjQ.png"));

Ungolfed

void xor(PImage a, PImage b) {
  int x = a.width;
  b.blend(a, 0, 0, x, x, 0, 0, x, x, DIFFERENCE);
  set(0, 0, b);
}

Nice golf! It's really smart that you used 32 instead of DIFFERENCE. This would be a nice tip for golfing: codegolf.stackexchange.com/questions/26809/… :)
Kritixi Lithos

2

C#, 233 bytes

using System.Drawing;class C{static void Main(){Bitmap
a=new Bitmap("a"),b=new Bitmap("b");for(int
x=0,y=0;;)try{a.SetPixel(x,y,a.GetPixel(x,y)==b.GetPixel(x,y)?Color.Black:Color.White);x++;}catch{if(x<1)break;x=0;++y;}a.Save("c");}}

Thanks to Unknown6656 for the tip that command line arguments are not necessary. The program now reads from files "a" and "b" and writes to file "c" in the same format as "a". Off by one error fixed too.

It sets each pixel to black if the colour is the same, otherwise white.

To save bytes, it catches out of bounds exceptions, rather than checking the Width and Height properties of the Bitmaps. Each time x goes out of bounds it is reset to 0, and y is incremented. When y goes out of bounds, x is 0 and the loop breaks to save the image and quit.

Example compile using csc and run using mono:

csc xor.cs

mono xor.exe

You could drop the token (string[] v) inside the main-declaration, as C# does not explicitly needs it to run an application
unknown6656

1

Clojure, 300 bytes

(ns s(:import[java.io File][java.awt.image BufferedImage][javax.imageio ImageIO]))(defn -main[](let[a(ImageIO/read(File."a.png"))](doseq[i(range(.getHeight a))j(range(.getWidth a))](.setRGB a j i(bit-xor(.getRGB a j i)(.getRGB(ImageIO/read(File."b.png")) j i))))(ImageIO/write a"png"(File."c.png"))))

Blatant rip-off of the Java answer. I didn't know how to do the challenge, but was curious how well the Java solution translated into Clojure. It was pretty straightforward. The ungolfed code is actually kind of pretty.

This was the first code-golf challenge I've done that included imports. There's probably a way to optimize them to save some bytes.

Ungolfed:

(ns bits.golf.bit-or-picts
  (:import [java.io File]
           [java.awt.image BufferedImage]
           [javax.imageio ImageIO]))

(defn -main []
  (let [^BufferedImage a (ImageIO/read (File. "a.png"))
        ^BufferedImage b (ImageIO/read (File. "b.png"))]
    (doseq [i (range (.getHeight a))
            j (range (.getWidth a))]
      (.setRGB a j i
                (bit-xor (.getRGB a j i)
                         (.getRGB b j i))))
    (ImageIO/write a "png" (File. "c.png"))))

1

PHP, 246 243 bytes

I can probably golf this down more.

$o=imagecreatetruecolor($w=max(imagesx($a=($i=imagecreatefrompng)($argv[1])),imagesx($b=$i($argv[2]))),$h=max(imagesy($a),imagesy($b)));for(;$k<$w*$h;)imagesetpixel($o,$x=$k%$w,$y=$k++/$w,($t=imagecolorat)($a,$x,$y)^$t($b,$x,$y));imagepng($o);

Run it from the command line like this:

php -d error_reporting=0 -r "$o=imagecreatetruecolor($w=max(imagesx($a=($i=imagecreatefrompng)($argv[1])),imagesx($b=$i($argv[2]))),$h=max(imagesy($a),imagesy($b)));for(;$k<$w*$h;)imagesetpixel($o,$x=$k%$w,$y=$k++/$w,($t=imagecolorat)($a,$x,$y)^$t($b,$x,$y));imagepng($o);" "http://i.stack.imgur.com/UbbfM.png" "http://i.stack.imgur.com/YyZG2.png" > output.png

Defining the function name variables at their first occurence can help: $i=imagecreatefrompng;$a=$i($argv[1]) is one byte longer than $a=($i=imagecreatefrompng)($argv[1]). And you could try palette images with a two color palette.
Titus

I tried to define it at the first occurrence but I kept getting a fatal error. I'll try again later when I have time. Maybe I didn't do it correctly.
Kodos Johnson

($f=func)(params) requires PHP 7.
Titus

@Titus ah ok thanks. That took me down 3 bytes.
Kodos Johnson

Here are 7 more bytes: Replace for(;$k<$w*$h;) with for(;$y<$h;$y+=1/$w), $x=$k%$w, $y=$k++/$w with $x, $y and the last $x with $x++. (assuming there are no rounding errors for any reasonable image sizes)
Titus

0

Node.js, 156 135 bytes

(a,b)=>(f=require('fs')).writeFile(a+b,((s=f.readFileSync)(a)+'').replace(/\d+$/,(c,d)=>[...c].map((e,f)=>+!(e^(s(b)+b)[f+d])).join``))

Input and output image files should be in the PBM (P1) format, where the first line is P1 [width] [height], and the second line is the b/w ascii values without spaces.

Here's a the input images followed by the xor output (32x32 pixels):

Input #1 Input #2 Output

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