Инвертировать PNG изображение


15

Создайте программу или функцию, которая принимает имя файла в качестве аргумента или читает его из стандартного ввода, и выполняет следующую задачу:

  1. Чтение изображения из png-файла (имя указывается в качестве аргумента).
  2. Поменяйте цвета на этом изображении, чтобы, например, темно-зеленый (0, 75, 30) стал (255, 180, 225) (потому что 255-0 = 255, 255-75 = 180 и 255-30 = 225). Вы не должны изменять значение альфа-канала.
  3. Выведите это изображение в файл с именем a.png(в формате png) или покажите его в окне графического интерфейса.

Это . Применяются стандартные лазейки.


Требуется ли поддерживать какие-либо дополнительные функции png? Допустимы ли встроенные функции загрузки / записи png?
Спарр

@Sparr Поддержка дополнительных функций не является обязательной . Встроенные функции явно не запрещены, поэтому я предполагаю, что они разрешены.
Ханнес Карппила

5
Файлы PNG могут быть проиндексированы (каждый пиксель содержит указатель на цвет в цветовой карте) или truecolor (каждый пиксель содержит фактический цвет). Кого нам нужно поддержать? Можем ли мы выбрать? На самом деле, есть пять разных подформатов, касающихся цвета. Так... ?
Луис Мендо

@ DonMuesli Я думаю, что любой метод, который обеспечивает правильный результат, будет в порядке. Вы можете предположить, что цвет не является серым, и поддержка альфа-канала является необязательной. Я думаю, что использование любого другого режима является приемлемым, поскольку задача будет по-прежнему менять цвета, а цвета имеют (r, g, b) -значения.
Ханнес Карппила

1
Могу ли я использовать только CSS?
Риззе

Ответы:


30

ImageMagick display -fx, 3 7 18 24 байта

1-u

Инструмент ImageMagick displayс fxпараметром может применить вышеуказанную программу к png, заданному в качестве параметра, и отобразить результаты на экране.

Проверьте мой пост на мета о ImageMagick как язык программирования. Я написал главного тестера в качестве доказательства концепции.

Подсчет байтов, display -fx code filenameэквивалентен тому perl -e code filename, где мы традиционно рассчитываем только codeдлину.


Разве это не стандартная лазейка? Он получил много голосов, но похоже, что так и должно быть. Я предполагаю, что если в Mathematica может быть встроена куча этих функций, то использование любого предварительно выпущенного приложения (до постановки вопроса) для вас - это честная игра, если она принимает аргументы командной строки?
Нейт Даймонд,

1
@NateDiamond Дайте мне около 5 минут, чтобы закончить мой мета-пост о том, «является ли imagemagick языком программирования», и я урежу это до 7 байтов и одновременно отвечу на ваш вопрос :)
Sparr


21

Pyth, 16 15 13 байт

.w-LLL255'z\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

Спасибо Якубе за 2 байта!


4
чувак, я должен выучить пит
подземный

1
Разве у Пифа нет побитового отрицания ( ~или подобного)?
Питер Тейлор

@PeterTaylor Я не думаю, что это удивительно. (В любом случае это должно быть ограничено 8 битами.)
Ручка двери

нет ли способа глубокого отображения с pfn?
Ven

1
@ven @Doorknob На самом деле вы можете сделать это: .w-LLL255'z\a. Но не спрашивайте меня, как это работает или зачем вам нужно, LLLа не что-то подобное LMM.
Якуб

18

MATL , 10 байт

255iYi-IYG

Существует пять различных подформатов PNG, в зависимости от того, как кодируется цвет. Ни один из них не кажется более «необязательным», чем другие. Я выбрал наиболее гибкий Truecolor, в котором каждый пиксель может иметь произвольный цвет. Приведенный выше код также поддерживает Truecolor with alphaигнорирование альфа-канала.

Чтобы узнать цветовой подформат PNG-файла: ищите последовательность байтов [73 72 68 82]в начале файла; и десятый байт оттуда будет иметь одно из пяти значений в таблице, связанной выше .

Как работает код

Довольно просто:

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

пример

Я не мог удержаться от того, чтобы увидеть себя перевернутым, поэтому я скачал это изображение (которое находится в подформате Truecolor with alpha), запустил код (вторая строка - ввод пользователя)

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

и получил

введите описание изображения здесь


1
Ваш аватар на самом деле вы? Я думал, что это был только твой шлем! : P
Downgoat

1
Я думал, что PNG и все означает длинный код, но 10 байтов? Вау.
Чтение буфера

17

Ява, 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
Мне нравится, как x-- и x> 0 вместе составляют маленькую стрелку, показывающую, что x поднимается до 0. Почему я никогда не видел / не использовал это раньше?
LuWi

Импорт java.io.File?
nickb

1
@ LuWi Хе-хе, я видел и использовал его раньше, некоторые люди называют его оператором «идет в», и это довольно гольфы :)
aditsu

@nickb, даже если вы используете короче import java.io.*;, он не сохраняет байтов, но на самом деле увеличивает размер.
aditsu

4

R, 124 байта

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

Читает в имени файла через 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.

Пример ввода / вывода с использованием первого png, который я нашел на этом компьютере :)

вход Выход



2

Tcl, 176 байт

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

Загружает PNG через photoтип изображения, получает данные изображения, преобразуя каждую строку и цвет, вычитая из #FFFFFF, затем записывает файл обратно на диск (как «a.png»).

Для достижения наилучших результатов используйте TrueColor PNG, поскольку Tk будет пытаться использовать то же цветовое разрешение, что и данные исходного изображения.

Чтобы увидеть изображение без проблем сэмплирования, добавьте

pack [label .i -image image1]

к концу. (Очевидно, это дольше, чем опция сохранения диска.)


Вы можете заменить байты foreachнаlmap
sergiol

2

Mathematica, 140 байт

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

Обратите внимание, что вы можете сохранить два байта, изменив Import[#]на Import@#, и то же самое для ColorCombine[Most@#].
Numbermaniac

Почему простой не ColorNegate@*Importбудет полным ответом?
LegionMammal978


2

Юлия, 94 79 байт

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

Это полная программа, которая принимает имя файла в качестве аргумента командной строки и перезаписывает данный файл инвертированным изображением. Это требует, чтобы FileIOи Imageпакет был установлен. Последний не нужно импортировать, хотя.

Вызов программы из командной строки, как 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)

Пример:

регулярный перевернутый


1
Сорока (?) Выглядит серьезно подавленным на втором изображении.
Bálint

1

Python + PIL, 85 байт

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

Это определяет анонимную функцию, которая принимает имя файла в виде строки и сохраняет результирующее изображение в a.png.

Тестовый забег:

гуанако лама из


1
-3 байта: с from PIL import Image as Iпоследующей заменой Imageв функции:I
Тим Час

Я вполне уверен, что это просто import Imageсработает, избавившись от целой загрузки байтов
Beta Decay

сохранить 11 байтов сfrom PIL.Image import*
Аарон

Я думаю, что это случайно инвертирует альфа-канал. По всей видимости, evalфункция работает против всех «полос», включая альфа. Вот то , что я получаю , когда инвертирующий логотип Firefox - imgur.com/a/wV3MSQX
Dana

1
@dana Согласно комментарию ОП , поддержка альфа-каналов не является обязательной.
Мего

1

C + stb_image + stb_image_write, 175 162 байта (или + 72 =247 234)

Моя первая публикация на этом сайте.

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

Возможно, сбрил бы несколько байтов. Нужно, stb_*чтобы реализация находилась либо в отдельной библиотеке, либо в начале этого файла с помощью:

#define STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_WRITE_IMPLEMENTATION

Я не включил его в счетчик, потому что он по сути является частью библиотеки (особенно если он скомпилирован отдельно). +72 байта, чтобы добавить это, если требуется, однако.


Обновление 1:

Реализована только функция (в отличие от целой программы) приемлемая, сбрасывающая 15 байт. Старая реализация (это целая программа), для справки:

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 байт

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 байт

Код:

imshow(imcomplement(imread(x)))

Пример:

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

введите описание изображения здесь              введите описание изображения здесь

Объяснение:

Прочитайте изображение xиз графического файла, дополните изображение и затем отобразите изображение.


Код предполагает, что xэто предопределено, что недопустимо. Вы можете превратить его в лямбда-функцию на +4 байта с помощью @(x).
Мего

0

FFmpeg, 10 байт

Редактировать: принимая реплику от ответа @ Спарра

-vf negate

(вышеупомянутое, когда передано ffplay вместе с именем изображения, отобразит изображение с отрицанием)


ffplay %1 -vf negate

Вышеуказанное сохраняется как командный файл.


1
Является ли FFmpeg языком программирования по нашим стандартам? Я не знаю достаточно об этом, чтобы быть уверенным. Может спросить на мета?
Мего

0

Ракетка 282 байта

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

Более читаемая форма:

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

Использование:

(f "myimg.png")

0

Голанг, 311 байт

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

0

Python 2 + OpenCV , 55 байт

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

Библиотека OpenCV использует массивы NumPy для чтения, обработки и записи изображений. Ниже приведен пример того, как этот скрипт инвертирует изображение, найденное на mozilla.org .

Edge Artwork Inverted

Все каналы, включая альфа-канал, будут инвертированы. Это проблематично для изображений с прозрачностью. Но, как указал @Mego, поддержка альфа-канала не является обязательной.

Ниже приведена 82-байтовая закомментированная версия, которая обрабатывает альфа-канал.

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

Как показано ниже, это правильно обрабатывает инвертирование логотипа Firefox при сохранении прозрачного фона.

Firefox Logo Inverted

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.