From cc7beb7670499d93caaa716bde27d6d64a5f59eb Mon Sep 17 00:00:00 2001 From: ww-rm Date: Thu, 3 Apr 2025 20:14:13 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0SFMLExtension?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SpineViewer/Exporter/ExportHelper.cs | 56 +-------------------- SpineViewer/SFMLExtension.cs | 73 ++++++++++++++++++++++++++++ SpineViewer/Spine/Spine.cs | 26 +--------- 3 files changed, 76 insertions(+), 79 deletions(-) create mode 100644 SpineViewer/SFMLExtension.cs diff --git a/SpineViewer/Exporter/ExportHelper.cs b/SpineViewer/Exporter/ExportHelper.cs index e8e2d19..2e13116 100644 --- a/SpineViewer/Exporter/ExportHelper.cs +++ b/SpineViewer/Exporter/ExportHelper.cs @@ -33,7 +33,7 @@ namespace SpineViewer.Exporter } /// - /// SFML.Graphics.Image 帧对象包装类 + /// SFML.Graphics.Image 帧对象包装类, 将接管给定的 image 对象生命周期 /// public class SFMLImageVideoFrame(SFML.Graphics.Image image) : IVideoFrame, IDisposable { @@ -64,13 +64,7 @@ namespace SpineViewer.Exporter /// /// 获取 Winforms Bitmap 对象 /// - public Bitmap CopyToBitmap() - { - image.SaveToMemory(out var imgBuffer, "bmp"); - using var stream = new MemoryStream(imgBuffer); - using var bitmap = new Bitmap(stream); - return new(bitmap); // 必须重复构造一个副本才能摆脱对流的依赖, 否则之后使用会报错 - } + public Bitmap CopyToBitmap() => image.CopyToBitmap(); } /// @@ -87,51 +81,5 @@ namespace SpineViewer.Exporter else if (imageFormat == ImageFormat.Exif) return ".jpeg"; else return $".{imageFormat.ToString().ToLower()}"; } - - #region 包围盒辅助函数 - - /// - /// 获取某个包围盒下合适的视图 - /// - public static SFML.Graphics.View GetView(this RectangleF bounds, Size resolution, Padding padding) - => bounds.GetView((uint)resolution.Width, (uint)resolution.Height, (uint)padding.Left, (uint)padding.Right, (uint)padding.Top, (uint)padding.Bottom); - - /// - /// 获取某个包围盒下合适的视图 - /// - public static SFML.Graphics.View GetView(this RectangleF bounds, uint width, uint height, Padding padding) - => bounds.GetView(width, height, (uint)padding.Left, (uint)padding.Right, (uint)padding.Top, (uint)padding.Bottom); - - /// - /// 获取某个包围盒下合适的视图 - /// - public static SFML.Graphics.View GetView(this RectangleF bounds, Size resolution, uint paddingL = 1, uint paddingR = 1, uint paddingT = 1, uint paddingB = 1) - => bounds.GetView((uint)resolution.Width, (uint)resolution.Height, paddingL, paddingR, paddingT, paddingB); - - /// - /// 获取某个包围盒下合适的视图 - /// - public static SFML.Graphics.View GetView(this RectangleF bounds, uint width, uint height, uint paddingL = 1, uint paddingR = 1, uint paddingT = 1, uint paddingB = 1) - { - float sizeX = bounds.Width; - float sizeY = bounds.Height; - float innerW = width - paddingL - paddingR; - float innerH = height - paddingT - paddingB; - - float scale = 1; - if (sizeY / sizeX < innerH / innerW) - scale = sizeX / innerW; // 相同的 X, 视窗 Y 更大 - else - scale = sizeY / innerH; // 相同的 Y, 视窗 X 更大 - - var x = bounds.X + bounds.Width / 2 + (paddingL - (float)paddingR) * scale; - var y = bounds.Y + bounds.Height / 2 + (paddingT - (float)paddingB) * scale; - var viewX = width * scale; - var viewY = height * scale; - - return new(new(x, y), new(viewX, -viewY)); - } - - #endregion } } diff --git a/SpineViewer/SFMLExtension.cs b/SpineViewer/SFMLExtension.cs new file mode 100644 index 0000000..a4fdf58 --- /dev/null +++ b/SpineViewer/SFMLExtension.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SpineViewer +{ + public static class SFMLExtension + { + /// + /// 获取 Winforms Bitmap 对象, 需要使用 Dispose 释放对象 + /// + public static Bitmap CopyToBitmap(this SFML.Graphics.Image image) + { + image.SaveToMemory(out var imgBuffer, "bmp"); + using var stream = new MemoryStream(imgBuffer); + using var bitmap = new Bitmap(stream); + return new(bitmap); // 必须重复构造一个副本才能摆脱对流的依赖, 否则之后使用会报错 + } + + /// + /// 获取 Winforms Bitmap 对象, 需要使用 Dispose 释放对象 + /// + public static Bitmap CopyToBitmap(this SFML.Graphics.Texture texture) + { + using var image = texture.CopyToImage(); + return CopyToBitmap(image); + } + + /// + /// 获取某个包围盒下合适的视图 + /// + public static SFML.Graphics.View GetView(this RectangleF bounds, Size resolution, Padding padding) + => bounds.GetView((uint)resolution.Width, (uint)resolution.Height, (uint)padding.Left, (uint)padding.Right, (uint)padding.Top, (uint)padding.Bottom); + + /// + /// 获取某个包围盒下合适的视图 + /// + public static SFML.Graphics.View GetView(this RectangleF bounds, uint width, uint height, Padding padding) + => bounds.GetView(width, height, (uint)padding.Left, (uint)padding.Right, (uint)padding.Top, (uint)padding.Bottom); + + /// + /// 获取某个包围盒下合适的视图 + /// + public static SFML.Graphics.View GetView(this RectangleF bounds, Size resolution, uint paddingL = 1, uint paddingR = 1, uint paddingT = 1, uint paddingB = 1) + => bounds.GetView((uint)resolution.Width, (uint)resolution.Height, paddingL, paddingR, paddingT, paddingB); + + /// + /// 获取某个包围盒下合适的视图 + /// + public static SFML.Graphics.View GetView(this RectangleF bounds, uint width, uint height, uint paddingL = 1, uint paddingR = 1, uint paddingT = 1, uint paddingB = 1) + { + float sizeX = bounds.Width; + float sizeY = bounds.Height; + float innerW = width - paddingL - paddingR; + float innerH = height - paddingT - paddingB; + + float scale = 1; + if (sizeY / sizeX < innerH / innerW) + scale = sizeX / innerW; // 相同的 X, 视窗 Y 更大 + else + scale = sizeY / innerH; // 相同的 Y, 视窗 X 更大 + + var x = bounds.X + bounds.Width / 2 + (paddingL - (float)paddingR) * scale; + var y = bounds.Y + bounds.Height / 2 + (paddingT - (float)paddingB) * scale; + var viewX = width * scale; + var viewY = height * scale; + + return new(new(x, y), new(viewX, -viewY)); + } + } +} diff --git a/SpineViewer/Spine/Spine.cs b/SpineViewer/Spine/Spine.cs index c8461b5..80f1829 100644 --- a/SpineViewer/Spine/Spine.cs +++ b/SpineViewer/Spine/Spine.cs @@ -1,21 +1,7 @@ using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Text.RegularExpressions; -using System.Numerics; -using System.Collections; using System.Collections.ObjectModel; using System.ComponentModel; using System.Reflection; -using System.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Text.Json.Nodes; -using System.Collections.Immutable; -using SpineViewer.Exporter; -using System.ComponentModel.Design; using System.Drawing.Design; namespace SpineViewer.Spine @@ -94,17 +80,7 @@ namespace SpineViewer.Spine tex.Clear(SFML.Graphics.Color.Transparent); tex.Draw(this); tex.Display(); - - using (var img = tex.Texture.CopyToImage()) - { - if (img.SaveToMemory(out var imgBuffer, "bmp")) - { - // 必须重复构造一个副本才能摆脱对流的依赖, 否则之后使用会报错 - using var stream = new MemoryStream(imgBuffer); - using var bitmap = new Bitmap(stream); - Preview = new Bitmap(bitmap); - } - } + Preview = tex.Texture.CopyToBitmap(); // 取最后一个作为初始, 尽可能去显示非默认的内容 skin = SkinNames.Last();