Đảo ngược hình ảnh png


15

Tạo chương trình hoặc hàm lấy tên tệp làm đối số hoặc đọc nó từ đầu vào tiêu chuẩn và hoàn thành tác vụ sau:

  1. Đọc hình ảnh từ tệp png (tên được đặt làm đối số).
  2. Đảo ngược màu sắc trong hình ảnh đó, ví dụ như màu xanh đậm (0, 75, 30) sẽ trở thành (255, 180, 225) (vì 255-0 = 255, 255-75 = 180 và 255-30 = 225). Bạn không nên thay đổi giá trị kênh alpha.
  3. Xuất hình ảnh đó ra một tệp có tên a.png(ở định dạng png) hoặc hiển thị nó trong cửa sổ GUI.

Đây là . Tiêu chuẩn áp dụng.


Có cần thiết để hỗ trợ bất kỳ tính năng png tùy chọn? Các chức năng tải / ghi png tích hợp có được chấp nhận không?
Sparr

@Sparr Hỗ trợ tính năng tùy chọntùy chọn . Các hàm tích hợp không được phép rõ ràng, vì vậy tôi cho rằng chúng được cho phép.
Hannes Karppila

5
Các tệp PNG có thể được lập chỉ mục (mỗi pixel chứa một con trỏ tới một màu trong bản đồ màu) hoặc truecolor (mỗi pixel chứa màu thực tế). Chúng ta cần hỗ trợ cái nào? Chúng ta có thể chọn không? Trong thực tế, có năm biểu mẫu con khác nhau về màu sắc. Vì thế... ?
Luis Mendo

@DonMuesli Tôi nghĩ rằng bất kỳ phương pháp nào cung cấp kết quả chính xác sẽ ổn. Bạn có thể giả sử rằng màu sắc không phải là thang độ xám và việc hỗ trợ kênh alpha là tùy chọn. Tôi nghĩ rằng việc sử dụng bất kỳ chế độ nào khác đều được chấp nhận, miễn là tác vụ vẫn sẽ đảo ngược màu sắc và màu sắc có giá trị (r, g, b).
Hannes Karppila

1
Tôi chỉ có thể sử dụng CSS?
Rizze

Câu trả lời:


30

ImageMagick display -fx, 3 7 18 24 byte

1-u

Công cụ ImageMagick displayvới fxtham số có thể áp dụng chương trình trên cho png được cung cấp làm tham số và hiển thị kết quả trên màn hình.

Kiểm tra bài viết của tôi trên meta về ImageMagick như một ngôn ngữ lập trình. Tôi đã viết một thử nghiệm chính ở đó như một bằng chứng về khái niệm.

Đếm lại byte, display -fx code filenametương đương với perl -e code filename, trong đó chúng ta thường chỉ đếm codechiều dài.


Đây không phải là một lỗ hổng tiêu chuẩn? Nó đã nhận được rất nhiều sự ủng hộ, nhưng có vẻ như nó nên như vậy. Tôi đoán nếu Mathicala có thể tích hợp sẵn một loạt các chức năng này, thì sử dụng bất kỳ ứng dụng nào được phát hành trước (trước khi đặt câu hỏi) để làm điều đó cho bạn là trò chơi công bằng, miễn là nó chấp nhận các đối số dòng lệnh?
Kim cương Nate

1
@NateDiamond Hãy cho tôi khoảng 5 phút để hoàn thành bài đăng meta của tôi về "hãy tưởng tượng một ngôn ngữ lập trình" và tôi sẽ cắt nó xuống còn 7 byte và giải quyết câu hỏi của bạn cùng một lúc :)
Sparr


21

Bình thường, 16 15 13 byte

.w-LLL255'z\a

Đầu ra 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

Cảm ơn Jakube cho 2 byte!


4
người đàn ông, tôi đã gotta học pyth
undergroundmonorail

1
Pyth không có phủ định bitwise ( ~hoặc tương tự)?
Peter Taylor

@PeterTaylor Tôi không nghĩ vậy, thật đáng ngạc nhiên. (Trong mọi trường hợp, nó sẽ phải được giới hạn ở 8 bit.)
Doorknob

không có cách nào để bản đồ sâu với một pfn?
Ven

1
@ven @Doorknob Trên thực tế bạn có thể làm điều đó: .w-LLL255'z\a. Nhưng đừng hỏi tôi làm thế nào điều này hoạt động hoặc tại sao bạn cần LLLvà không phải như thế LMM.
Jakube

18

MATL , 10 byte

255iYi-IYG

năm biểu mẫu con khác nhau của PNG, tùy thuộc vào cách mã hóa màu sắc. Không ai trong số họ dường như là "tùy chọn" hơn những người khác. Tôi đã chọn một điểm linh hoạt nhất Truecolor, trong đó mỗi pixel có thể có một màu tùy ý. Đoạn mã trên cũng hỗ trợ Truecolor with alpha, bỏ qua kênh alpha.

Để biết biểu mẫu con màu của tệp PNG: hãy tìm chuỗi byte [73 72 68 82]gần đầu tệp; và byte thứ mười từ đó sẽ có một trong năm giá trị trong bảng được liên kết ở trên .

Mã hoạt động như thế nào

Khá đơn giản:

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

Thí dụ

Tôi không thể cưỡng lại việc nhìn thấy mình bị đảo ngược, vì vậy tôi đã tải xuống hình ảnh này (ở dạng con Truecolor with alpha), chạy mã (dòng thứ hai là đầu vào của người dùng)

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

và có

nhập mô tả hình ảnh ở đây


1
Hình đại diện của bạn thực sự là bạn? Tôi nghĩ đó chỉ là mũ bảo hiểm của bạn! : P
Downgoat

1
Tôi nghĩ PNG và tất cả có nghĩa là mã dài, nhưng 10 byte? Ồ
Bộ đệm đã đọc

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
Tôi thích cách x-- và x> 0 cùng nhau tạo ra một mũi tên litte cho thấy x tăng lên 0. Tại sao tôi chưa bao giờ thấy / sử dụng nó trước đây?
LuWi

Nhập khẩu java.io.File?
nickb

1
@LuWi hehe, tôi đã thấy và sử dụng nó trước đây, một số người gọi nó là nhà điều hành "đi đến", và nó khá là golf :)
aditsu

@nickb ngay cả khi bạn sử dụng ngắn hơn import java.io.*;, nó không lưu bất kỳ byte nào nhưng thực sự làm tăng kích thước.
aditsu

4

R, 124 byte

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

Đọc tên tập tin thông qua 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.

Ví dụ Nhập / Xuất bằng png đầu tiên tôi tìm thấy trên máy tính này :)

Đầu vào Đầu ra



2

Tcl, 176 byte

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

Tải PNG thông qua photoloại hình ảnh, lấy dữ liệu hình ảnh, chuyển đổi từng hàng và màu bằng cách trừ từ #FFFFFF, sau đó ghi tệp trở lại vào đĩa (dưới dạng "a.png").

Để có kết quả tốt nhất, hãy sử dụng TrueColor PNGs, vì Tk sẽ cố gắng sử dụng độ phân giải màu giống như dữ liệu hình ảnh nguồn.

Để xem hình ảnh mà không có vấn đề lấy mẫu, thêm

pack [label .i -image image1]

đến cuối cùng. (Rõ ràng, cái này dài hơn tùy chọn lưu đĩa.)


Bạn có thể thay thế byte foreachbằnglmap
sergiol

2

Toán học, 140 byte

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

Lưu ý rằng bạn có thể lưu hai byte bằng cách thay đổi Import[#]thành Import@#, và tương tự cho ColorCombine[Most@#].
numbermaniac

Tại sao ColorNegate@*Importmột câu trả lời đơn giản sẽ là một câu trả lời hoàn chỉnh?
LegionMammal978


2

Julia, 94 79 byte

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

Đây là một chương trình đầy đủ lấy tên tệp làm đối số dòng lệnh và ghi đè lên tệp đã cho bằng hình ảnh ngược. Nó đòi hỏi rằng gói FileIOImageđược cài đặt. Cái sau không cần phải nhập.

Gọi chương trình từ dòng lệnh như julia filename.jl /path/to/image.png .

Ung dung:

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)

Thí dụ:

đều đặn đảo ngược


1
Chim ác (trông có vẻ chán nản nghiêm trọng trên hình ảnh thứ hai.
Bálint

1

Python + PIL, 85 byte

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

Điều này xác định một hàm ẩn danh lấy tên tệp là một chuỗi và lưu hình ảnh kết quả vào a.png.

Chạy thử nghiệm:

llama sẽ ra


1
-3 byte : from PIL import Image as I, tiếp theo là thay thế Imagetrong hàm bằngI
Tim Čas

Tôi khá chắc chắn rằng đơn giản là import Imagenó sẽ hoạt động, loại bỏ toàn bộ tải byte
Beta Decay

lưu 11 byte vớifrom PIL.Image import*
Aaron

Tôi nghĩ rằng điều này vô tình đảo ngược kênh alpha là tốt. Rõ ràng evalchức năng chạy với tất cả các "dải", bao gồm cả dải alpha. Đây là những gì tôi nhận được khi đảo ngược logo Firefox - imgur.com/a/wV3MSQX
dana

1
@dana Theo nhận xét của OP , việc hỗ trợ các kênh alpha là tùy chọn.
Mego

1

C + stb_image + stb_image_write, 175 162 byte (hoặc + 72 =247 234)

Trình đầu tiên của tôi trên trang web này bao giờ hết.

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

Có lẽ có thể cạo đi một vài byte. Cần stb_*triển khai trong một thư viện riêng hoặc ở đầu tệp này với:

#define STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_WRITE_IMPLEMENTATION

Tôi không bao gồm nó trong số đếm vì về cơ bản nó là một phần của thư viện (đặc biệt nếu nó được biên dịch riêng). +72 byte để thêm rằng nếu cần, tuy nhiên.


Cập nhật 1:

Chỉ nhận ra một chức năng (trái ngược với toàn bộ chương trình) là có thể chấp nhận được, loại bỏ 15 byte. Việc thực hiện (là toàn bộ chương trình), để tham khảo:

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 byte

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 byte

Mã số:

imshow(imcomplement(imread(x)))

Thí dụ:

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

nhập mô tả hình ảnh ở đây              nhập mô tả hình ảnh ở đây

Giải trình:

Đọc hình ảnh, xtừ một tệp đồ họa, bổ sung cho hình ảnh, và sau đó hiển thị hình ảnh.


Mã giả định xđược xác định trước, không được phép. Bạn có thể biến nó thành hàm lambda cho +4 byte với @(x).
Mego

0

FFmpeg, 10 byte

Chỉnh sửa: Lấy một gợi ý từ câu trả lời của @ Sparr

-vf negate

(ở trên khi được chuyển đến ffplay cùng với tên hình ảnh, sẽ hiển thị hình ảnh bị phủ định)


ffplay %1 -vf negate

Ở trên được lưu dưới dạng một tập tin bó.


1
FFmpeg có phải là ngôn ngữ lập trình theo tiêu chuẩn của chúng tôi không? Tôi không biết đủ về nó để chắc chắn. Có lẽ hỏi về meta?
Mego

0

Vợt 282 byte

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

Hình thức dễ đọc hơn:

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

Sử dụng:

(f "myimg.png")

0

Golang, 311 byte

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

vô dụng

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 byte

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

Thư viện OpenCV sử dụng mảng NumPy để đọc, xử lý và viết hình ảnh. Dưới đây là một ví dụ về tập lệnh này đảo ngược một hình ảnh được tìm thấy trên mozilla.org .

Edge Artwork Inverted

Tất cả các kênh, bao gồm cả kênh alpha, sẽ được đảo ngược. Đây là vấn đề đối với hình ảnh có độ trong suốt. Nhưng như @Mego chỉ ra, hỗ trợ cho kênh alpha là tùy chọn.

Dưới đây là một phiên bản nhận xét 82 byte mà thuộc tính xử lý kênh alpha.

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

Như được hiển thị bên dưới, điều này xử lý đúng cách đảo ngược logo Firefox trong khi vẫn giữ nền trong suốt.

Firefox Logo Inverted

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.