Lật nó, lật nó, có nghĩa là nó


24

Tổng quan

Đưa ra một hình ảnh ở định dạng PPM (P3) đơn giản làm đầu vào, cho mỗi pixel ptrong ảnh, thay thế từng màu đỏ, xanh lục và xanh lam của 4 pixel sau bằng giá trị trung bình nổi của các kênh tương ứng của cả 4 pixel:

  1. p chinh no

  2. Pixel nằm ở pvị trí của hình ảnh khi lật hình ảnh theo chiều dọc

  3. Pixel nằm ở pvị trí của hình ảnh khi lật hình ảnh theo chiều ngang

  4. Pixel nằm ở pvị trí của hình ảnh khi hình ảnh được lật theo cả chiều dọc và chiều ngang

Xuất hình ảnh kết quả ở định dạng PPM (P3) đơn giản.

Để giải thích thêm, hãy xem xét hình ảnh 8x8 này, được phóng to lên 128x128:

ví dụ bước 2

Hãy plà pixel đỏ. Để tính giá trị mới cho p(và 3 pixel màu xanh), các giá trị của pvà 3 pixel màu xanh sẽ được tính trung bình cùng nhau:

p1 = (255, 0, 0)
p2 = (0, 0, 255)
p3 = (0, 0, 255)
p4 = (0, 0, 255)
p_result = (63, 0, 191)

Ví dụ

PPM: đầu vào , đầu ra


PPM: đầu vào , đầu ra


PPM: đầu vào , đầu ra


PPM: đầu vào , đầu ra


Thực hiện tham khảo

#!/usr/bin/python

import sys
from itertools import *

def grouper(iterable, n, fillvalue=None):
    args = [iter(iterable)] * n
    return list(izip_longest(*args, fillvalue=fillvalue))

def flatten(lst):
    return sum(([x] if not isinstance(x, list) else flatten(x) for x in lst), [])

def pnm_to_bin(p):
    w,h = map(int,p[1].split(' '))
    data = map(int, ' '.join(p[3:]).replace('\n', ' ').split())
    bin = []
    lines = grouper(data, w*3)
    for line in lines:
        data = []
        for rgb in grouper(line, 3):
            data.append(list(rgb))
        bin.append(data)
    return bin

def bin_to_pnm(b):
    pnm = 'P3 {} {} 255 '.format(len(b[0]), len(b))
    b = flatten(b)
    pnm += ' '.join(map(str, b))
    return pnm

def imageblender(img):
    h = len(img)
    w = len(img[0])
    for y in range(w):
        for x in range(h):
            for i in range(3):
                val = (img[x][y][i] + img[x][~y][i] + img[~x][y][i] + img[~x][~y][i])//4
                img[x][y][i],img[x][~y][i],img[~x][y][i],img[~x][~y][i] = (val,)*4
    return img

def main(fname):
    bin = pnm_to_bin(open(fname).read().split('\n'))
    bin = imageblender(bin)
    return bin_to_pnm(bin)

if __name__ == '__main__':
    print main(sys.argv[1])

Chương trình này lấy một tên tệp làm đầu vào, được định dạng như đầu ra của pngtopnm <pngfile> -plainvà xuất ra một dòng dữ liệu PPM được phân tách bằng dấu cách.


Mô tả ngắn gọn về định dạng P3

Một tệp văn bản PPM được tạo từ pngtopnm <pngfile> -plainsẽ trông như thế này:

P3
<width in pixels> <height in pixels>
<maximum value as defined by the bit depth, always 255 for our purposes>
<leftmost 24 pixels of row 1, in RGB triples, space-separated; like (0 0 0 1 1 1 ...)>
<next 24 pixels of row 1>
<...>
<rightmost (up to) 24 pixels of row 1>

<leftmost 24 pixels of row 2>
<next 24 pixels of row 2>
<...>
<rightmost (up to) 24 pixels of row 2>

<...>

Đây là định dạng mà các tệp đầu vào và đầu ra ví dụ sử dụng. Tuy nhiên, PNM rất lỏng lẻo về định dạng của nó - bất kỳ khoảng trắng nào cũng có thể tách các giá trị. Bạn có thể thay thế tất cả các dòng mới trong tệp trên bằng một khoảng trống duy nhất và vẫn có một tệp hợp lệ. Ví dụ: tệp nàytệp này đều hợp lệ và đại diện cho cùng một hình ảnh. Các yêu cầu duy nhất khác là tệp phải kết thúc bằng một dòng mới và phải có width*heightbộ ba RGB theo sau 255.


Quy tắc

  • Đây là , vì vậy giải pháp hợp lệ ngắn nhất sẽ thắng.
  • Bạn có thể nhập và xuất dữ liệu PPM được định dạng theo bất kỳ cách thuận tiện và nhất quán nào, miễn là nó hợp lệ theo định dạng PPM được mô tả ở trên. Ngoại lệ duy nhất là bạn phải sử dụng định dạng thuần (P3) chứ không phải định dạng nhị phân (P6).
  • Bạn phải cung cấp xác minh rằng giải pháp của bạn đưa ra hình ảnh chính xác cho hình ảnh thử nghiệm ở trên.
  • Tất cả các hình ảnh sẽ có độ sâu 8 bit.

Đọc thêm: trang wikipedia định dạng Netpbm


Kiểm tra Snippet (nhờ Sở thích của Calvin cho việc này)


Các thư viện hình ảnh mở / lưu tệp ppm có được phép không?
Sở thích của Calvin

@ Calvin'sHob sở thích Có
Mego

3
" Lật nó, lật nó, trung bình " youtube.com/watch?v=D8K90hX4PrE
Luis Mendo

3
Có lẽ "Lật nó, lật nó, có nghĩa là nó"?
Conor O'Brien

2
@ CᴏɴᴏʀO'Bʀɪᴇɴ Nghe có vẻ như một bữa tiệc nào đó - oh, đợi đã, những gì Luis đăng.
Addison Crump

Câu trả lời:


4

Bình thường, 30 29 byte

zjms.OdC.nM[JrR7.zKm_cd3J_J_K

Chương trình của tôi hy vọng tất cả siêu dữ liệu trên dòng đầu tiên và hàng dữ liệu hình ảnh theo hàng trên các dòng sau trên stdin. Để giúp đỡ, đây là một chương trình Python nhỏ để chuyển đổi bất kỳ tệp PPM hợp lệ nào thành tệp PPM mà chương trình của tôi có thể hiểu:

import sys
p3, w, h, d, *data = sys.stdin.read().split()
print(p3, w, h, d)
for i in range(0, int(w) * int(h), int(w)):
    print(" ".join(data[i:i+int(w)]))

Khi bạn có hàng dữ liệu hình ảnh theo hàng, các thao tác thực sự đơn giản. Đầu tiên tôi đọc dữ liệu hình ảnh vào một danh sách các danh sách số nguyên ( JrR7.z), sau đó tôi tạo phiên bản được nhân đôi theo chiều ngang bằng cách nhóm 3 số nguyên và đảo ngược chúng cho mỗi hàng ( Km_cd3J). Sau đó, các phiên bản được nhân đôi theo chiều dọc chỉ đơn giản _J_K, vì chúng ta chỉ có thể đảo ngược các hàng.

Tôi lấy tất cả các ma trận đó, làm phẳng mỗi ma trận thành một mảng 1d với .nM, hoán đổi Cđể có được danh sách các danh sách của từng thành phần pixel, trung bình và cắt ngắn để int từng danh sách đó ( ms.Od) và cuối cùng được in bằng các dòng mới j.

Lưu ý rằng chương trình của tôi tạo đầu ra ở định dạng khác (nhưng PPM vẫn hợp lệ). Các hình ảnh demo có thể được xem trong album imgur này .


13

Bash (+ ImageMagick), 64 + 1 = 65 byte

C=convert;$C a -flip b;$C a -flop c;$C c -flip d;$C * -average e

Công cụ phù hợp cho công việc.

Phải được chạy trong một thư mục chứa một tệp achứa dữ liệu PPM để chuyển đổi. Vì tên tệp này rất quan trọng, tôi đã thêm một byte vào số byte.

Đầu ra hình thu nhỏ PNG (không chắc tại sao điều này lại cần thiết bởi vì dù sao chúng đều giống nhau, nhưng câu hỏi nói như vậy, vì vậy ...):

chim cánh cụt tinh túy peter xe buýt nhỏ

Cảm ơn nneonneo vì đã tiết kiệm 2 byte!


3
Tôi yêu cầu đầu ra bởi vì mọi người có thói quen xấu là đăng các giải pháp mà không thử nghiệm chúng. +1 cho -flop, tôi thực sự muốn ngạc nhiên rằng đó là một lá cờ.
Mego

1
Cạo sạch 2 byte bằng cách sử dụng C=convert$Cthay vì alias.
nneonneo

12

Matlab, 106 82 80 byte

i=imread(input(''))/4;for k=1:2;i=i+flipdim(i,k);end;imwrite(i,'p3.pnm','e','A')

Hình ảnh được tải dưới dạng n*m*3ma trận. Sau đó, chúng ta lật ma trận và thêm vào chính nó cho cả hai trục và viết lại vào một tệp.


Tôi không thể tìm thấy một nơi để tải lên các tệp văn bản quá lớn, vì vậy đây là các phiên bản PNG:


Ồ, tôi thậm chí không biết bạn có thể sử dụng <imgthẻ!
flawr

1
Trong MATLAB R2013b và mới hơn có thể sử dụng flip thay vì flipdim . Điều đó sẽ giúp bạn tiết kiệm thêm 3 byte. Trợ giúp của flipdim thực sự nói: "flipdim sẽ bị xóa trong phiên bản tương lai. Thay vào đó hãy sử dụng FLIP."
slvrbld

10

Toán học, 86 84 byte

Cảm ơn DavidC cho lời khuyên. (tiết kiệm 2 byte)

Export[#2,⌊Mean@Join[#,(r=Reverse)/@#]&@{#,r/@#}&@Import[#,"Data"]⌋~Image~"Byte"]&

Các tham số thứ nhất và thứ hai lần lượt là các đường dẫn đến hình ảnh đầu vào và đầu ra.


Các trường hợp thử nghiệm

f=%; (assign the function to symbol f)
f["penguin.pnm","penguin2.pnm"]
f["quintopia.pnm","quintopia2.pnm"]
f["peter.pnm","peter2.pnm"]

Kết quả

(Phiên bản PNG của hình ảnh được tải lên bên dưới)

Import["penguin2.pnm"]

Import["quintopia2.pnm"]

Import["peter2.pnm"]


Join[#,(r=Reverse)/@#]
DavidC

4

Julia, 157 byte

using FileIO
s->(a=load(s);b=deepcopy(a);d=a.data;(n,m)=size(d);for i=1:n,j=1:m b.data[i,j]=mean([d[i,j];d[n-i+1,j];d[i,m-j+1];d[n-i+1,m-j+1]])end;save(s,b))

Đây là một hàm lambda chấp nhận một chuỗi chứa đường dẫn đầy đủ đến tệp PPM và ghi đè lên nó bằng hình ảnh được chuyển đổi. Để gọi nó, gán nó cho một biến.

Ung dung:

using FileIO

function f(s::AbstractString)
    # Load the input image
    a = load(s)

    # Create a copy (overwriting does bad things)
    b = deepcopy(a)

    # Extract the matrix of RGB triples from the input
    d = a.data

    # Store the size of the matrix
    n, m = size(d)

    # Apply the transformation
    # Note that we don't floor the mean; this is because the RGB values
    # aren't stored as integers, they're fixed point values in [0,1].
    # Simply taking the mean produces the desired output.
    for i = 1:n, j = 1:m
        b.data[i,j] = mean([d[i,j]; d[n-i+1,j]; d[i,m-j+1]; d[n-i+1,m-j+1]])
    end

    # Overwrite the input
    save(s, b)
end

Kết quả ví dụ:

chim cánh cụt tinh túy peter xe buýt nhỏ


4

trăn 2 + PIL, 268

Bây giờ tôi sử dụng ồ ạt PIL, sử dụng lật hình ảnh và trộn alpha

from PIL import Image
I=Image
B,T=I.blend,I.FLIP_TOP_BOTTOM
a=I.open(raw_input()).convert('RGB')
exec'b=a@I.FLIP_LEFT_RIGHT);c=a@T);d=b@T)'.replace('@','.transpose(')
x,y=a.size
print'P3',x,y,255
for r,g,b in list(B(B(B(a,b,0.5),c,0.25),d,0.25).getdata()):print r,g,b

Hình ảnh kết quả có sẵn ở đây


1
Vui lòng bao gồm các đầu ra cho các trường hợp thử nghiệm, theo yêu cầu của các quy tắc.
Mego
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.