from __future__ import annotations import io import numpy as np from PIL import Image def depth_to_png16_bytes(depth: np.ndarray, target_hw: tuple[int, int] | None = None) -> bytes: depth = np.asarray(depth, dtype=np.float32).squeeze() if depth.ndim != 2: raise ValueError(f"depth 应为二维数组,实际 shape={depth.shape}") if target_hw is not None: th, tw = int(target_hw[0]), int(target_hw[1]) if th > 0 and tw > 0 and (depth.shape[0] != th or depth.shape[1] != tw): im = Image.fromarray(depth, mode="F") im = im.resize((tw, th), Image.Resampling.BILINEAR) depth = np.asarray(im, dtype=np.float32) dmin = float(depth.min()) dmax = float(depth.max()) if dmax > dmin: norm = (depth - dmin) / (dmax - dmin) else: norm = np.zeros_like(depth, dtype=np.float32) # 前后端约定:最远=255,最近=0(8-bit) u8 = ((1.0 - norm) * 255.0).clip(0, 255).astype(np.uint8) img = Image.fromarray(u8, mode="L") buf = io.BytesIO() img.save(buf, format="PNG") return buf.getvalue()