CI / Go Backend (push) Canceled after 0s
初始化 monorepo: Go后端(7微服务) + Unity客户端(9模块) + 启动器 HTML5原型: Three.js 3D体素世界, Perlin噪声地形, 原版材质, 22种方块 Minecraft创造模式背包: 双栏布局, 拖拽移动物品, 方向性元件引脚 AI助搭策划文档 + 客户端/服务端骨架 + Docker Compose + CI
78 lines
3.1 KiB
C#
78 lines
3.1 KiB
C#
using System;
|
||
using System.IO;
|
||
using System.Windows.Media.Imaging;
|
||
|
||
namespace PCL.Core.UI.Media;
|
||
|
||
public static class ImageConverter
|
||
{
|
||
/// <summary>
|
||
/// 从 WebP 输入流解码并转换为 PNG,返回包含 PNG 数据的 MemoryStream(Position=0)。
|
||
/// 需要系统内置的 WebP WIC 编解码器(Windows 10/11 通常已内置或可通过商店扩展提供)。
|
||
/// </summary>
|
||
/// <param name="input">输入 WebP 流(不会在此方法中关闭)</param>
|
||
/// <param name="frameIndex">要提取的帧索引,默认 0</param>
|
||
/// <returns>包含 PNG 数据的 MemoryStream,调用方负责释放</returns>
|
||
/// <exception cref="ArgumentOutOfRangeException">帧索引超出图像支持范围</exception>
|
||
/// <exception cref="NotSupportedException">系统缺少 WebP 解码器,或数据格式不受支持</exception>
|
||
// Partly generated by gpt-5 (20250813)
|
||
public static MemoryStream FromWebpToPng(this Stream input, int frameIndex = 0)
|
||
{
|
||
// 确保有可寻址的源流
|
||
var source = input;
|
||
MemoryStream? tempBuffer = null;
|
||
if (!input.CanSeek)
|
||
{
|
||
tempBuffer = new MemoryStream();
|
||
input.CopyTo(tempBuffer);
|
||
tempBuffer.Position = 0;
|
||
source = tempBuffer;
|
||
}
|
||
else
|
||
{
|
||
// 从开头解码
|
||
if (source.Position != 0) source.Position = 0;
|
||
}
|
||
try
|
||
{
|
||
// 使用 WPF 的 BitmapDecoder(底层是 WIC)。OnLoad 使得图像数据在解码完成后与源流解耦。
|
||
var decoder = BitmapDecoder.Create(
|
||
source,
|
||
BitmapCreateOptions.PreservePixelFormat,
|
||
BitmapCacheOption.OnLoad);
|
||
|
||
if (decoder.Frames.Count == 0)
|
||
throw new NotSupportedException("未能从输入数据解码出任何图像帧,可能不是有效的 WebP 图像。");
|
||
|
||
if (frameIndex < 0 || frameIndex >= decoder.Frames.Count)
|
||
throw new ArgumentOutOfRangeException(nameof(frameIndex), $"帧索引超出范围(0..{decoder.Frames.Count - 1})。");
|
||
|
||
var frame = decoder.Frames[frameIndex];
|
||
|
||
var encoder = new PngBitmapEncoder();
|
||
// 使用 BitmapFrame.Create 包装,避免后续冻结或依赖源的问题
|
||
encoder.Frames.Add(BitmapFrame.Create(frame));
|
||
|
||
var output = new MemoryStream();
|
||
encoder.Save(output);
|
||
output.Position = 0;
|
||
return output;
|
||
}
|
||
catch (NotSupportedException)
|
||
{
|
||
// 透传,提示缺少编解码器或格式不支持
|
||
throw;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
// 统一转为更明确的异常信息(保留原始异常以便调试)
|
||
throw new NotSupportedException("转换 WebP 到 PNG 失败:输入可能不是有效的 WebP,或系统未提供所需的编解码支持。", ex);
|
||
}
|
||
finally
|
||
{
|
||
// 仅释放我们创建的临时缓冲,不关闭调用方传入的 input
|
||
tempBuffer?.Dispose();
|
||
}
|
||
}
|
||
}
|