Przegląd
Biorąc pod uwagę obraz w formacie PPM (P3) jako dane wejściowe, dla każdego piksela p
na obrazie zamień każdy z następujących 4 pikseli na czerwony, zielony i niebieski na uśrednioną średnią z odpowiednich kanałów wszystkich 4 pikseli:
p
samoPiksel zlokalizowany w
p
miejscu, w którym obraz jest obrócony w pioniePiksel zlokalizowany w
p
miejscu, w którym obraz jest obrócony w poziomiePiksel zlokalizowany w
p
miejscu, w którym obraz jest odwracany zarówno w pionie, jak iw poziomie
Wygeneruj uzyskany obraz w zwykłym formacie PPM (P3).
Aby uzyskać dalsze wyjaśnienia, rozważ ten obraz 8 x 8 powiększony do 128 x 128:
Niech p
będzie czerwonym pikselem. Aby obliczyć nową wartość p
(i 3 niebieskie piksele), wartości p
i 3 niebieskie piksele zostaną uśrednione razem:
p1 = (255, 0, 0)
p2 = (0, 0, 255)
p3 = (0, 0, 255)
p4 = (0, 0, 255)
p_result = (63, 0, 191)
Przykłady
Wdrożenie referencyjne
#!/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])
Ten program pobiera jako dane wejściowe pojedynczą nazwę pliku, sformatowaną jak dane wyjściowe pngtopnm <pngfile> -plain
i wysyła pojedynczy wiersz danych PPM oddzielony spacjami.
Krótki opis formatu P3
Plik tekstowy PPM wygenerowany z pngtopnm <pngfile> -plain
będzie wyglądał następująco:
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>
<...>
Jest to format używany w przykładowych plikach wejściowych i wyjściowych. Jednak formatowanie danych PNM jest bardzo luźne - każda biała spacja może rozdzielać wartości. Możesz zastąpić wszystkie znaki nowego wiersza w powyższym pliku pojedynczym odstępem i nadal mieć poprawny plik. Na przykład ten plik i ten plik są poprawne i reprezentują ten sam obraz. Jedyne inne wymagania to to, że plik musi kończyć się znakiem nowej linii, a po nim muszą być width*height
trojaczki RGB 255
.
Zasady
- To jest golf golfowy , więc wygrywa najkrótsze prawidłowe rozwiązanie.
- Możesz wprowadzać i wyprowadzać dane PPM sformatowane w dowolny wygodny i spójny sposób, o ile są one zgodne z opisanym powyżej formatem PPM. Jedynym wyjątkiem jest to, że musisz użyć formatu zwykłego (P3), a nie formatu binarnego (P6).
- Musisz potwierdzić, że Twoje rozwiązanie wyświetla prawidłowe obrazy dla powyższych obrazów testowych.
- Wszystkie obrazy będą miały głębię 8 bitów.
Dodatkowa lektura: strona Wikipedii w formacie Netpbm
Odpowiedzi:
Pyth,
3029 bajtówMój program oczekuje wszystkich metadanych w pierwszym wierszu, a dane obrazu wiersz po wierszu w wierszach po włączeniu standardowego wejścia. Aby pomóc, jest to mały program w języku Python do konwersji dowolnego prawidłowego pliku PPM na plik PPM, który mój program może zrozumieć:
Po uzyskaniu danych obrazu wiersz po rzędzie operacje są naprawdę proste. Najpierw czytam dane obrazu do listy list liczb całkowitych (
JrR7.z
), a następnie tworzę wersję lustrzaną w poziomie, grupując co 3 liczby całkowite i odwracając je dla każdego wiersza (Km_cd3J
). Wersje lustrzane w pionie są po prostu_J_K
, ponieważ możemy po prostu odwrócić rzędy.Biorę wszystkie te macierze, spłaszczam każdą z nich do tablicy 1d
.nM
, transponuję za pomocą,C
aby uzyskać listę list każdego ze składników pikseli, uśredniam i obcinam do każdej z tych list (ms.Od
), a na końcu drukuję dołączając nowe liniej
.Zauważ, że mój program generuje dane wyjściowe w innym formacie (ale nadal prawidłowym PPM). Obrazy demo można obejrzeć w tym albumie imgur .
źródło
Bash (+ ImageMagick), 64 + 1 = 65 bajtów
Odpowiednie narzędzie do pracy.
Musi być uruchomiony w katalogu zawierającym pojedynczy plik
a
zawierający dane PPM do transformacji. Ponieważ ta nazwa pliku jest znacząca, dodałem jeden bajt do liczby bajtów.Dane wyjściowe miniatury PNG (nie jestem pewien, dlaczego jest to konieczne, ponieważ i tak wszystkie są takie same, ale pytanie tak mówi, więc ...):
Dzięki nneonneo za oszczędność 2 bajtów!
źródło
-flop
, naprawdę chcę być zaskoczony, że to flaga.C=convert
i$C
zamiastalias
.Matlab,
1068280 bajtówObraz jest ładowany jako
n*m*3
matryca. Następnie odwracamy macierz i dodajemy do siebie dla obu osi i zapisujemy ją ponownie do pliku.Nie mogłem znaleźć miejsca na przesyłanie plików tekstowych tak dużych, więc oto wersje PNG:
źródło
<img
tagów!Mathematica,
8684 bajtówDzięki DavidC za radę. (zapisuje 2 bajty)
Pierwszy i drugi parametr to odpowiednio ścieżki do obrazów wejściowych i wyjściowych.
Przypadki testowe
Wynik
(Wersje obrazów PNG są przesyłane poniżej)
źródło
Join[#,(r=Reverse)/@#]
Julia, 157 bajtów
Jest to funkcja lambda, która akceptuje ciąg zawierający pełną ścieżkę do pliku PPM i zastępuje go przekształconym obrazem. Aby go wywołać, przypisz go do zmiennej.
Nie golfowany:
Przykładowe wyniki:
źródło
python 2 + PIL, 268
Teraz masowo używam PIL, używając przewijania obrazu i mieszania alfa
Powstałe obrazy są dostępne tutaj
źródło