增加SFMLExtension
This commit is contained in:
@@ -33,7 +33,7 @@ namespace SpineViewer.Exporter
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// SFML.Graphics.Image 帧对象包装类
|
/// SFML.Graphics.Image 帧对象包装类, 将接管给定的 image 对象生命周期
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class SFMLImageVideoFrame(SFML.Graphics.Image image) : IVideoFrame, IDisposable
|
public class SFMLImageVideoFrame(SFML.Graphics.Image image) : IVideoFrame, IDisposable
|
||||||
{
|
{
|
||||||
@@ -64,13 +64,7 @@ namespace SpineViewer.Exporter
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取 Winforms Bitmap 对象
|
/// 获取 Winforms Bitmap 对象
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Bitmap CopyToBitmap()
|
public Bitmap CopyToBitmap() => image.CopyToBitmap();
|
||||||
{
|
|
||||||
image.SaveToMemory(out var imgBuffer, "bmp");
|
|
||||||
using var stream = new MemoryStream(imgBuffer);
|
|
||||||
using var bitmap = new Bitmap(stream);
|
|
||||||
return new(bitmap); // 必须重复构造一个副本才能摆脱对流的依赖, 否则之后使用会报错
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -87,51 +81,5 @@ namespace SpineViewer.Exporter
|
|||||||
else if (imageFormat == ImageFormat.Exif) return ".jpeg";
|
else if (imageFormat == ImageFormat.Exif) return ".jpeg";
|
||||||
else return $".{imageFormat.ToString().ToLower()}";
|
else return $".{imageFormat.ToString().ToLower()}";
|
||||||
}
|
}
|
||||||
|
|
||||||
#region 包围盒辅助函数
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取某个包围盒下合适的视图
|
|
||||||
/// </summary>
|
|
||||||
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);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取某个包围盒下合适的视图
|
|
||||||
/// </summary>
|
|
||||||
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);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取某个包围盒下合适的视图
|
|
||||||
/// </summary>
|
|
||||||
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);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取某个包围盒下合适的视图
|
|
||||||
/// </summary>
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
73
SpineViewer/SFMLExtension.cs
Normal file
73
SpineViewer/SFMLExtension.cs
Normal file
@@ -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
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获取 Winforms Bitmap 对象, 需要使用 Dispose 释放对象
|
||||||
|
/// </summary>
|
||||||
|
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); // 必须重复构造一个副本才能摆脱对流的依赖, 否则之后使用会报错
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取 Winforms Bitmap 对象, 需要使用 Dispose 释放对象
|
||||||
|
/// </summary>
|
||||||
|
public static Bitmap CopyToBitmap(this SFML.Graphics.Texture texture)
|
||||||
|
{
|
||||||
|
using var image = texture.CopyToImage();
|
||||||
|
return CopyToBitmap(image);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取某个包围盒下合适的视图
|
||||||
|
/// </summary>
|
||||||
|
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);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取某个包围盒下合适的视图
|
||||||
|
/// </summary>
|
||||||
|
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);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取某个包围盒下合适的视图
|
||||||
|
/// </summary>
|
||||||
|
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);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取某个包围盒下合适的视图
|
||||||
|
/// </summary>
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,21 +1,7 @@
|
|||||||
using System;
|
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.Collections.ObjectModel;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Reflection;
|
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;
|
using System.Drawing.Design;
|
||||||
|
|
||||||
namespace SpineViewer.Spine
|
namespace SpineViewer.Spine
|
||||||
@@ -94,17 +80,7 @@ namespace SpineViewer.Spine
|
|||||||
tex.Clear(SFML.Graphics.Color.Transparent);
|
tex.Clear(SFML.Graphics.Color.Transparent);
|
||||||
tex.Draw(this);
|
tex.Draw(this);
|
||||||
tex.Display();
|
tex.Display();
|
||||||
|
Preview = tex.Texture.CopyToBitmap();
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 取最后一个作为初始, 尽可能去显示非默认的内容
|
// 取最后一个作为初始, 尽可能去显示非默认的内容
|
||||||
skin = SkinNames.Last();
|
skin = SkinNames.Last();
|
||||||
|
|||||||
Reference in New Issue
Block a user