diff --git a/tools/logos_check.py b/tools/logos_check.py
new file mode 100755
index 00000000..8375ae17
--- /dev/null
+++ b/tools/logos_check.py
@@ -0,0 +1,75 @@
+#!/usr/bin/env python3
+
+import sys
+import argparse
+from pathlib import Path
+
+from PIL import Image
+
+
+class ImageCheck():
+    def __init__(self, imgpath: Path) -> None:
+        self.imgpath = imgpath
+        self.image = Image.open(imgpath)
+
+        self.fails: list[str] = []
+
+    def check(self) -> bool:
+        self.fails.clear()
+        for fn_name in dir(self):
+            if fn_name.startswith("check_"):
+                getattr(self, fn_name)()
+
+        if not self.fails:
+            return True
+
+        print(f"Image '{self.imgpath}' failed tests:")
+        for fail in self.fails:
+            print(f"  - {fail}")
+        print()
+        return False
+
+    def check_type(self) -> None:
+        format = self.image.format.lower()
+        accepted_formats = ["png", "jpeg", "webp"]
+        if format not in accepted_formats:
+            self.fails.append(f"Image should be one of {', '.join(accepted_formats)} but is {format}")
+
+    def check_dimensions(self) -> None:
+        dim_min, dim_max = 96, 300
+        dimensions_range = range(dim_min, dim_max+1)
+        w, h = self.image.width, self.image.height
+        if w not in dimensions_range or h not in dimensions_range:
+            self.fails.append(f"Dimensions should be in [{dim_min}, {dim_max}] but are {w}×{h}")
+
+    def check_ratio(self) -> None:
+        w, h = self.image.width, self.image.height
+        if w != h:
+            self.fails.append(f"Image is not square but {w}×{h}")
+
+    def check_filesize(self) -> None:
+        filesize = self.imgpath.stat().st_size
+        max_size = 80_000
+        if filesize > max_size:
+            self.fails.append(f"Filesize should be <={max_size/1000}kB but is {filesize/1000}kB")
+
+    def check_compressed(self) -> None:
+        pass
+
+
+def main() -> None:
+    parser = argparse.ArgumentParser()
+    parser.add_argument("logos", nargs="+", type=Path, help="Logos to check")
+    args = parser.parse_args()
+
+    total_result = True
+    for logo in args.logos:
+        checker = ImageCheck(logo)
+        if checker.check() is not True:
+            total_result = False
+
+    if not total_result:
+        sys.exit(1)
+
+if __name__ == "__main__":
+    main()