.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

相关文章

input的accept属性让文件上传安全高效

《input的accept属性让文件上传安全高效》文章介绍了HTML的input文件上传`accept`属性在文件上传校验中的重要性和优势,通过使用`accept`属性,可以减少前端JavaScrip... 目录前言那个悄悄毁掉你上传体验的“常见写法”改变一切的 html 小特性:accept真正的魔法:让

Java使用Spire.Doc for Java实现Word自动化插入图片

《Java使用Spire.DocforJava实现Word自动化插入图片》在日常工作中,Word文档是不可或缺的工具,而图片作为信息传达的重要载体,其在文档中的插入与布局显得尤为关键,下面我们就来... 目录1. Spire.Doc for Java库介绍与安装2. 使用特定的环绕方式插入图片3. 在指定位

Python + Streamlit项目部署方案超详细教程(非Docker版)

《Python+Streamlit项目部署方案超详细教程(非Docker版)》Streamlit是一款强大的Python框架,专为机器学习及数据可视化打造,:本文主要介绍Python+St... 目录一、针对 Alibaba Cloud linux/Centos 系统的完整部署方案1. 服务器基础配置(阿里

SpringSecurity中的跨域问题处理方案

《SpringSecurity中的跨域问题处理方案》本文介绍了跨域资源共享(CORS)技术在JavaEE开发中的应用,详细讲解了CORS的工作原理,包括简单请求和非简单请求的处理方式,本文结合实例代码... 目录1.什么是CORS2.简单请求3.非简单请求4.Spring跨域解决方案4.1.@CrossOr

使用MyBatis TypeHandler实现数据加密与解密的具体方案

《使用MyBatisTypeHandler实现数据加密与解密的具体方案》在我们日常的开发工作中,经常会遇到一些敏感数据需要存储,比如用户的手机号、身份证号、银行卡号等,为了保障数据安全,我们通常会对... 目录1. 核心概念:什么是 TypeHandler?2. 实战场景3. 代码实现步骤步骤 1:定义 E

Python实现繁体转简体功能的三种方案

《Python实现繁体转简体功能的三种方案》在中文信息处理中,繁体字与简体字的转换是一个常见需求,无论是处理港澳台地区的文本数据,还是开发面向不同中文用户群体的应用,繁简转换都是不可或缺的功能,本文将... 目录前言为什么需要繁简转换?python实现方案方案一:使用opencc库方案二:使用zhconv库

Python多任务爬虫实现爬取图片和GDP数据

《Python多任务爬虫实现爬取图片和GDP数据》本文主要介绍了基于FastAPI开发Web站点的方法,包括搭建Web服务器、处理图片资源、实现多任务爬虫和数据可视化,同时,还简要介绍了Python爬... 目录一. 基于FastAPI之Web站点开发1. 基于FastAPI搭建Web服务器2. Web服务

java对接Pinata上传文件到IPFS全过程

《java对接Pinata上传文件到IPFS全过程》本文详细介绍了如何使用PinataAPI将文件上传到IPFS网络,首先登录Pinata官网并生成JWT令牌,然后在项目中导入OkHttp依赖并编写代... 目录1.登录2.生成令牌3.导入依赖4.编写代码5.调用接口调试China编程代码总结Pinata调用AP

Python包管理工具uv下载python版本慢问题解决办法

《Python包管理工具uv下载python版本慢问题解决办法》uv是一个非常快的Python包和项目管理器,用Rust编写,使用热缓存安装Trio的依赖项的速度对比,:本文主要介绍Python包... 目录发现问题对于 MACOS / linux 用户 (zsh/bash):对于 Windows 用户:总

利用Python将PDF文件转换为PNG图片的代码示例

《利用Python将PDF文件转换为PNG图片的代码示例》在日常工作和开发中,我们经常需要处理各种文档格式,PDF作为一种通用且跨平台的文档格式,被广泛应用于合同、报告、电子书等场景,然而,有时我们需... 目录引言为什么选择 python 进行 PDF 转 PNG?Spire.PDF for Python