From b3d758a3e387a409e7743ff7b18785ad302657e2 Mon Sep 17 00:00:00 2001 From: Hector <145347438+hudomn@users.noreply.github.com> Date: Thu, 26 Feb 2026 18:04:12 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8B=96=E5=8A=A8=E5=AF=BC=E5=85=A5=E6=A8=A1?= =?UTF-8?q?=E5=9E=8B=E5=B8=A7=E7=8E=87=E5=BC=82=E5=B8=B8=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=EF=BC=8C=E6=B7=BB=E5=8A=A0web=E8=A7=86=E5=9B=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ui/panels/editor_panels.py | 78 +++++++++++++++++++++++++------------- 1 file changed, 51 insertions(+), 27 deletions(-) diff --git a/ui/panels/editor_panels.py b/ui/panels/editor_panels.py index 042d63f3..44e4300a 100644 --- a/ui/panels/editor_panels.py +++ b/ui/panels/editor_panels.py @@ -1,7 +1,14 @@ from imgui_bundle import imgui, imgui_ctx import os +import io +import tempfile +import time from pathlib import Path -from panda3d.core import PNMImage, StringStream, Texture +from panda3d.core import Filename +try: + from PIL import Image +except Exception: # pragma: no cover - pillow may be missing in minimal env + Image = None class EditorPanels: @@ -36,10 +43,10 @@ class EditorPanels: self.app.web_panel_url_input = "https://www.example.com" if not hasattr(self.app, "_imgui_webview"): self.app._imgui_webview = None - if not hasattr(self.app, "_imgui_webview_texture"): - self.app._imgui_webview_texture = None if not hasattr(self.app, "_imgui_webview_tex_id"): self.app._imgui_webview_tex_id = None + if not hasattr(self.app, "_imgui_webview_texture_path"): + self.app._imgui_webview_texture_path = None def _start_imgui_webview(self, url): self._ensure_web_panel_state() @@ -76,7 +83,13 @@ class EditorPanels: except Exception: pass self.app._imgui_webview_tex_id = None - self.app._imgui_webview_texture = None + texture_path = getattr(self.app, "_imgui_webview_texture_path", None) + if texture_path: + try: + Path(texture_path).unlink(missing_ok=True) + except Exception: + pass + self.app._imgui_webview_texture_path = None def _navigate_web_panel(self): self._ensure_web_panel_state() @@ -102,30 +115,41 @@ class EditorPanels: if not jpeg_bytes: return - pnm = PNMImage() - if not pnm.read(StringStream(jpeg_bytes), "imgui_webview.png"): + try: + if Image is None: + self.app.add_warning_message("缺少 Pillow,无法更新Web纹理") + return + img = Image.open(io.BytesIO(jpeg_bytes)).convert("RGBA") + # p3dimgui 纹理坐标系与网页截图存在Y轴方向差异,先在像素层修正 + img = img.transpose(Image.FLIP_TOP_BOTTOM) + + temp_dir = Path(tempfile.gettempdir()) / "eg_imgui_webpanel" + temp_dir.mkdir(parents=True, exist_ok=True) + temp_path = temp_dir / f"webview_{time.time_ns()}.png" + img.save(temp_path, format="PNG") + + panda_path = Filename.fromOsSpecific(str(temp_path)).getFullpath() + new_tex_id = self.app.imgui.loadTexture(panda_path) + old_tex_id = getattr(self.app, "_imgui_webview_tex_id", None) + if old_tex_id: + try: + self.app.imgui.removeTexture(old_tex_id) + except Exception: + pass + + old_texture_path = getattr(self.app, "_imgui_webview_texture_path", None) + if old_texture_path: + try: + Path(old_texture_path).unlink(missing_ok=True) + except Exception: + pass + + self.app._imgui_webview_tex_id = new_tex_id + self.app._imgui_webview_texture_path = str(temp_path) + except Exception as e: + self.app.add_warning_message(f"Web纹理更新失败: {e}") + finally: webview.tex_dirty = False - return - # p3dimgui 纹理坐标系与网页截图存在Y轴方向差异,先在像素层修正 - pnm.flip(False, True, False) - - # 某些后端在“已注册纹理原位更新”时存在稳定性问题。 - # 改为每次创建新纹理并替换旧纹理ID,避免原位更新导致崩溃。 - texture = Texture("imgui_web_panel_texture") - texture.load(pnm) - new_tex_id = self.app.imgui.loadTexture(texture) - - old_tex_id = getattr(self.app, "_imgui_webview_tex_id", None) - if old_tex_id: - try: - self.app.imgui.removeTexture(old_tex_id) - except Exception: - pass - - self.app._imgui_webview_texture = texture - self.app._imgui_webview_tex_id = new_tex_id - - webview.tex_dirty = False @staticmethod def _clamp01(value):