15
\$\begingroup\$

Create program or function that takes file name as an argument or reads it from standard input, and completes the following task:

  1. Read image from a png file (name given as argument).
  2. Reverse colors in that image, so that for example dark green (0, 75, 30) would become (255, 180, 225) (because 255-0=255, 255-75=180 and 255-30=225). You should not change alpha channel value.
  3. Output that image to a file called a.png (in png format), or show it in GUI window.

This is . Standard loopholes apply.

\$\endgroup\$
5
  • \$\begingroup\$ Is it required to support any optional png features? Are built-in png loading/writing functions acceptable? \$\endgroup\$
    – Sparr
    Commented Mar 28, 2016 at 22:42
  • \$\begingroup\$ @Sparr Optional feature support is optional. Built-in functions are not explicitly disallowed, so I'll assume they are allowed. \$\endgroup\$ Commented Mar 28, 2016 at 22:44
  • 5
    \$\begingroup\$ PNG files can be indexed (each pixel contains a pointer to a color in the colormap) or truecolor (each pixel contains the actual color). Which one do we need to support? Can we choose? In fact, there are five different subformats regarding color. So... ? \$\endgroup\$
    – Luis Mendo
    Commented Mar 28, 2016 at 23:20
  • \$\begingroup\$ @DonMuesli I think any method that provides correct result will be fine. You can assume that the color isn't greyscale, and supporting alpha-channel is optional. I think that using any other mode is acceptable, as long as the task will still be reversing the colors, and colors have (r,g,b)-values. \$\endgroup\$ Commented Mar 29, 2016 at 9:10
  • 1
    \$\begingroup\$ Can I use just CSS? \$\endgroup\$
    – Rizze
    Commented Sep 8, 2016 at 8:36

18 Answers 18

29
\$\begingroup\$

ImageMagick display -fx, 3 7 18 24 bytes

1-u

The ImageMagick tool display with the fx parameter can apply the above program to a png given as the parameter and display the results on screen.

Check out my post on meta about ImageMagick as a programming language. I wrote a prime tester over there as a proof of concept.

Re byte counting, display -fx code filename is equivalent to perl -e code filename, where we traditionally count just code for length.

\$\endgroup\$
3
  • \$\begingroup\$ Is this not a standard loophole? It's gotten plenty of upvotes, but it seems like it should be. I guess if Mathematica can have a bunch of these functions built-in, then using any pre-released application (before the asking of the question) to do it for you is fair game, so long as it accepts command-line arguments? \$\endgroup\$ Commented Mar 29, 2016 at 16:01
  • 1
    \$\begingroup\$ @NateDiamond Give me about 5 minutes to finish my meta post about "is imagemagick a programming language" and I'll cut this down to 7 bytes and address your question at the same time :) \$\endgroup\$
    – Sparr
    Commented Mar 29, 2016 at 16:03
  • 7
    \$\begingroup\$ @NateDiamond meta.codegolf.stackexchange.com/questions/8828/… \$\endgroup\$
    – Sparr
    Commented Mar 29, 2016 at 16:18
21
\$\begingroup\$

Pyth, 16 15 13 bytes

.w-LLL255'z\a

Outputs to a.png.

          z    read input
         '     read as RGB triples from file
   LLL         map over rows, then triples, then individual values...
  -   255      ...subtract from 255
.w         \a  write as image to a.png

Thanks to Jakube for 2 bytes!

\$\endgroup\$
12
  • 4
    \$\begingroup\$ man, i've gotta learn pyth \$\endgroup\$ Commented Mar 28, 2016 at 22:53
  • 1
    \$\begingroup\$ Does Pyth not have bitwise negation (~ or similar)? \$\endgroup\$ Commented Mar 29, 2016 at 7:33
  • \$\begingroup\$ @PeterTaylor I don't think it does, surprisingly. (In any case, it would have to be restricted to 8 bits.) \$\endgroup\$
    – Doorknob
    Commented Mar 29, 2016 at 10:55
  • \$\begingroup\$ is there no way to deeply-map with a pfn? \$\endgroup\$
    – Ven
    Commented Mar 29, 2016 at 11:09
  • 1
    \$\begingroup\$ @ven @Doorknob Actually you can do it: .w-LLL255'z\a. But don't ask me how this works or why you need LLL and not something like LMM. \$\endgroup\$
    – Jakube
    Commented Mar 29, 2016 at 12:32
18
\$\begingroup\$

MATL, 10 bytes

255iYi-IYG

There are five different subformats of PNG, depending on how color is encoded. None of them seems to be more "optional" than the others. I chose the most flexible one, Truecolor, in which each pixel can have an arbitrary color. The above code also supports Truecolor with alpha, ignoring the alpha channel.

To know the color subformat of a PNG file: look for the byte sequence [73 72 68 82] near the beginning of the file; and the tenth byte from there will have one of the five values in the table linked above.

How the code works

Pretty straightforward:

255    % push 255 to the stack
i      % input filename with extension '.png'
Yi     % read contents of that file as (truecolor) image
-      % subtract
IYG    % show image

Example

I couldn't resist seeing myself inverted, so I downloaded this image (which is in subformat Truecolor with alpha), ran the code (second line is user input)

>> matl 255iYi-IYG
> 'C:\Users\Luis\Desktop\me.png'

and got

enter image description here

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Your avatar is actually you? I thought it was just your helmet! :P \$\endgroup\$
    – Downgoat
    Commented Mar 29, 2016 at 22:15
  • 1
    \$\begingroup\$ I thought PNG and all means long code, but 10 bytes? Wow. \$\endgroup\$ Commented Sep 4, 2016 at 17:02
17
\$\begingroup\$

Java, 295

import javax.imageio.*;class V{public static void main(String[]a)throws
Exception{java.awt.image.BufferedImage m=ImageIO.read(new
java.io.File(a[0]));for(int
x=m.getWidth(),y;x-->0;)for(y=m.getHeight();y-->0;)m.setRGB(x,y,m.getRGB(x,y)^-1>>>8);ImageIO.write(m,"png",new
java.io.File("a.png"));}}
\$\endgroup\$
4
  • 1
    \$\begingroup\$ I like how x-- and x>0 together make a litte arrow showing that x goes up to 0. Why have I never seen/used that before? \$\endgroup\$
    – LuWi
    Commented Mar 29, 2016 at 14:41
  • \$\begingroup\$ Import java.io.File? \$\endgroup\$
    – nickb
    Commented Mar 29, 2016 at 14:56
  • 1
    \$\begingroup\$ @LuWi hehe, I've seen and used it before, some people call it the "goes to" operator, and it's pretty golfy :) \$\endgroup\$ Commented Mar 29, 2016 at 15:40
  • \$\begingroup\$ @nickb even if you use the shorter import java.io.*;, it doesn't save any bytes but actually increases the size. \$\endgroup\$ Commented Mar 29, 2016 at 15:42
4
\$\begingroup\$

R, 124 bytes

p=png::readPNG(readline());p[,,-4]=1-p[,,-4];png("a.png",h=nrow(p),w=ncol(p));par(mar=rep(0,4));plot(as.raster(p));dev.off()

Reads in file name through stdin (readline()).

p=png::readPNG(readline()) #Reads in png as an RGBA array on range [0,1]
p[,,-4]=1-p[,,-4] #Takes the opposite value except on alpha layer
png("a.png",h=nrow(p),w=ncol(p)) #Prepares output png of same size as input
par(mar=rep(0,4)) #Makes the png take the full space of the figure region
plot(as.raster(p)) #Transforms p as a raster so that it can be plotted as is.
dev.off() #Closes the plotting device.

Example Input/Output using the first png I found on this computer :)

Input Output

\$\endgroup\$
3
\$\begingroup\$

CSS, 19 Bytes

*{filter:invert(1)}

http://output.jsbin.com/suqayudoyu

\$\endgroup\$
2
  • \$\begingroup\$ The two images don't appear to have any change. \$\endgroup\$
    – clismique
    Commented Sep 8, 2016 at 12:07
  • \$\begingroup\$ Use Firefox, caniuse.com/#feat=css-filters \$\endgroup\$
    – Rizze
    Commented Sep 8, 2016 at 12:27
2
\$\begingroup\$

Tcl, 176 bytes

foreach r [[image c photo -file {*}$argv] d] {set x {}
foreach c $r {lappend x [format #%06X [expr "0xFFFFFF-0x[string ra $c 1 end]"]]}
lappend y $x}
image1 p $y
image1 w a.png

Loads the PNG via the photo image type, gets the image data, converting each row and color by subtracting from #FFFFFF, then writes the file back to disk (as "a.png").

For best results, use TrueColor PNGs, since Tk will try to use the same color resolution as the source image data.

To see the image without sampling problems, add

pack [label .i -image image1]

to the end. (Obviously, this is longer than the disk-save option.)

\$\endgroup\$
1
  • \$\begingroup\$ You can ave bytes replacing foreachby lmap \$\endgroup\$
    – sergiol
    Commented Feb 15, 2017 at 2:15
2
\$\begingroup\$

Mathematica, 140 bytes

Export["a.png",SetAlphaChannel[ColorCombine[Most@#],Last@#]&@MapAt[Image[1-ImageData@#]&,ColorSeparate[Import[#],{"R","G","B","A"}],{;;3}]]&
\$\endgroup\$
2
  • \$\begingroup\$ Note that you can save two bytes by changing Import[#] to Import@#, and same for ColorCombine[Most@#]. \$\endgroup\$ Commented Apr 6, 2017 at 7:39
  • \$\begingroup\$ Why wouldn't a simple ColorNegate@*Import be a complete answer? \$\endgroup\$ Commented Dec 31, 2018 at 3:19
2
\$\begingroup\$

cmd + IrfanView, 19 characters

i_view32 %1 /invert

Just the expensive alternative of Sparr's answer.

\$\endgroup\$
2
\$\begingroup\$

Julia, 94 79 bytes

using FileIO
save(ARGS[1],map(x->typeof(x)(1-x.r,1-x.g,1-x.b,1),load(ARGS[1])))

This is a full program that takes a file name as a command line argument and overwrites the given file with the inverted image. It requires that the FileIO and Image package be installed. The latter doesn't need to be imported though.

Call the program from the command line like julia filename.jl /path/to/image.png.

Ungolfed:

using FileIO # required for reading and writing image files

# Load the given image into a matrix where each element is an RGBA value
a = load(ARGS[1])

# Construct a new image matrix as the inverse of `a` by, for each element
# `x` in `a`, constructing a new RGBA value as 1 - the RGB portions of
# `x`, but with an alpha of 1 to avoid transparency.
b = map(x -> typeof(x)(1 - x.r, 1 - x.g, 1 - x.b, 1), a)

# Save the image using the same filename
save(ARGS[1], b)

Example:

regular inverted

\$\endgroup\$
1
  • 1
    \$\begingroup\$ The magpie (?) looks seriously depressed on the second image. \$\endgroup\$
    – Bálint
    Commented May 3, 2016 at 7:33
1
\$\begingroup\$

Python + PIL, 85 bytes

from PIL import Image
lambda a:Image.eval(Image.open(a),lambda x:255-x).save('a.png')

This defines an anonymous function that takes a filename as a string and saves the resultant image to a.png.

Test run:

llama llama out

\$\endgroup\$
6
  • 1
    \$\begingroup\$ -3 bytes: from PIL import Image as I, followed by replacing Image in the function with I \$\endgroup\$
    – Tim Čas
    Commented Aug 30, 2016 at 23:50
  • \$\begingroup\$ I'm fairly sure that simply import Image will work, shaving off a whole load of bytes \$\endgroup\$
    – Beta Decay
    Commented Aug 31, 2016 at 10:36
  • \$\begingroup\$ save 11 bytes with from PIL.Image import* \$\endgroup\$
    – Aaron
    Commented Sep 8, 2016 at 14:14
  • \$\begingroup\$ I think this accidentally inverts the alpha channel as well. Apparently the eval function runs against all "bands", including the alpha one. Here is what I get when inverting the Firefox logo - imgur.com/a/wV3MSQX \$\endgroup\$
    – dana
    Commented Dec 31, 2018 at 20:12
  • 1
    \$\begingroup\$ @dana Per the OP's comment, supporting alpha channels is optional. \$\endgroup\$
    – user45941
    Commented Dec 31, 2018 at 22:12
1
\$\begingroup\$

C + stb_image + stb_image_write, 175 162 bytes (or +72=247 234)

My first submission on this site ever.

#include"stb_image.h"
#include"stb_image_write.h"
x,y,c,i;f(char*d){d=stbi_load(d,&x,&y,&c,i=0);for(;i<x*y*c;i++)d[i]=255-d[i];stbi_write_png("a.png",x,y,c,d,0);}

Could probably shave off a few bytes. Needs stb_* implementation to either be in a separate library, or at the start of this file with:

#define STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_WRITE_IMPLEMENTATION

I didn't include it in the count because it's essentially part of the library (esp. if it's compiled separately). +72 bytes to add that if required, however.


Update 1:

Realized only a function (as opposed to an entire program) is acceptable, shaving off 15 bytes. The old implementation (which is an entire program), for reference:

x,y,i;main(int c,char**d){*d=stbi_load(d[1],&x,&y,&c,0);for(;i<x*y*c;i++)i[*d]=255-i[*d];stbi_write_png("a.png",x,y,c,*d,0);}
\$\endgroup\$
1
\$\begingroup\$

Java, 300 298 bytes

import javax.swing.*;void c(String f)throws Exception{java.awt.image.BufferedImage r=javax.imageio.ImageIO.read(new java.io.File(f));for(int i=0;i++<r.getWidth();)for(int j=0;j++<r.getHeight();)r.setRGB(i,j,(0xFFFFFF-r.getRGB(i,j))|0xFF000000);JOptionPane.showMessageDialog(null,new ImageIcon(r));}
\$\endgroup\$
1
\$\begingroup\$

MATLAB / Octave, 31 bytes

Code:

imshow(imcomplement(imread(x)))

Example:

imshow(imcomplement(imread('balloons.png')))

enter image description here              enter image description here

Explanation:

Read the image, x, from a graphics file, complement the image, and then display the image.

\$\endgroup\$
1
  • \$\begingroup\$ The code assumes that x is predefined, which is not allowed. You can turn it into a lambda function for +4 bytes with @(x). \$\endgroup\$
    – user45941
    Commented Dec 31, 2018 at 22:14
0
\$\begingroup\$

FFmpeg, 10 bytes

Edit: Taking a cue from @Sparr's answer

-vf negate

(the above when passed to ffplay alongwith the image name, will display the negated image)


ffplay %1 -vf negate

The above is saved as a batch file.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Is FFmpeg a programming language by our standards? I don't know enough about it to be sure. Perhaps ask on meta? \$\endgroup\$
    – user45941
    Commented May 3, 2016 at 7:55
0
\$\begingroup\$

Racket 282 bytes

(λ(fname)(let*((i(make-object bitmap% fname))(w(send i get-width))(h(send i get-height))(pixels(make-bytes(* w h 4)))(i2(make-object bitmap% w h)))
(send i get-argb-pixels 0 0 w h pixels)(send i2 set-argb-pixels 0 0 w h(list->bytes(map(lambda(x)(- 255 x))(bytes->list pixels))))i2))

More readable form:

(define(f fname)
  (let*(
        (i (make-object bitmap% fname))
        (w (send i get-width))
        (h (send i get-height))
        (pixels (make-bytes(* w h 4)))
        (i2 (make-object bitmap% w h)))
    (send i get-argb-pixels 0 0 w h pixels)
    (send i2 set-argb-pixels 0 0 w h
          (list->bytes
           (map
            (lambda(x) (- 255 x))
            (bytes->list pixels))))
    i2))

Usage:

(f "myimg.png")
\$\endgroup\$
0
\$\begingroup\$

Golang, 311 bytes

package main
import("image"
."image/png"
."image/color"
."os")
func main(){f,_:=Open(Args[1])
i,_:=Decode(f)
q:=i.Bounds()
n:=image.NewRGBA(q)
s:=q.Size()
for x:=0;x<s.X;x++{for y:=0;y<s.Y;y++{r,g,b,a:=i.At(x,y).RGBA()
n.Set(x,y,RGBA{byte(255-r),byte(255-g),byte(255-b),byte(a)})}}
o,_:=Create("o")
Encode(o,n)}

ungolfed

package main
import(
    "image"
    "image/png"
    "image/color"
    "os"
)

func main(){
    // open a png image.
    f, _ := os.Open(Args[1])

    // decode the png image to a positive image object(PIO).
    p, _ := png.Decode(f)

    // get a rectangle from the PIO.
    q := p.Bounds()

    // create a negative image object(NIO).
    n := image.NewRGBA(q)

    // get the size of the PIO.
    s := q.Size()

    // invert the PIO.
    for x := 0; x < s.X; x++ {
        for y := 0; y < s.Y; y++ {
            // fetch the value of a pixel from the POI.
            r, g, b, a := p.At(x, y).RGBA()

            // set the value of an inverted pixel to the NIO.
            // Note: byte is an alias for uint8 in Golang.
            n.Set(x, y, color.RGBA{uint8(255-r), uint8(255-g), uint8(255-b), uint8(a)})
        }
    }

    // create an output file.
    o, _ := os.Create("out.png")


    // output a png image from the NIO.
    png.Encode(o, n)
}
\$\endgroup\$
0
\$\begingroup\$

Python 2 + OpenCV, 55 bytes

import cv2
cv2.imwrite('a.png',255-cv2.imread(input()))

The OpenCV library uses NumPy arrays to read, process, and write images. Below is an example of this script inverting an image found on mozilla.org.

Edge Artwork Inverted

All channels, including the alpha channel, will be inverted. This is problematic for images that have transparency. But as @Mego pointed out, support for the alpha channel is optional.

Below is an 82 byte commented version that property handles the alpha channel.

import cv2                # import OpenCV library
i=cv2.imread(input(),-1)  # image file name is specified from stdin
                          # read with the IMREAD_UNCHANGED option
                          # to preserve transparency
i[:,:,:3]=255-i[:,:,:3]   # invert R,G,B channels
cv2.imwrite('a.png',i)    # output to a file named a.png

As shown below, this properly handles inverting the Firefox logo while preserving the transparent background.

Firefox Logo Inverted

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.