Invertir imagen png


15

Cree un programa o función que tome el nombre del archivo como argumento o lo lea de la entrada estándar y complete la siguiente tarea:

  1. Leer la imagen de un archivo png (nombre dado como argumento).
  2. Invierta los colores en esa imagen, de modo que, por ejemplo, el verde oscuro (0, 75, 30) se convierta en (255, 180, 225) (porque 255-0 = 255, 255-75 = 180 y 255-30 = 225). No debe cambiar el valor del canal alfa.
  3. Imprima esa imagen en un archivo llamado a.png(en formato png) o muéstrela en la ventana de la GUI.

Este es el . Se aplican lagunas estándar.


¿Es necesario admitir las funciones png opcionales? ¿Son aceptables las funciones de carga / escritura png incorporadas?
Sparr

@Sparr El soporte de funciones opcionales es opcional . Las funciones integradas no están explícitamente prohibidas, por lo que supongo que están permitidas.
Hannes Karppila

55
Los archivos PNG pueden indexarse ​​(cada píxel contiene un puntero a un color en el mapa de colores) o truecolor (cada píxel contiene el color real). ¿Cuál necesitamos apoyar? Podemos elegir? De hecho, hay cinco subformatos diferentes con respecto al color. Entonces... ?
Luis Mendo

@DonMuesli Creo que cualquier método que proporcione el resultado correcto estará bien. Puede suponer que el color no es en escala de grises, y el soporte del canal alfa es opcional. Creo que usar cualquier otro modo es aceptable, siempre y cuando la tarea siga invirtiendo los colores y los colores tengan valores (r, g, b).
Hannes Karppila

1
¿Puedo usar solo CSS?
Rizze

Respuestas:


30

ImageMagick display -fx, 3 7 18 24 bytes

1-u

La herramienta ImageMagick displaycon el fxparámetro puede aplicar el programa anterior a un png dado como parámetro y mostrar los resultados en la pantalla.

Mira mi publicación sobre meta sobre ImageMagick como lenguaje de programación. Escribí un probador principal allí como prueba de concepto.

El recuento de bytes, display -fx code filenamees equivalente a perl -e code filename, donde tradicionalmente contamos solo codepor longitud.


¿No es esto una escapatoria estándar? Ha recibido muchos votos a favor, pero parece que debería serlo. Supongo que si Mathematica puede tener un montón de estas funciones incorporadas, entonces usar cualquier aplicación prelanzada (antes de hacer la pregunta) para hacerlo por usted es un juego justo, siempre que acepte argumentos de línea de comandos.
Nate Diamond

1
@NateDiamond Dame unos 5 minutos para terminar mi meta publicación sobre "es una imagen mágica de un lenguaje de programación" y reduciré esto a 7 bytes y responderé tu pregunta al mismo tiempo :)
Sparr


21

Pyth, 16 15 13 bytes

.w-LLL255'z\a

Salidas a 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

¡Gracias a Jakube por 2 bytes!


44
hombre, tengo que aprender pyth
undergroundmonorail

1
¿Pyth no tiene negación bit a bit ( ~o similar)?
Peter Taylor

@ PeterTaylor No creo que lo haga, sorprendentemente. (En cualquier caso, tendría que estar restringido a 8 bits.)
Pomo de la puerta

¿no hay forma de mapear profundamente con un pfn?
Ven

1
@ven @Doorknob En realidad, usted puede hacerlo: .w-LLL255'z\a. Pero no me preguntes cómo funciona esto o por qué lo necesitas LLLy no algo así LMM.
Jakube

18

MATL , 10 bytes

255iYi-IYG

Hay cinco subformatos diferentes de PNG, dependiendo de cómo se codifica el color. Ninguno de ellos parece ser más "opcional" que los demás. Elegí el más flexible Truecolor, en el que cada píxel puede tener un color arbitrario. El código anterior también es compatible Truecolor with alpha, ignorando el canal alfa.

Para conocer el subformato de color de un archivo PNG: busque la secuencia de bytes [73 72 68 82]cerca del comienzo del archivo; y el décimo byte desde allí tendrá uno de los cinco valores en la tabla vinculada anteriormente .

Como funciona el código

Muy claro:

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

Ejemplo

No pude resistir verme invertido, así que descargué esta imagen (que está en subformato Truecolor with alpha), ejecuté el código (la segunda línea es entrada del usuario)

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

y consiguió

ingrese la descripción de la imagen aquí


1
¿Tu avatar eres realmente tú? ¡Pensé que era solo tu casco! : P
Downgoat

1
Pensé que PNG y todo significa código largo, pero ¿10 bytes? Guau.
Buffer Over Read

17

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

1
Me gusta cómo x-- yx> 0 juntos forman una pequeña flecha que muestra que x sube a 0. ¿Por qué nunca antes había visto / usado eso?
LuWi

Importar java.io.File?
nickb

1
@LuWi jeje, lo he visto y lo he usado antes, algunas personas lo llaman el operador "va a", y es bastante golfoso :)
Aditsu

@nickb, incluso si utiliza el más corto import java.io.*;, no guarda ningún byte, pero en realidad aumenta el tamaño.
aditsu

4

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

Lee el nombre del archivo a través de 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.

Ejemplo de entrada / salida usando el primer png que encontré en esta computadora :)

Entrada Salida



2

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

Carga el PNG a través del phototipo de imagen, obtiene los datos de la imagen, convierte cada fila y color restando de #FFFFFF, luego vuelve a escribir el archivo en el disco (como "a.png").

Para obtener mejores resultados, use PNG TrueColor, ya que Tk intentará usar la misma resolución de color que los datos de la imagen de origen.

Para ver la imagen sin problemas de muestreo, agregue

pack [label .i -image image1]

hasta el final. (Obviamente, esto es más largo que la opción de guardar el disco).


Puede reemplazar los bytes foreachporlmap
sergiol

2

Mathematica, 140 bytes

Export["a.png",SetAlphaChannel[ColorCombine[Most@#],Last@#]&@MapAt[Image[1-ImageData@#]&,ColorSeparate[Import[#],{"R","G","B","A"}],{;;3}]]&

Tenga en cuenta que puede guardar dos bytes cambiando Import[#]a Import@#, y lo mismo para ColorCombine[Most@#].
numbermaniac

¿Por qué un simple no ColorNegate@*Importsería una respuesta completa?
LegionMammal978


2

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

Este es un programa completo que toma un nombre de archivo como argumento de línea de comando y sobrescribe el archivo dado con la imagen invertida. Se requiere que el FileIOy Imageel paquete se instalará. Sin embargo, este último no necesita ser importado.

Llame al programa desde la línea de comando como julia filename.jl /path/to/image.png .

Sin golf:

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)

Ejemplo:

regular invertido


1
La urraca (?) Se ve muy deprimida en la segunda imagen.
Bálint

1

Python + PIL, 85 bytes

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

Esto define una función anónima que toma un nombre de archivo como una cadena y guarda la imagen resultante en a.png .

Prueba de funcionamiento:

llama llama fuera


1
-3 bytes: from PIL import Image as Iseguido de reemplazo Imageen la función conI
Tim Čas

Estoy bastante seguro de que simplemente import Imagefuncionará, reduciendo una carga completa de bytes
Decaimiento Beta

guardar 11 bytes confrom PIL.Image import*
Aaron

Creo que esto accidentalmente invierte el canal alfa también. Aparentemente, la evalfunción se ejecuta contra todas las "bandas", incluida la alfa. Esto es lo que obtengo al invertir el logotipo de Firefox - imgur.com/a/wV3MSQX
dana

1
@dana Según el comentario del OP , el soporte de canales alfa es opcional.
Mego

1

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

Mi primera presentación en este sitio.

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

Probablemente podría reducir algunos bytes. Necesita stb_*implementación para estar en una biblioteca separada o al comienzo de este archivo con:

#define STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_WRITE_IMPLEMENTATION

No lo incluí en el recuento porque es esencialmente parte de la biblioteca (especialmente si se compila por separado). Sin embargo, +72 bytes para agregar eso si es necesario.


Actualización 1:

Se dio cuenta de que solo una función (a diferencia de un programa completo) es aceptable, eliminando 15 bytes. La edad aplicación (que es todo un programa), como referencia:

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

1

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

1

MATLAB / Octave, 31 bytes

Código:

imshow(imcomplement(imread(x)))

Ejemplo:

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

ingrese la descripción de la imagen aquí              ingrese la descripción de la imagen aquí

Explicación:

Lea la imagen, xdesde un archivo de gráficos, complemente la imagen y luego visualice la imagen.


El código supone que xestá predefinido, lo que no está permitido. Puede convertirlo en una función lambda para +4 bytes con @(x).
Mego

0

FFmpeg, 10 bytes

Editar: siguiendo el ejemplo de la respuesta de @ Sparr

-vf negate

(lo anterior cuando se pasa a ffplay junto con el nombre de la imagen, mostrará la imagen negada)


ffplay %1 -vf negate

Lo anterior se guarda como un archivo por lotes.


1
¿Es FFmpeg un lenguaje de programación según nuestros estándares? No sé lo suficiente para estar seguro. Tal vez preguntar sobre meta?
Mego

0

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

Forma más legible:

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

Uso:

(f "myimg.png")

0

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

sin golf

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

0

Python 2 + OpenCV , 55 bytes

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

La biblioteca OpenCV usa matrices NumPy para leer, procesar y escribir imágenes. A continuación se muestra un ejemplo de este script que invierte una imagen encontrada en mozilla.org .

Edge Artwork invertido

Todos los canales, incluido el canal alfa, se invertirán. Esto es problemático para las imágenes que tienen transparencia. Pero como señaló @Mego, el soporte para el canal alfa es opcional.

A continuación se muestra una versión comentada de 82 bytes cuya propiedad maneja el canal alfa.

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

Como se muestra a continuación, esto maneja correctamente la inversión del logotipo de Firefox mientras conserva el fondo transparente.

Logotipo de Firefox invertido

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.