v12.1 — Edycja 2026. Zwięzły przewodnik po używaniu biblioteki Pillow do przetwarzania obrazów oraz jej integracji z większymi projektami AI i machine learning (v12.1 - 2026).
Odkrywamy klasę Image z biblioteki Pillow i pokazujemy, jak działa jako brama do Twojego zbioru danych computer vision. Dowiesz się, jak otwierać obrazy i błyskawicznie wyodrębniać metadane za pomocą lazy loading.
3m 39s
2
Standaryzacja tensorów: Tryby obrazu i konwersje
Zrozumienie trybów obrazu jest kluczowe przed przekazaniem danych do sieci neuronowej. Wyjaśniamy różnice między kanałami Grayscale, RGB i RGBA oraz pokazujemy, jak używać metody convert do standaryzacji danych wejściowych.
4m 29s
3
Geometria dla modeli: Zmiana rozmiaru, przycinanie i padding
Zajmujemy się problemem zmiany kształtu obrazów dla wejść modeli o ściśle określonych rozmiarach. Poznasz różnicę między spłaszczaniem obrazu za pomocą resize, przycinaniem za pomocą fit oraz dodawaniem pasów (letterboxing) za pomocą pad.
4m 29s
4
Most dla tablic: Przenoszenie pikseli do PyTorch
Pillow działa jako most między surowymi plikami obrazów a tablicami matematycznymi. Omawiamy, jak tłumaczyć obrazy na tensory NumPy i formaty PyArrow, a także jak konwertować wyniki modelu z powrotem na widoczne obrazy.
3m 58s
5
Lekka augmentacja: Moduł ImageOps
Nie zawsze potrzebujesz ciężkich bibliotek do augmentacji swojego zbioru danych. Odkrywamy moduł ImageOps z biblioteki Pillow, aby łatwo tworzyć lustrzane odbicia, odwracać i dostosowywać kontrast w celu sztucznego powiększenia danych treningowych.
4m 07s
Odcinki
1
Brama do wizji: Lazy Loading i metadane
3m 39s
Odkrywamy klasę Image z biblioteki Pillow i pokazujemy, jak działa jako brama do Twojego zbioru danych computer vision. Dowiesz się, jak otwierać obrazy i błyskawicznie wyodrębniać metadane za pomocą lazy loading.
Cześć, tu Alex z DEV STORIES DOT EU. Pillow: The Imaging Library, odcinek 1 z 5. Możesz przeskanować dataset miliona obrazów w kilka sekund, nie zapychając przy tym pamięci. Sekret tkwi w tym, że twoja biblioteka tak naprawdę nie ładuje danych pikseli aż do ostatniego możliwego momentu. The Vision Gateway: lazy loading i metadane to mechanizm, który umożliwia obsługę ogromnych katalogów z obrazami.
Kiedy budujesz dataset AI, często zaczynasz od nieprzefiltrowanego web scrape'u. Patrzysz na katalog z milionami nieznanych plików. Musisz je przefiltrować przed trenowaniem modelu. Powiedzmy, że twój model wymaga obrazów o wymiarach dokładnie 512 na 512 pikseli, zapisanych jako JPEG w pełnym kolorze. Powszechnym błędem jest myślenie, że otwarcie pliku obrazu w skrypcie od razu załaduje każdy pojedynczy piksel do pamięci. Gdyby tak było, skanowanie miliona obrazów w wysokiej rozdzielczości zużyłoby ogromne ilości RAM-u i ostatecznie scrashowało twoją maszynę. Zamiast tego, Pillow radzi sobie z tym używając koncepcji zwanej lazy loading.
Punktem wejścia do odczytu obrazu w Pillow jest funkcja open, znajdująca się w module Image. Przekazujesz do tej funkcji ścieżkę do pliku, a ona zwraca obiekt Image. I tu jest kluczowa sprawa. Wywołanie funkcji open nie dekoduje danych rastrowych. Otwiera tylko plik na dysku i odczytuje nagłówek pliku. Nagłówek zawiera tylko tyle informacji, żeby zidentyfikować plik i zrozumieć jego podstawową geometrię. Właściwa, ciężka praca związana z dekompresją i mapowaniem danych pikseli jest odroczona.
Ponieważ Pillow odczytuje nagłówek natychmiast, twój skrypt dostaje od razu dostęp do metadanych obrazu. Te metadane są przechowywane jako atrybuty w obiekcie Image. Są trzy główne atrybuty, których będziesz używać do oceny plików. Pierwszy to atrybut format. Identyfikuje on typ pliku źródłowego, zwracając string taki jak JPEG lub PNG. Drugi to atrybut size. Zwraca on dwuelementową tuplę zawierającą szerokość i wysokość obrazu w pikselach. Trzeci to atrybut mode. Atrybut mode definiuje liczbę i nazwy pasm pikseli w obrazie, na przykład RGB dla standardowego koloru, RGBA dla koloru z przezroczystością, lub literę L dla skali szarości.
Z tymi trzema atrybutami, nasz data engineer może bezpiecznie przetworzyć ten ogromny web scrape. Pisze pętlę, która wywołuje funkcję open na każdym pliku w katalogu. Skrypt sprawdza metadane. Czy format to JPEG? Czy size to 512 na 512? Czy mode to RGB? Jeśli plik nie przejdzie któregokolwiek z tych testów, skrypt go ignoruje i idzie dalej.
Pillow zostawia same dane pikseli w całkowitym spokoju przez cały ten proces. Dane rastrowe są dekodowane i ładowane do pamięci tylko wtedy, gdy twój kod ostatecznie wywoła metodę, która wymusi operację na pikselach, jak przycięcie obrazu czy nałożenie filtra wizualnego. Dla setek tysięcy nieodpowiednich obrazów w katalogu, ta ekstrakcja pikseli nigdy nie ma miejsca. Memory footprint pozostaje minimalny. Twój skrypt przetwarza katalog tak szybko, jak twój dysk jest w stanie odczytać te małe nagłówki plików.
Lazy loading przekształca funkcję open z ciężkiej operacji renderowania w wysoce wydajny skaner metadanych, utrzymując twoje data pipelines szybkimi, a zużycie pamięci na płaskim poziomie. Jeśli chciałbyś wesprzeć nasz podcast, możesz wyszukać DevStoriesEU na Patreon. To wszystko w tym odcinku. Dzięki za wysłuchanie i twórz dalej!
2
Standaryzacja tensorów: Tryby obrazu i konwersje
4m 29s
Zrozumienie trybów obrazu jest kluczowe przed przekazaniem danych do sieci neuronowej. Wyjaśniamy różnice między kanałami Grayscale, RGB i RGBA oraz pokazujemy, jak używać metody convert do standaryzacji danych wejściowych.
Cześć, tu Alex z DEV STORIES DOT EU. Pillow: The Imaging Library, odcinek 2 z 5. Zostawiasz trenowanie modelu wizyjnego na noc, budzisz się rano i widzisz, że pętla scrashowała się kilka godzin temu. Winowajcą był pojedynczy obraz wrzucony przez użytkownika, sformatowany nieco inaczej niż reszta. Naprawienie tej niespójności, zanim dotrze do twojego modelu, to zadanie dla standaryzacji tensorów: modes i konwersji obrazów.
Sieci neuronowe są sztywne. Jeśli twoja warstwa konwolucyjna oczekuje wejściowego tensora z trzema kanałami kolorów, a ty podasz jej obraz z czterema kanałami albo jednym kanałem, matematyka się sypie, a pipeline się zatrzymuje. W computer vision standaryzacja formatów danych obrazu to obowiązkowy krok w pre-processingu.
Aby zarządzać tym w Pillow, musisz zrozumieć dwie powiązane ze sobą właściwości: bands i modes. Obraz w Pillow składa się z jednego lub więcej bands z danymi. Możesz myśleć o band jako o osobnej, dwuwymiarowej tablicy zawierającej jeden konkretny składnik obrazu. Na przykład wartości czerwieni na całym zdjęciu tworzą jeden band. Pillow pozwala na istnienie kilku bands w pojedynczym obiekcie obrazu, o ile dzielą one te same wymiary i głębokość.
Mode to string, który definiuje typ i głębokość piksela na obrazie. Mode mówi bibliotece Pillow dokładnie, co oznaczają poszczególne bands. Są trzy modes, z którymi będziesz się stale spotykać w pipeline'ach machine learningowych. Mode L oznacza luminancję. To standardowy, ośmiobitowy obraz w skali szarości i zawiera dokładnie jeden band. Mode RGB to twój standardowy format true color. Składa się z trzech ośmiobitowych bands: czerwonego, zielonego i niebieskiego. Następnie mamy mode RGBA. Ludzie często myślą o obrazie RGBA jako o zwykłym zdjęciu z przezroczystym tłem. Komputer wcale tak tego nie traktuje. Matematycznie, obraz RGBA posiada kompletny, czwarty kanał danych — kanał alfa, który dyktuje przezroczystość każdego pojedynczego piksela.
A oto część, która ma największe znaczenie. Kiedy użytkownik wrzuca przezroczyste zdjęcie profilowe w formacie PNG, ten obraz trafia do twojego pipeline'u jako RGBA. Niesie ze sobą cztery bands danych. Jeśli twój klasyfikator obrazów oczekuje tensora RGB, podanie mu tego surowego pliku PNG natychmiast wywoła błąd niezgodności wymiarów. Musisz go ustandaryzować. Osiągniesz to, używając metody convert.
Kiedy wywołujesz metodę convert na obiekcie obrazu, przekazujesz docelowy string mode jako argument. Aby naprawić nasz problem z PNG, otwierasz obraz, a następnie wywołujesz convert, przekazując string RGB. Wywołanie metody convert nie modyfikuje twojego oryginalnego obrazu in-place. Zwraca nowo utworzony obiekt obrazu, zawierający przekonwertowane dane pikseli.
Proces konwersji to nie zawsze proste usunięcie dodatkowych danych. Kiedy konwertujesz obraz RGBA do RGB, Pillow odrzuca kanał alfa, ale nie zachowuje w magiczny sposób tego, jak według ciebie wyglądało przezroczyste tło. Domyślnie Pillow zastępuje przezroczystość kolorem czarnym. Jeśli konwertujesz obraz RGB w dół do mode L dla modelu w skali szarości, Pillow nie uśrednia po prostu leniwie trzech bands kolorów. Stosuje specjalny, ważony wzór matematyczny do kanałów czerwonego, zielonego i niebieskiego, aby obliczyć bardzo dokładną, postrzeganą przez człowieka luminancję. Wynikowy obraz w mode L ma dokładnie jeden band.
Jeśli wywołasz convert i zażądasz mode, w którym obraz już się znajduje, Pillow po prostu zwróci kopię oryginału bez marnowania cykli obliczeniowych. Oznacza to, że możesz w ciemno uruchomić polecenie convert do RGB na każdym pojedynczym pliku w twoim datasecie, bez martwienia się o karanie tych, które są już poprawnie sformatowane.
Zawsze zakładaj, że obrazy dostarczone przez użytkownika mają nieprzewidywalne głębokości kanałów. Wymuszenie ścisłej konwersji mode na granicy twojego pipeline'u to najtańsza polisa ubezpieczeniowa, jaką masz przed błędami wymiarów w runtime.
To wszystko w tym odcinku. Dzięki za wysłuchanie i twórz dalej!
3
Geometria dla modeli: Zmiana rozmiaru, przycinanie i padding
4m 29s
Zajmujemy się problemem zmiany kształtu obrazów dla wejść modeli o ściśle określonych rozmiarach. Poznasz różnicę między spłaszczaniem obrazu za pomocą resize, przycinaniem za pomocą fit oraz dodawaniem pasów (letterboxing) za pomocą pad.
Cześć, tu Alex z DEV STORIES DOT EU. Pillow: The Imaging Library, odcinek 3 z 5. Wrzucasz zdjęcie ze smartfona do swojej sieci neuronowej, a jej dokładność spada. Problemem nie są twoje wagi ani architektura. Jeśli po prostu wciśniesz prostokątne zdjęcie w kwadratowy tensor, zniekształcisz features, zanim model w ogóle je zobaczy. Ten odcinek omawia geometrię dla modeli: resize, crop i padding.
Przygotowujesz zdjęcia ze smartfona dla modelu ResNet, który oczekuje inputu o dokładnych wymiarach 224 na 224 piksele. Zdjęcia z prawdziwego świata mają różne proporcje. Masz szerokie krajobrazy i wysokie portrety, ale twój model wymaga idealnego kwadratu. Musisz jakoś rozwiązać ten problem, nie psując przy tym oryginalnych danych. Najczęstszym błędem jest wywołanie na obrazie standardowej metody resize i przekazanie wymiarów 224 na 224. Resize to tępe narzędzie. Wymusza na obrazie te dokładne wymiary i całkowicie ignoruje oryginalny aspect ratio. Jeśli oryginalny obraz był szerokim prostokątem, zostaje ściśnięty w poziomie. Koła stają się wąskimi owalami. Sieć neuronowa uczy się na tych zniekształconych kształtach, co pogarsza jej performance w prawdziwym świecie. Resize nie dopasowuje obrazu w inteligentny sposób; po prostu ślepo go zniekształca.
Aby uniknąć zniekształceń, możesz ręcznie zrobić crop obrazu. Standardowa metoda crop przyjmuje tuple z czterema współrzędnymi, definiującymi lewą, górną, prawą i dolną granicę. Możesz wyliczyć środkowy kwadrat swojego obrazu i odciąć resztę. To zachowuje aspect ratio i zapobiega spłaszczaniu features. Jednak przez to tracisz dane na krawędziach, a pisanie tych obliczeń, żeby wyznaczyć dokładny środkowy box dla każdego rozmiaru obrazu wejściowego, jest żmudne.
I tu pojawia się kluczowa sprawa. Pillow ma moduł ImageOps, zaprojektowany specjalnie do rozwiązania dokładnie tego problemu z geometrią. Jeśli chcesz zrobić crop bez ręcznego liczenia, używasz metody fit z ImageOps. Podajesz jej dokładny rozmiar, jakiego potrzebujesz, na przykład 224 na 224. Metoda ta oblicza aspect ratio żądanego rozmiaru, skaluje obraz w dół, tak aby najkrótszy bok pasował do twojego targetu, a następnie automatycznie robi crop nadmiaru ze środka. Otrzymujesz idealny kwadrat i zero zniekształceń, a główny obiekt zazwyczaj zostaje dokładnie na środku.
A co, jeśli nie możesz sobie pozwolić na utratę krawędzi obrazu? Jeśli obiekt nie jest na środku, center crop może przeciąć go na pół. W takim przypadku przerzucasz się na metodę pad z ImageOps. Pad skaluje obraz w dół, tak aby najdłuższy bok pasował do twojego targetu 224 pikseli. Krótszy bok będzie teraz miał mniej niż 224. Aby nadrobić tę różnicę, metoda pad dodaje ramki w jednolitym kolorze, żeby wypełnić kwadrat. Jest to powszechnie znane jako letterboxing. Cały oryginalny obraz zostaje zachowany, aspect ratio pozostaje w pełni nienaruszone, a model nadal dostaje swój idealny kwadrat.
Za każdym razem, gdy zmieniasz rozmiar obrazu za pomocą którejkolwiek z tych metod, Pillow musi obliczyć nowe piksele. W przypadku modeli machine learningowych, gdzie liczą się detale na poziomie pikseli, potrzebujesz wysokiej jakości filtra do resamplingu. Wywołując fit, pad lub resize, możesz przekazać argument resampling. Filtr taki jak BICUBIC to tutaj mocny, standardowy wybór. Analizuje on otaczające piksele, żeby obliczyć płynne przejścia, zachowując ostrość krawędzi, na których polegają twoje convolutional layers. Sieć neuronowa może łatwo nauczyć się ignorować czarny padding, ale nie potrafi cofnąć spłaszczenia zniekształconego feature'a. To wszystko w tym odcinku. Dzięki za wysłuchanie i twórz dalej!
4
Most dla tablic: Przenoszenie pikseli do PyTorch
3m 58s
Pillow działa jako most między surowymi plikami obrazów a tablicami matematycznymi. Omawiamy, jak tłumaczyć obrazy na tensory NumPy i formaty PyArrow, a także jak konwertować wyniki modelu z powrotem na widoczne obrazy.
Cześć, tu Alex z DEV STORIES DOT EU. Pillow: The Imaging Library, odcinek 4 z 5. Frameworki do machine learningu, takie jak PyTorch czy TensorFlow, tak naprawdę nie wiedzą, czym jest JPEG czy PNG. Rozumieją tylko matematykę, co oznacza, że rozumieją tylko wielowymiarowe arraye. Jeśli przekażesz plik obrazu bezpośrednio do modelu, dostaniesz błąd. Potrzebujesz sposobu, żeby przetłumaczyć te zakodowane bajty na czysty format matematyczny. The Array Bridge: Moving Pixels to PyTorch to dokładnie to, jak możesz to rozwiązać.
Pillow działa jak uniwersalny translator w stacku AI. Kiedy otwierasz obraz za pomocą Pillow, dostajesz obiekt Image. Żeby wrzucić go do pipeline'u danych, przekazujesz ten obiekt Pillow bezpośrednio do Numpy, używając funkcji as array. Pod spodem Pillow wystawia standardowy buffer interface. Numpy odczytuje ten memory buffer i opakowuje go w wielowymiarowy array. Dla standardowej, kolorowej fotografii dostajesz trójwymiarowy array reprezentujący wysokość, szerokość i kanały kolorów.
I tu robi się ciekawie. Kiedy robisz tę konwersję, całkowicie opuszczasz ekosystem Pillow. Wynikowy array nie zawiera żadnych metadanych z Pillow. Ustawienia DPI, dane EXIF, profile kolorów ICC i palety kolorów są całkowicie usuwane. Zostajesz z czystymi, surowymi wartościami liczbowymi pikseli. Jeśli twój oryginalny obraz był oparty na palecie, jak plik GIF, musisz go przekonwertować na obraz RGB wewnątrz Pillow, zanim przekażesz go do Numpy. W przeciwnym razie dostaniesz po prostu array bezsensownych numerów indeksów palety zamiast rzeczywistych kolorów.
Kiedy twoje piksele są już w formie arraya, twój framework może odpalić swoje operacje na tensorach, nałożyć filtry albo wykonać model computer vision. Ale w końcu dostajesz wynik z powrotem. Model może zwrócić nowy array reprezentujący wygenerowany obraz albo maskę segmentacji. Żeby zobaczyć lub zapisać ten wynik, musisz przejść przez most w odwrotnym kierunku. Bierzesz ten wyjściowy array i przekazujesz go do funkcji Pillow o nazwie from array. Pillow odczytuje shape i typ danych arraya Numpy, żeby ogarnąć, jak zinterpretować te liczby. Jeśli zobaczy array ośmiobitowych intów bez znaku z trzema kanałami, domyślnie tworzy obraz RGB. Jeśli zobaczy pojedynczy kanał, tworzy obraz w skali szarości. Masz też opcję, żeby jawnie przekazać tryb kolorów samemu, jeśli musisz nadpisać domyślne zachowanie. Kiedy Pillow zrekonstruuje obiekt Image, po prostu wywołujesz metodę save, żeby zapisać go prosto na dysk twardy.
Przenoszenie pamięci między różnymi bibliotekami może być kosztowne. Jeśli przetwarzasz ogromny dataset obrazów w wysokiej rozdzielczości, kopiowanie danych pikseli w tę i z powrotem tworzy poważny bottleneck. Żeby to rozwiązać, Pillow wspiera format Apache Arrow poprzez funkcję o nazwie from arrow. Arrow to standard dla danych in-memory. Kiedy używasz funkcji from arrow, Pillow konstruuje obraz bezpośrednio ze struktury danych Arrow, używając pamięci współdzielonej zero-copy. To oznacza, że Pillow i twoje inne narzędzia wskazują na dokładnie tę samą fizyczną lokalizację w pamięci. Dane nigdy nie są duplikowane. To bardzo wydajny sposób, żeby wrzucać duże ilości pikseli do nowoczesnych pipeline'ów bez wyczerpywania pamięci systemowej.
Prawdziwa moc biblioteki do obsługi obrazów w stacku AI nie polega tylko na otwieraniu pliku, ale na zgrabnym usunięciu się z drogi, żeby matematyka mogła się zadziać. Dzięki za spędzenie ze mną tych kilku minut. Do usłyszenia następnym razem, trzymaj się.
5
Lekka augmentacja: Moduł ImageOps
4m 07s
Nie zawsze potrzebujesz ciężkich bibliotek do augmentacji swojego zbioru danych. Odkrywamy moduł ImageOps z biblioteki Pillow, aby łatwo tworzyć lustrzane odbicia, odwracać i dostosowywać kontrast w celu sztucznego powiększenia danych treningowych.
Cześć, tu Alex z DEV STORIES DOT EU. Pillow: The Imaging Library, odcinek 5 z 5. Importujesz potężny framework do computer vision, dociągając gigabajty dependencies, tylko po to, by odwrócić kilka obrazów treningowych. Nie zawsze potrzebujesz ciężkiej, wyspecjalizowanej biblioteki, żeby zbudować solidny pipeline do augmentacji. Czasami wszystko, czego potrzebujesz, to lekka augmentacja: moduł ImageOps.
Zanim przyjrzymy się funkcjom, musimy oddzielić moduł ImageOps od modułu ImageFilter. Słuchacze czasami je mylą. ImageFilter aplikuje convolution kernels na obrazie, obliczając nowe wartości pikseli na podstawie ich sąsiadów, żeby tworzyć rozmycia lub znajdować krawędzie. ImageOps działa zupełnie inaczej. Dostarcza gotowe operacje typu pixel-mapping. Są to bezpośrednie, szybkie transformacje, które manipulują kolorem lub pozycją pojedynczych pikseli, bez polegania na skomplikowanej matematyce sąsiadujących pikseli.
Jeśli przygotowujesz dataset do machine learningu, ImageOps daje ci gotowe narzędzia do pomnożenia twoich danych. Masz do dyspozycji deterministyczne augmentacje przestrzenne. Funkcja mirror odwraca twój obraz w poziomie, zamieniając lewą i prawą stronę. Funkcja flip odwraca go w pionie, zamieniając górę z dołem. Obie operacje zachowują dokładne wymiary twoich oryginalnych danych, po prostu zmieniając ich orientację.
Masz też natychmiastowy dostęp do modyfikacji kolorów i kontrastu. Funkcja grayscale konwertuje twój obraz do ośmiobitowego formatu czarno-białego. Jest to powszechnie stosowane, żeby zredukować wymiarowość twoich danych wejściowych, gdy kolor nie ma znaczenia dla zadania klasyfikacji. Funkcja invert odwraca wszystkie kanały kolorów. Ośmiobitowy piksel o wartości zero przyjmuje wartość dwieście pięćdziesiąt pięć, zmieniając białe tło na czarne, a czerwone piksele na cyjanowe. Jest to bardzo skuteczne przy generowaniu negatywowych masek do zadań segmentacji.
A oto kluczowa sprawa. Funkcja autocontrast jest szczególnie przydatna do standaryzacji surowych datasetów z niespójnym oświetleniem. Oblicza histogram obrazu, znajduje najciemniejsze i najjaśniejsze piksele i rozciąga zakres kolorów tak, żeby najciemniejszy piksel stał się czystą czernią, a najjaśniejszy czystą bielą. Możesz przekazać procentowy cutoff do funkcji autocontrast. To mówi bibliotece Pillow, żeby zignorowała skrajne piksele typu outlier, takie jak pojedynczy jasny odblask słońca, podczas obliczania nowej krzywej kontrastu.
Wyobraź sobie budowę prostego generatora danych dla zdjęć satelitarnych. Zdjęcia satelitarne wyglądają poprawnie w każdej orientacji, więc możesz bezpiecznie podwoić swój zbiór treningowy za pomocą przesunięć przestrzennych. Piszesz funkcję, która przyjmuje katalog ze zdjęciami. Dla każdego pliku ładujesz obraz. Generujesz losowego integera. Jeśli integer jest parzysty, przekazujesz obraz do funkcji mirror z modułu ImageOps. Jeśli integer jest nieparzysty, przekazujesz go do funkcji flip. Następnie zapisujesz wynikowy obraz pod nową nazwą pliku z doklejonym typem transformacji. Właśnie pomnożyłeś swój dataset używając standardowej biblioteki, utrzymując swoje środowisko deploymentowe wyjątkowo lekkim.
Zamiast sięgać po ciężkie pakiety do machine learningu do podstawowego przygotowania danych, sprawdzenie oficjalnej dokumentacji pod kątem natywnych rozwiązań zapobiega zjawisku dependency bloat. Praktyczne eksperymentowanie z tymi wbudowanymi narzędziami drastycznie uprości twoje skrypty preprocessingowe. Jeśli chcesz zaproponować tematy do nowej serii, odwiedź devstories dot eu. To wszystko w tym odcinku. Dzięki za wysłuchanie i twórz dalej!
Tap to start playing
Browsers block autoplay
Share this episode
Episode
—
Copy this episode in another language:
Ta strona nie używa plików cookie. Nasz dostawca hostingu może rejestrować Twój adres IP do celów analitycznych. Dowiedz się więcej.