.Net7.0 或更高版本 System.Drawing.Common 上传图片跨平台方案

项目升级.Net7.0+以后,System.Drawing.Common开关已经被删除,且System.Drawing.Common仅在 Windows 上支持 ,于是想办法将原来上传图片验证文件名和获取图片扩展名方法替换一下,便开始搜索相关解决方案。

.Net6.0文档:中断性变更:仅在 Windows 上支持 System.Drawing.Common - .NET | Microsoft Learn

.Net7.0文档:中断性变更:删除了 System.Drawing.Common 配置开关 - .NET | Microsoft Learn 

旧行为

在 .NET 6 之前,使用 System.Drawing.Common 包不会产生任何编译时警告,也不会引发任何运行时异常。

新行为

从 .NET 6 开始,当为非 Windows 操作系统编译引用代码时,平台分析器会发出编译时警告。 此外,除非设置了配置选项,否则将引发以下运行时异常:

System.TypeInitializationException : The type initializer for 'Gdip' threw an exception.
      ---- System.PlatformNotSupportedException : System.Drawing.Common is not supported on non-Windows platforms. See https://aka.ms/systemdrawingnonwindows for more information.
      Stack Trace:
           at System.Drawing.SafeNativeMethods.Gdip.GdipCreateBitmapFromFile(String filename, IntPtr& bitmap)
        /_/src/libraries/System.Drawing.Common/src/System/Drawing/Bitmap.cs(42,0): at System.Drawing.Bitmap..ctor(String filename, Boolean useIcm)
        /_/src/libraries/System.Drawing.Common/src/System/Drawing/Bitmap.cs(25,0): at System.Drawing.Bitmap..ctor(String filename)
        /_/src/libraries/System.Resources.ResourceManager/tests/ResourceManagerTests.cs(270,0): at System.Resources.Tests.ResourceManagerTests.EnglishImageResourceData()+MoveNext()
        /_/src/libraries/System.Linq/src/System/Linq/Select.cs(136,0): at System.Linq.Enumerable.SelectEnumerableIterator`2.MoveNext()
        ----- Inner Stack Trace -----
        /_/src/libraries/System.Drawing.Common/src/System/Drawing/LibraryResolver.cs(31,0): at System.Drawing.LibraryResolver.EnsureRegistered()
        /_/src/libraries/System.Drawing.Common/src/System/Drawing/GdiplusNative.Unix.cs(65,0): at System.Drawing.SafeNativeMethods.Gdip.PlatformInitialize()
        /_/src/libraries/System.Drawing.Common/src/System/Drawing/Gdiplus.cs(27,0): at System.Drawing.SafeNativeMethods.Gdip..cctor()

可通过将 runtimeconfig.json 文件中的 System.Drawing.EnableUnixSupport运行时配置开关设置为 true 来启用对 .NET 6 中非 Windows 平台的支持。

runtimeconfig.template.json 模板文件:

{
   "configProperties": {
      "System.Drawing.EnableUnixSupport": true
   }
}

[appname].runtimeconfig.json 输出文件:

{
   "runtimeOptions": {
      "configProperties": {
         "System.Drawing.EnableUnixSupport": true
      }
   }
}

上面描述.Net6.0之前还是可以使用System.Drawing.Common,.Net6.0需要设置开关,而.Net7.0中直接将开关删除,由于项目中上传文件验证文件格式等操作,于是便搜索相关替代方案。

在github中发现一个开源项目:https://github.com/iron-software/IronSoftware.System.Drawing

 将项目中代码替换为IronSoftware.System.Drawing类库,本文使用的版本为:

保存图片:

/// <summary>
/// 字节数组转换成图片
/// hef 2023.03.10 13:53 将原System.Drawing替换为IronSoftware.Drawing
/// </summary>
/// <param name="buffer"></param>
/// <param name="sImgSavePath"></param>
/// <returns></returns>
static public string ByteToImg(byte[] buffer, string sImgSavePath)
{
    AnyBitmap img = AnyBitmap.FromBytes(buffer);
    img.SaveAs(sImgSavePath);
    return sImgSavePath;
}

获取图片扩展名:

/// <summary>
/// 获取图片后缀
/// hef 2023.03.10 13:54 将原System.Drawing替换为IronSoftware.Drawing
/// </summary>
/// <param name="image"></param>
/// <returns></returns>
static public string GetImageExt(AnyBitmap image)
{
    string imageExt = "";
    var RawFormat = image.GetImageFormat();
    if (RawFormat == AnyBitmap.ImageFormat.Png)
    {
        imageExt = ".png";
    }
    if (RawFormat == AnyBitmap.ImageFormat.Jpeg)
    {
        imageExt = ".jpg";
    }
    if (RawFormat == AnyBitmap.ImageFormat.Bmp)
    {
        imageExt = ".bmp";
    }
    if (RawFormat == AnyBitmap.ImageFormat.Gif)
    {
        imageExt = ".gif";
    }
    if (RawFormat == AnyBitmap.ImageFormat.Icon)
    {
        imageExt = ".icon";
    }
    if (RawFormat == AnyBitmap.ImageFormat.Wbmp)
    {
        imageExt = ".bmp";
    }
    if (RawFormat == AnyBitmap.ImageFormat.Webp)
    {
        imageExt = ".png";
    }
    return imageExt;
}

你可以直接获取扩展名:

string sExtName = Enum.GetName(typeof(AnyBitmap.ImageFormat), AnyBitmap.ImageFormat.Gif);

使用上面一行代码得到的值为gif,并不包含.[点]

使用封装的方法如下,列举两种常用方法,你也可以使用其它方法:

1.通过字节数组转换为AnyBitmap
var vAnyBitmap = IronSoftware.Drawing.AnyBitmap.FromBytes(bytes);

2.通过Stream转换为AnyBitmap
var vAnyBitmap = IronSoftware.Drawing.AnyBitmap.FromStream(fileStream);

string sImgExt = FileHelper.GetImageExt(vAnyBitmap);

 其它示例:

Bitmap to Stream:

using IronSoftware.Drawing;
using System.IO;
 
AnyBitmap bitmap = AnyBitmap.FromFile(@"FILE_PATH");
 
// Get stream of AnyBitmap
MemoryStream stream = bitmap.GetStream();
 
// Convert AnyBitmap to stream
MemoryStream stream1 = bitmap.ToStream();

Bitmap to String:

using IronSoftware.Drawing;
 
AnyBitmap bitmap = AnyBitmap.FromFile(@"FILE_PATH");
 
// Convert AnyBitmap to a string that represents the object
string bitmapString = bitmap.ToString();

Cast to AnyBitmap:

using IronSoftware.Drawing;
using System.IO;
 
// We create an AnyBitmap object. We will then cast other popular types to Anybitmap.
AnyBitmap anyBitmap;
 
// Cast System.Drawing bitmap to AnyBitmap
System.Drawing.Bitmap bitmapFromBitmap = new System.Drawing.Bitmap(@"FILE_PATH");
anyBitmap = bitmapFromBitmap;
 
// Cast System image to AnyBitmap
System.Drawing.Image bitmapFromFile = System.Drawing.Image.FromFile(@"FILE_PATH");
anyBitmap = bitmapFromFile;
 
// Cast SKBitmap to AnyBitmap
SkiaSharp.SKBitmap skiaBitmap = SkiaSharp.SKBitmap.Decode(@"FILE_PATH");
anyBitmap = skiaBitmap;
 
// Cast SKimage to AnyBitmap
SkiaSharp.SKImage skiaImage = SkiaSharp.SKImage.FromBitmap(SkiaSharp.SKBitmap.Decode(@"FILE_PATH"));
anyBitmap = skiaImage;
 
// Cast SixLabors Image to AnyBitmap
SixLabors.ImageSharp.Image<SixLabors.ImageSharp.PixelFormats.Rgba32> imgSharp = SixLabors.ImageSharp.Image.Load<SixLabors.ImageSharp.PixelFormats.Rgba32>(@"FILE_PATH");
anyBitmap = imgSharp;
 
// Cast Maui image to AnyBitmap (not for NET 4.7.2):
byte[] imageAsBytes = File.ReadAllBytes(@"FILE_PATH");
// var mauiPlatformImage = Microsoft.Maui.Graphics.Platform.PlatformImage.FromStream(new MemoryStream(imageAsBytes));

Clone AnyBitmap:

using IronSoftware.Drawing;
 
// Clone an AnyBitmap
AnyBitmap clonedframe = AnyBitmap.FromFile(@"FILE_PATH").Clone();
clonedframe.SaveAs("frameClone.jpg");
 
// Clone frames of any image with a specified crop area
AnyBitmap clonedWithCrop = AnyBitmap.FromFile(@"FILE_PATH").Clone(new Rectangle(0, 0, 150, 150));
clonedWithCrop.SaveAs("cropCloned.jpg");

Create Multipage TIFF and GIF:

using IronSoftware.Drawing;
using System.Collections.Generic;
 
// Create a multipage Tiff with frames of different dimensions
List<AnyBitmap> tiffBitmaps = new List<AnyBitmap>()
{
     AnyBitmap.FromFile("cropframe1.jpg"),
     AnyBitmap.FromFile("frame2.jpg"),
     AnyBitmap.FromFile("cropframe3.jpg")
};
AnyBitmap multiFrameTiff = AnyBitmap.CreateMultiFrameTiff(tiffBitmaps);
multiFrameTiff.SaveAs("multiTiffwcrops.tiff");
 
 
// Create a multipage Gif with frames of different dimensions
List<AnyBitmap> gifBitmaps = new List<AnyBitmap>()
{
    AnyBitmap.FromFile("frame1.jpg"),
    AnyBitmap.FromFile("frame2.jpg"),
    AnyBitmap.FromFile("frame3.jpg"),
    AnyBitmap.FromFile("cropframe4.jpg")
};
AnyBitmap multiFrameGif = AnyBitmap.CreateMultiFrameGif(gifBitmaps);
multiFrameGif.SaveAs("multiGif.gif");

Export AnyBitmap:

using IronSoftware.Drawing;
 
//Export AnyBitmap files to other formats with ability to control loss
AnyBitmap bitmap = new AnyBitmap(@"FILE_PATH");
bitmap.ExportFile("losslogo.png", AnyBitmap.ImageFormat.Png, 100);

Generate AnyBitmap:

using IronSoftware.Drawing;
using System;
using System.IO;
 
AnyBitmap bitmap;
 
// Generate AnyBitmap using filepath
bitmap = AnyBitmap.FromFile(@"FILE_PATH");
bitmap.SaveAs("output.bmp");
 
// Generate AnyBitmap from bytes
byte[] bytes = File.ReadAllBytes(@"FILE_PATH");
bitmap = AnyBitmap.FromBytes(bytes);
bitmap.SaveAs("result.bmp");
 
// Generate AnyBitmap from memory stream
byte[] bytes2 = File.ReadAllBytes(@"FILE_PATH");
MemoryStream ms = new MemoryStream(bytes2);
bitmap = AnyBitmap.FromStream(ms);
bitmap.SaveAs("output.bmp");
 
// Generate AnyBitmap from Uri
Uri uri = new Uri("URI_PATH");
bitmap = await AnyBitmap.FromUriAsync(uri);
bitmap.SaveAs("uriImage.bmp");
 
// Generate AnyBitmap file from SVG file
bitmap = AnyBitmap.FromFile(@"FILE_PATH.svg");
bitmap.SaveAs("result.jpg");

以上示例代码可能与本人使用的版本有不同,可以更新至新版本,希望本文对你有帮助。

  • 17
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
font-awesome是一个非常流行的图标字体库,它包含了数千个矢量图标,可以用于网站和应用程序的设计和开发。fontawesome-webfont.woff?v=4.7.0是font-awesome字体库的一个文件,用于存储字体的相关信息。 字体文件使用.woff扩展名,表示它是一种Web开发中常用的字体格式,可以在网页上使用。而?v=4.7.0版本号,用于标识字体库的版本。通过在文件名中包含版本号,可以确保每次新后的字体文件都会被浏览器正确地缓存,从而提网页加载速度。 使用fontawesome-webfont.woff?v=4.7.0文件,开发人员可以在网页上轻松地引用和显示font-awesome图标。通过在CSS中指定对该字体文件的引用,可以使用简单的类名来插入和管理图标。而font-awesome库提供的CSS文件则将这些类名与相应的矢量图标进行了映射。 由于font-awesome提供了丰富的图标选择,开发人员可以快速引入和使用这些图标,而不必自己设计或找寻图标素材。这样可以减少设计和开发的时间,提工作效率。同时,font-awesome还支持对图标的样式进行定制,如改颜色、大小和旋转等,以及与其他CSS框架的集成。 总之,fontawesome-webfont.woff?v=4.7.0是font-awesome字体库的一个文件,它提供了丰富的矢量图标供开发人员使用,并通过CSS将图标与类名进行映射,简化了图标的引用和操作。它大大简化了网页和应用程序的设计和开发工作,使得添加图标变得加方便和效。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值