{"record":{"id":"638070b6c6e7a728","repo":"deepfakes/faceswap","slug":"for-arrow-image-the-minimum-size-across-any-axis","errorCode":null,"errorMessage":"For arrow image, the minimum size across any axis must be 8 and dimensions must all be divisible by 2","messagePattern":"For arrow image, the minimum size across any axis must be 8 and dimensions must all be divisible by 2","errorType":"exception","errorClass":"FaceswapError","httpStatus":null,"severity":"error","filePath":"lib/gui/theme.py","lineNumber":490,"sourceCode":"        \"\"\" Return a background color with a \"v\" arrow in foreground color\n\n        Parameters\n        ----------\n        dimensions: tuple\n            The (`width`, `height`) of the desired tk image\n        thickness: int\n            The thickness of the pattern to be drawn\n        direction: [\"left\", \"up\", \"right\", \"down\"]\n            The direction that the pattern should be facing\n\n        Returns\n        -------\n        :class:`numpy.ndarray`\n            A 2D, UINT8 array of shape (height, width) of all zeros\n        \"\"\"\n        square_size = min(dimensions[1], dimensions[0])\n        if square_size < 16 or any(dim % 2 != 0 for dim in dimensions):\n            raise FaceswapError(\"For arrow image, the minimum size across any axis must be 8 and \"\n                                \"dimensions must all be divisible by 2\")\n        crop_size = (square_size // 16) * 16\n        draw_rows = int(6 * crop_size / 16)\n        start_row = dimensions[1] // 2 - draw_rows // 2\n        initial_indent = 2 * (crop_size // 16) + (dimensions[0] - crop_size) // 2\n\n        retval = np.zeros((dimensions[1], dimensions[0]), dtype=\"uint8\")\n        for i in range(start_row, start_row + draw_rows):\n            indent = initial_indent + i - start_row\n            join = (min(indent + thickness, dimensions[0] // 2),\n                    max(dimensions[0] - indent - thickness, dimensions[0] // 2))\n            retval[i, np.r_[indent:join[0], join[1]:dimensions[0] - indent]] = 1\n        if direction in (\"right\", \"left\"):\n            retval = np.rot90(retval)\n        if direction in (\"up\", \"left\"):\n            retval = np.flip(retval)\n        return retval\n","sourceCodeStart":472,"sourceCodeEnd":508,"githubUrl":"https://github.com/deepfakes/faceswap/blob/f530cb7508ae670f6474f8a7d9c4df94705cf96b/lib/gui/theme.py#L472-L508","documentation":"lib/image.py read_image_wrap catches TypeError from the cv2/PIL decode path: the file was opened but decoding raised TypeError (cv2 raises TypeError when handed None/invalid buffer rather than a clean cv2 error). Faceswap logs the message and re-raises TypeError only if raise_error=True, otherwise returns None and marks success=False.","triggerScenarios":"read_image(filename, raise_error=True) where the bytes read from disk are not a decodable image (zero-length file, HTML error page saved as .png, truncated download); or with_metadata=True on a non-PNG file where PNG header parsing gets None values.","commonSituations":"Partially downloaded/corrupted images in an extraction folder; a file being written concurrently while read; mismatched extension (file named .png but contains JPEG data combined with metadata parsing); filesystem returning empty reads on network mounts.","solutions":["Verify the file outside Faceswap: file integrity, non-zero size, `cv2.imread` in a scratch script","Re-download or re-extract the offending image; remove zero-byte files (find . -size 0 -delete after review)","Pass raise_error=False and check the None return to skip bad frames instead of aborting"],"exampleFix":"# before\nimg = read_image(\"frame_000001.png\", raise_error=True)  # TypeError on corrupt file\n\n# after\nimg = read_image(\"frame_000001.png\", raise_error=False)\nif img is None:\n    logger.warning(\"skipping unreadable frame\")\n    continue","handlingStrategy":"fallback","validationCode":"import os\n\ndef readable_image(path):\n    return os.path.isfile(path) and os.path.getsize(path) > 0\n\n# skip empty/corrupt candidates before read_image","typeGuard":"def likely_readable_image(path: str) -> bool:\n    \"\"\"Cheap pre-check: existing, non-empty file.\"\"\"\n    import os\n    return os.path.isfile(path) and os.path.getsize(path) > 0","tryCatchPattern":"try:\n    img = read_image(path, raise_error=True)\nexcept TypeError as err:\n    if \"Error while reading image (TypeError)\" in str(err):\n        quarantine(path); img = None\n    else:\n        raise","preventionTips":["Prefer raise_error=False in batch pipelines and check for None","Filter zero-byte files before runs: find dir -size 0","Verify downloads completed before feeding extraction"],"tags":["faceswap","image-io","opencv","corrupt-file","cv2"],"backgroundTag":null,"analyzedSha":"f530cb7508ae670f6474f8a7d9c4df94705cf96b","analyzedAt":"2026-08-15T02:59:26.626Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}