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

2023-12-27 06:52

本文主要是介绍.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 = FileHelper.ByteToImg(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");

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

这篇关于.Net7.0 或更高版本 System.Drawing.Common 上传图片跨平台方案的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/542233

相关文章

Python利用PIL进行图片压缩

《Python利用PIL进行图片压缩》有时在发送一些文件如PPT、Word时,由于文件中的图片太大,导致文件也太大,无法发送,所以本文为大家介绍了Python中图片压缩的方法,需要的可以参考下... 有时在发送一些文件如PPT、Word时,由于文件中的图片太大,导致文件也太大,无法发送,所有可以对文件中的图

java获取图片的大小、宽度、高度方式

《java获取图片的大小、宽度、高度方式》文章介绍了如何将File对象转换为MultipartFile对象的过程,并分享了个人经验,希望能为读者提供参考... 目China编程录Java获取图片的大小、宽度、高度File对象(该对象里面是图片)MultipartFile对象(该对象里面是图片)总结java获取图片

Java实战之自助进行多张图片合成拼接

《Java实战之自助进行多张图片合成拼接》在当今数字化时代,图像处理技术在各个领域都发挥着至关重要的作用,本文为大家详细介绍了如何使用Java实现多张图片合成拼接,需要的可以了解下... 目录前言一、图片合成需求描述二、图片合成设计与实现1、编程语言2、基础数据准备3、图片合成流程4、图片合成实现三、总结前

java中不同版本JSONObject区别小结

《java中不同版本JSONObject区别小结》本文主要介绍了java中不同版本JSONObject区别小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们... 目录1. FastjsON2. Jackson3. Gson4. org.json6. 总结在Jav

使用Python实现图片和base64转换工具

《使用Python实现图片和base64转换工具》这篇文章主要为大家详细介绍了如何使用Python中的base64模块编写一个工具,可以实现图片和Base64编码之间的转换,感兴趣的小伙伴可以了解下... 简介使用python的base64模块来实现图片和Base64编码之间的转换。可以将图片转换为Bas

css实现图片旋转功能

《css实现图片旋转功能》:本文主要介绍了四种CSS变换效果:图片旋转90度、水平翻转、垂直翻转,并附带了相应的代码示例,详细内容请阅读本文,希望能对你有所帮助... 一 css实现图片旋转90度.icon{ -moz-transform:rotate(-90deg); -webkit-transfo

Oracle数据库如何切换登录用户(system和sys)

《Oracle数据库如何切换登录用户(system和sys)》文章介绍了如何使用SQL*Plus工具登录Oracle数据库的system用户,包括打开登录入口、输入用户名和口令、以及切换到sys用户的... 目录打开登录入口登录system用户总结打开登录入口win+R打开运行对话框,输php入:sqlp

Redis 多规则限流和防重复提交方案实现小结

《Redis多规则限流和防重复提交方案实现小结》本文主要介绍了Redis多规则限流和防重复提交方案实现小结,包括使用String结构和Zset结构来记录用户IP的访问次数,具有一定的参考价值,感兴趣... 目录一:使用 String 结构记录固定时间段内某用户 IP 访问某接口的次数二:使用 Zset 进行

解读Redis秒杀优化方案(阻塞队列+基于Stream流的消息队列)

《解读Redis秒杀优化方案(阻塞队列+基于Stream流的消息队列)》该文章介绍了使用Redis的阻塞队列和Stream流的消息队列来优化秒杀系统的方案,通过将秒杀流程拆分为两条流水线,使用Redi... 目录Redis秒杀优化方案(阻塞队列+Stream流的消息队列)什么是消息队列?消费者组的工作方式每

MySQL分表自动化创建的实现方案

《MySQL分表自动化创建的实现方案》在数据库应用场景中,随着数据量的不断增长,单表存储数据可能会面临性能瓶颈,例如查询、插入、更新等操作的效率会逐渐降低,分表是一种有效的优化策略,它将数据分散存储在... 目录一、项目目的二、实现过程(一)mysql 事件调度器结合存储过程方式1. 开启事件调度器2. 创