Rozpoznawanie ekranu #1: Biblioteka Pillow
Jako testerzy takich urządzeń, możemy mieć problem wyzwanie z automatyzowaniem testów UI (Interfejsu użytkownika). Biblioteka Pillow może być w tym pomocna.

Rozpoznawanie ekranu
Wiele projektów opartych o systemy wbudowane posiada wyświetlacz. Uogólniając, producenci urządzeń, wszędzie chcą umieścić wyświetlacze. Jako testerzy takich urządzeń, możemy mieć problem wyzwanie z automatyzowaniem takich testów. Często ogranicza się to do testów manualnych. Gdy screeny są stałe w niektórych sytuacjach, a developerzy mogą w jakiś sposób udostępnić nam możliwość robienia zrzutów ekranu i wysyłanie ich do naszego środowiska testowego. Wtedy możemy użyć biblioteki Pillow, aby porównać screen oczekiwany z tym, który właśnie jest wyświetlany na ekranie urządzenia.
Instalacja
Jednym z najprostszych sposobów instalacji biblioteki Pillow jest użycie programu pip:
pip install Pillow
Otwórz screen
Zacznijmy od zaczytania obrazu za pomocą Python’a. Będziemy potrzebowali do tego klasy Image importowaną z PIL. Zaczytywanym przez nas obrazem będzie screenshot ekranu smatphona stworzony w jednym z poprzednich artykułów:
Po tym, jak zostanie on zaczytany przy pomocy metody open zawartej w klasie Image, dla sprawdzenia, czy aby na pewno wczytałem odpowiedni obrazek, wyświetlę go na ekranie swojego komputera za pomocą metody show:
from PIL import Image
image1 = 'D:\qabrio\scrcpy\image1.JPG'
image1_open = Image.open(image1)
image1_open.show()
Po wykonaniu powyższego kodu na moim ekranie pojawił się poniższy rysunek:

Porównanie obrazów
Teraz gdy wiem, że zaczytuje poprawnie obrazek image1.JPG mogę przejść do porównania go z innymi grafikami. W moim przypadku będzie to image2.JPG i image3.JPG. Nie martw się to nie zadanie z cyklu, znajdź 7 różnic na obrazku. Jak widzisz poniżej obrazki image1 i image2 są identyczne. image3 jest monochromatyczny odpowiednikiem tych poprzednich:



Przejdźmy więc do porównania obrazów, które wykonujemy za pomocą klasy ImageChops. Każdy z obrazków wczytamy, ale nie będziemy już wyświetlać. Następnie zczytane obrazki porównamy metodą difference. Jej wynikiem jest obiekt klasy, z którego możemy wyłuskać, czy obrazki się różnią, używając metody getbbox. Jeżeli metoda ta zwraca None, to oznacza, że obrazy nie różnią się. Natomiast wynikiem różnic jest krotka z danymi liczbowymi. Dla potrzeb naszego porównania wystarczy nam sprawdzenie, czy wynikiem jest wartość None:
from PIL import Image
from PIL import ImageChops
image1 = 'D:\qabrio\scrcpy\image1.JPG'
image2 = 'D:\qabrio\scrcpy\image2.JPG'
image3 = 'D:\qabrio\scrcpy\image3.JPG'
image1_open = Image.open(image1)
image2_open = Image.open(image2)
image3_open = Image.open(image3)
diff_1_2 = ImageChops.difference(image1_open, image2_open)
print("Compare img1 and img2: ", diff_1_2.getbbox())
diff_1_3 = ImageChops.difference(image1_open, image3_open)
print("Compare img1 and img3: ", diff_1_3.getbbox())
Poniżej możemy zobaczyć wynik, którego się spodziewaliśmy. Otrzymaliśmy None z pierwszej metody print odnoszącej się do porównania image1 i image2. Za to przy drugiej metodzie print, porównującej image1 i image3, otrzymaliśmy krotkę z obszarem w którym znajduje się różnice (w moim przykładzie jest to cały obrazek):
Compare img1 and img2: None
Compare img1 and img3: (0, 0, 465, 953)
Od takich porównań można rozpocząć automatyzację testów, w których mamy dostęp do zrzutów ekranu testowanego urządzenia. W kolejnych odsłonach serii zaprezentuję bardziej rozbudowane metody porównawcze ekranów.