Browse Source

增加 DrawingUtility 类,提供保存图片的扩展方法

master
Elivo 2 months ago
parent
commit
304d48de26
  1. 108
      Apewer.Windows/Apewer.Windows.csproj
  2. 98
      Apewer/Apewer.csproj
  3. 123
      Apewer/DrawingUtility.cs

108
Apewer.Windows/Apewer.Windows.csproj

@ -1,64 +1,66 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\Apewer\Apewer.props" />
<Import Project="..\Apewer\Apewer.props" />
<PropertyGroup>
<NoWarn>CS0108;CS0612</NoWarn>
<TargetFrameworks>net461;net40;net20;netcoreapp3.1</TargetFrameworks>
</PropertyGroup>
<PropertyGroup>
<NoWarn>CS0108;CS0612</NoWarn>
<TargetFrameworks>net461;net40;net20;netcoreapp3.1</TargetFrameworks>
</PropertyGroup>
<!-- 打包 -->
<PropertyGroup>
<Description>实现 Windows 程序功能。</Description>
</PropertyGroup>
<!-- 打包 -->
<PropertyGroup>
<Description>实现 Windows 程序功能。</Description>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Apewer\Apewer.csproj" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Apewer\Apewer.csproj" />
</ItemGroup>
<!-- .NET Core 3.1 -->
<PropertyGroup Condition="'$(TargetFramework)'=='netcoreapp3.1'">
<!-- <UseWPF>true</UseWPF> -->
<!-- <UseWindowsForms>true</UseWindowsForms> -->
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)'=='netcoreapp3.1'">
<!-- <FrameworkReference Include="Microsoft.AspNetCore.App" /> -->
<FrameworkReference Include="Microsoft.WindowsDesktop.App" />
<!--<PackageReference Include="System.ServiceProcess.ServiceController" Version="4.4.0" />-->
<PackageReference Include="System.ServiceProcess.ServiceController" Version="6.0.0" />
</ItemGroup>
<!-- .NET Core 3.1 -->
<PropertyGroup Condition="'$(TargetFramework)'=='netcoreapp3.1'">
<!-- <UseWPF>true</UseWPF> -->
<!-- <UseWindowsForms>true</UseWindowsForms> -->
<DefineConstants>DRAWING;$(DefineConstants);$(AdditionalConstants)</DefineConstants>
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)'=='netcoreapp3.1'">
<!-- <FrameworkReference Include="Microsoft.AspNetCore.App" /> -->
<FrameworkReference Include="Microsoft.WindowsDesktop.App" />
<!--<PackageReference Include="System.ServiceProcess.ServiceController" Version="4.4.0" />-->
<PackageReference Include="System.ServiceProcess.ServiceController" Version="6.0.0" />
<Compile Include="..\Apewer\DrawingUtility.cs" />
</ItemGroup>
<!-- .NET Framework 4.6.1 -->
<ItemGroup Condition="'$(TargetFramework)'=='net461'">
<Reference Include="CustomMarshalers" />
<Reference Include="PresentationCore" />
<Reference Include="System.Drawing" />
<Reference Include="System.Management" />
<Reference Include="System.ServiceProcess " />
<Reference Include="System.Speech" />
<Reference Include="System.Windows.Forms" />
<Reference Include="WindowsBase" />
</ItemGroup>
<!-- .NET Framework 4.6.1 -->
<ItemGroup Condition="'$(TargetFramework)'=='net461'">
<Reference Include="CustomMarshalers" />
<Reference Include="PresentationCore" />
<Reference Include="System.Drawing" />
<Reference Include="System.Management" />
<Reference Include="System.ServiceProcess " />
<Reference Include="System.Speech" />
<Reference Include="System.Windows.Forms" />
<Reference Include="WindowsBase" />
</ItemGroup>
<!-- .NET Framework 4.0 -->
<ItemGroup Condition="'$(TargetFramework)'=='net40'">
<Reference Include="CustomMarshalers" />
<Reference Include="PresentationCore" />
<Reference Include="System.Drawing" />
<Reference Include="System.Management" />
<Reference Include="System.ServiceProcess " />
<Reference Include="System.Speech" />
<Reference Include="System.Windows.Forms" />
<Reference Include="WindowsBase" />
</ItemGroup>
<!-- .NET Framework 4.0 -->
<ItemGroup Condition="'$(TargetFramework)'=='net40'">
<Reference Include="CustomMarshalers" />
<Reference Include="PresentationCore" />
<Reference Include="System.Drawing" />
<Reference Include="System.Management" />
<Reference Include="System.ServiceProcess " />
<Reference Include="System.Speech" />
<Reference Include="System.Windows.Forms" />
<Reference Include="WindowsBase" />
</ItemGroup>
<!-- .NET Framework 2.0 -->
<ItemGroup Condition="'$(TargetFramework)'=='net20'">
<Reference Include="CustomMarshalers" />
<Reference Include="System.Configuration" />
<Reference Include="System.Management" />
<Reference Include="System.ServiceProcess " />
<Reference Include="System.Windows.Forms" />
</ItemGroup>
<!-- .NET Framework 2.0 -->
<ItemGroup Condition="'$(TargetFramework)'=='net20'">
<Reference Include="CustomMarshalers" />
<Reference Include="System.Configuration" />
<Reference Include="System.Management" />
<Reference Include="System.ServiceProcess " />
<Reference Include="System.Windows.Forms" />
</ItemGroup>
</Project> </Project>

98
Apewer/Apewer.csproj

@ -1,53 +1,53 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\Apewer\Apewer.props" />
<PropertyGroup>
<AppendTargetFrameworkToOutputPath>true</AppendTargetFrameworkToOutputPath>
<Description>实现通用的实用功能。</Description>
<TargetFrameworks>netstandard2.0;netcoreapp3.1;net461;net40;net20</TargetFrameworks>
</PropertyGroup>
<!-- .NET Standard 2.1 -->
<PropertyGroup Condition="'$(TargetFramework)'=='netstandard2.1'">
<DefineConstants>NETSTD;HAVE_ASYNC;HAVE_BIG_INTEGER;$(DefineConstants);$(AdditionalConstants)</DefineConstants>
</PropertyGroup>
<!-- .NET Standard 2.0 -->
<PropertyGroup Condition="'$(TargetFramework)'=='netstandard2.0'">
<DefineConstants>NETSTD;HAVE_ASYNC;HAVE_BIG_INTEGER;$(DefineConstants);$(AdditionalConstants)</DefineConstants>
</PropertyGroup>
<!-- .NET Framework 2.0 -->
<PropertyGroup Condition="'$(TargetFramework)'=='net20'">
<DefineConstants>NETFX;NET20;$(DefineConstants);$(AdditionalConstants)</DefineConstants>
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)'=='net20'">
<Reference Include="System.Web" />
<Reference Include="System.Windows.Forms" />
</ItemGroup>
<!-- .NET Framework 4.0 -->
<PropertyGroup Condition="'$(TargetFramework)'=='net40'">
<DefineConstants>NETFX;NET40;HAVE_BIG_INTEGER;$(DefineConstants);$(AdditionalConstants)</DefineConstants>
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)'=='net40'">
<Reference Include="System.Web" />
<Reference Include="System.Windows.Forms" />
</ItemGroup>
<!-- .NET Framework 4.6.1 -->
<PropertyGroup Condition="'$(TargetFramework)'=='net461'">
<DefineConstants>NETFX;NET461;NET45;HAVE_ASYNC;HAVE_BIG_INTEGER;$(DefineConstants);$(AdditionalConstants)</DefineConstants>
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)'=='net461'">
<Reference Include="System.Web" />
<Reference Include="System.Windows.Forms" />
</ItemGroup>
<!-- .NET Core 3.1 -->
<PropertyGroup Condition="'$(TargetFramework)'=='netcoreapp3.1'">
<DefineConstants>HAVE_ASYNC;HAVE_BIG_INTEGER;$(DefineConstants);$(AdditionalConstants)</DefineConstants>
</PropertyGroup>
<Import Project="..\Apewer\Apewer.props" />
<PropertyGroup>
<AppendTargetFrameworkToOutputPath>true</AppendTargetFrameworkToOutputPath>
<Description>实现通用的实用功能。</Description>
<TargetFrameworks>netstandard2.0;netcoreapp3.1;net461;net40;net20</TargetFrameworks>
</PropertyGroup>
<!-- .NET Standard 2.1 -->
<PropertyGroup Condition="'$(TargetFramework)'=='netstandard2.1'">
<DefineConstants>NETSTD;HAVE_ASYNC;HAVE_BIG_INTEGER;$(DefineConstants);$(AdditionalConstants)</DefineConstants>
</PropertyGroup>
<!-- .NET Standard 2.0 -->
<PropertyGroup Condition="'$(TargetFramework)'=='netstandard2.0'">
<DefineConstants>NETSTD;HAVE_ASYNC;HAVE_BIG_INTEGER;$(DefineConstants);$(AdditionalConstants)</DefineConstants>
</PropertyGroup>
<!-- .NET Framework 2.0 -->
<PropertyGroup Condition="'$(TargetFramework)'=='net20'">
<DefineConstants>NETFX;NET20;DRAWING;$(DefineConstants);$(AdditionalConstants)</DefineConstants>
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)'=='net20'">
<Reference Include="System.Web" />
<Reference Include="System.Windows.Forms" />
</ItemGroup>
<!-- .NET Framework 4.0 -->
<PropertyGroup Condition="'$(TargetFramework)'=='net40'">
<DefineConstants>NETFX;NET40;DRAWING;HAVE_BIG_INTEGER;$(DefineConstants);$(AdditionalConstants)</DefineConstants>
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)'=='net40'">
<Reference Include="System.Web" />
<Reference Include="System.Windows.Forms" />
</ItemGroup>
<!-- .NET Framework 4.6.1 -->
<PropertyGroup Condition="'$(TargetFramework)'=='net461'">
<DefineConstants>NETFX;NET461;NET45;DRAWING;HAVE_ASYNC;HAVE_BIG_INTEGER;$(DefineConstants);$(AdditionalConstants)</DefineConstants>
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)'=='net461'">
<Reference Include="System.Web" />
<Reference Include="System.Windows.Forms" />
</ItemGroup>
<!-- .NET Core 3.1 -->
<PropertyGroup Condition="'$(TargetFramework)'=='netcoreapp3.1'">
<DefineConstants>HAVE_ASYNC;HAVE_BIG_INTEGER;$(DefineConstants);$(AdditionalConstants)</DefineConstants>
</PropertyGroup>
</Project> </Project>

123
Apewer/DrawingUtility.cs

@ -0,0 +1,123 @@
#if DRAWING
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
namespace Apewer
{
/// <summary>绘图。</summary>
public static class DrawingUtility
{
/// <summary>优化 Graphics 对象的属性,提升绘图质量。</summary>
public static Graphics Optimize(this Graphics graphics)
{
if (graphics != null)
{
graphics.CompositingMode = CompositingMode.SourceOver;
graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.SmoothingMode = SmoothingMode.AntiAlias;
}
return graphics;
}
/// <summary>保存图像为文件。</summary>
/// <exception cref="ArgumentNullException"></exception>
public static byte[] Save(this Image image, ImageFormat format)
{
if (image == null) throw new ArgumentNullException(nameof(image));
if (format == null) throw new ArgumentNullException(nameof(format));
using (var memory = new MemoryStream())
{
image.Save(memory, format);
return memory.ToArray();
}
}
/// <summary>保存为 JPEG 文件。</summary>
/// <param name="image">Image 实例。</param>
/// <param name="quality">JPEG 质量,0 为最低质量,100 为最高质量。</param>
/// <exception cref="ArgumentNullException" />
/// <exception cref="ArgumentOutOfRangeException" />
/// <exception cref="System.Runtime.InteropServices.ExternalException" />
public static byte[] SaveAsJpeg(this Image image, int quality = 100)
{
if (image == null) throw new ArgumentNullException(nameof(image));
if (quality < 0 || quality > 100) throw new ArgumentOutOfRangeException(nameof(quality));
var codec = ImageCodecInfo.GetImageDecoders().Find(x => x.FormatID == ImageFormat.Jpeg.Guid);
if (codec == null) throw new System.Runtime.InteropServices.ExternalException($"系统中不存在 JPEG 编码器。");
var parameters = new EncoderParameters(1);
parameters.Param[0] = new EncoderParameter(Encoder.Quality, quality);
using (var memory = new MemoryStream())
{
image.Save(memory, codec, parameters);
return memory.ToArray();
}
}
/// <summary>缩放图像,生成新图像。</summary>
/// <param name="image">原始图像。</param>
/// <param name="size">新图像的大小。</param>
/// <param name="backgroundColor">填充新图像背景色。</param>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="ArgumentOutOfRangeException"></exception>
public static Bitmap Scale(this Image image, Size size, Color? backgroundColor = null) => Scale(image, size.Width, size.Height, backgroundColor);
/// <summary>缩放图像,生成新图像。</summary>
/// <param name="image">原始图像。</param>
/// <param name="width">新图像的宽度。</param>
/// <param name="height">新图像的高度。</param>
/// <param name="backgroundColor">填充新图像背景色。</param>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="ArgumentOutOfRangeException"></exception>
static Bitmap Scale(this Image image, int width, int height, Color? backgroundColor = null)
{
if (image == null) throw new ArgumentNullException(nameof(image));
if (width < 1) throw new ArgumentOutOfRangeException(nameof(width));
if (height < 1) throw new ArgumentOutOfRangeException(nameof(height));
// 检查原始图像是否为透明格式
var rawFormat = image.RawFormat;
var isTransparentFormat = rawFormat.Equals(ImageFormat.Png) || rawFormat.Equals(ImageFormat.Gif);
var pixelFormat = isTransparentFormat ? PixelFormat.Format32bppArgb : PixelFormat.Format24bppRgb;
var bitmap = new Bitmap(width, height, pixelFormat);
try
{
using (var graphic = Graphics.FromImage(bitmap))
{
graphic.CompositingMode = CompositingMode.SourceOver;
graphic.CompositingQuality = CompositingQuality.HighQuality;
graphic.SmoothingMode = SmoothingMode.AntiAlias;
// 填充背景色
if (isTransparentFormat)
{
if (backgroundColor != null && backgroundColor.HasValue) graphic.Clear(backgroundColor.Value);
}
// 绘制新图像
graphic.DrawImage(image, 0, 0, width, height);
}
return bitmap;
}
catch
{
bitmap.Dispose();
throw;
}
}
}
}
#endif
Loading…
Cancel
Save