.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");

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/578447.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Nature | Baker团队用AI设计出史上最高互作强度的蛋白质

蛋白质是生命的基础&#xff0c;是生命功能的主要执行者&#xff0c;其结构与功能由氨基酸序列所决定。蛋白质设计是指对新蛋白质分子进行人为的合理设计&#xff0c;旨在设计新的活性&#xff0c;行为或目的&#xff0c;并增进对蛋白质功能的基本了解。可以从头开始设计蛋白质…

有没有好用的视频提取文案工具推荐?

在如今这个快节奏的时代中&#xff0c;视频已成为人们记录和分享生活的重要媒介。当然有很多优秀的人&#xff0c;它们创作的视频文案或是演讲的台词、字幕等都非常精彩&#xff1b;难免有时候我们也会借鉴他人的优质内容供自己参考、修改等。那么怎么把这些内容自动提取出来呢…

PyQt5实现学生管理系统第三天

上一节,我们实现了学生管理模块的相关功能。这一节我们实现课程管理模块的功能。 一:课程查询 点击左侧导航课程查询,我们同样使用self.right_widget.setCurrentIndex(2),这里跳转的是第三个QWidget,课程查询页面包含了搜索框,查询按钮,新增,编辑和删除按钮。 二:搜…

高手写的CAN总线入门总结

关注菲益科公众号—>对话窗口发送 “CANoe ”或“INCA”&#xff0c;即可获得canoe入门到精通电子书和INCA软件安装包&#xff08;不带授权码&#xff09;下载地址。 1. 简介 CAN总线由德国BOSCH公司开发&#xff0c;最高速率可达到1Mbps。CAN的容错能力特别强&#xff0c;…

亚马逊鲲鹏AI智能养号系统助您快速养成买家号

在如今竞争激烈的电商市场&#xff0c;拥有一个优质的亚马逊买家号显得尤为重要。然而&#xff0c;要想提高账号的质量&#xff0c;不仅需要精心呵护&#xff0c;还需要借助先进的技术手段。亚马逊鲲鹏系统引入了AI智能养号功能&#xff0c;为买家们提供了更便捷、更智能的账号…

idea自动注释

前言 保存一下自己的自动注释代码 idea自动注释 前言1 创建类时&#xff0c;自动生成注释2 在方法上使用快捷键生成注释3 使用方法4 效果图 1 创建类时&#xff0c;自动生成注释 如下&#xff1a; #if (${PACKAGE_NAME} && ${PACKAGE_NAME} ! "")package …

隐私计算:数据匿名化的优点和缺点

PrimiHub一款由密码学专家团队打造的开源隐私计算平台&#xff0c;专注于分享数据安全、密码学、联邦学习、同态加密等隐私计算领域的技术和内容。 数据分析是如今商业社会业务运营的核心工具&#xff0c;节省成本的同时还可以深入了解用户偏好&#xff0c;通过定制产品来收获最…

基于SVM的鸟鸣识别,语谱分析

目录 支持向量机SVM的详细原理 SVM的定义 SVM理论 Libsvm工具箱详解 简介 参数说明 易错及常见问题 完整代码和数据下载链接: 基于SVM的鸟鸣识别,语谱分析(代码完整,数据齐全)资源-CSDN文库 https://download.csdn.net/download/abc991835105/88610830 SVM应用实例, 基于S…

基于机器学习算法的数据分析师薪资预测模型优化研究(文末送书)

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

阿里云“块存储”是系统盘和数据盘的意思

阿里云“块存储”是什么意思&#xff1f;块存储是指阿里云服务器的系统盘或数据盘。块存储EBS&#xff08;Elastic Block Storage&#xff09;是为云服务器ECS提供的低时延、持久性、高可靠的块级随机存储。块存储支持在可用区内自动复制您的数据&#xff0c;防止意外硬件故障导…

W5100S-EVB-Pico评估版介绍

文章目录 1 简介2 硬件资源2.1 硬件规格2.2 引脚定义2.3 工作条件 3 参考资料3.1 Datasheet3.2 原理图3.3 尺寸图&#xff08;单位&#xff1a;mm&#xff09;3.4 参考例程 4 硬件协议栈优势 1 简介 W5100S-EVB-Pico是一款基于树莓派RP2040和全硬件TCP/IP协议栈以太网芯片W5100…

Java基于TCP网络编程的群聊功能

服务端 import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; import java.util.List;public class Server2 {public static List<Socket> onlineList new ArrayList<>();public static void main(String[] args) throws Except…

运维工程师的出路

在当今社会&#xff0c;随着科技的不断进步和数字化转型的加速&#xff0c;运维工程师这一职业面临着前所未有的挑战和机遇。许多运维工程师开始思考自己的职业出路&#xff0c;他们想知道如何在竞争激烈的市场中脱颖而出&#xff0c;寻找更好的职业发展机会。本文将探讨运维工…

java流浪动物保护系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 java Web 流浪动物保护系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysql…

工具系列:TensorFlow决策森林_(6)模型预测

文章目录 重要提示设置model.predict(...) 和 pd_dataframe_to_tf_dataset 函数model.predict(...) 和手动的TF数据集model.predict(...)和model.predict_on_batch()在字典上的使用使用YDF格式进行推理 TensorFlow决策森林&#xff08; TF-DF&#xff09;的 预测。 在本文中&…

kubernetes(k8s) Yaml 文件详解

YAML格式&#xff1a;用于配置和管理&#xff0c;YAML是一种简洁的非标记性语言&#xff0c;内容格式人性化&#xff0c;较易读。 1、查看API 资源版本标签 kubectl api-versions 2、编写资源配置清单 kubectl create -f nginx-test.yaml --validatefalse 2.3 查看创建的po…

氢燃料电池商用车系统架构开发与集成技术

一、国家及不同地区对氢能发展支持政策 近三年国家对氢能及燃料电池产业的支持政策 近年来22个省市的发展规划中提到了大力支持氢能源产业发展 二、燃料电池客车架构分解及国内外已有车型 未来燃料电池客车发展方向 未来燃料电池客车新增加的燃料电池堆产业链及供应商 国内外差…

Java毕业设计——vue+springboot音乐网站音乐播放器,歌曲管理系统

1&#xff0c;项目背景 随着计算机技术的发展&#xff0c;网络技术对我们生活和工作显得越来越重要&#xff0c;特别是现在信息高度发达的今天&#xff0c;人们对最新信息的需求和发布迫切的需要及时性。为了满足不同人们对网络需求&#xff0c;各种特色&#xff0c;各种主题的…

spring初始化bean之后执行某个方法

这个问题可以分两种解释&#xff1a; 1. 某个bean初始化执行? 2. 所有bean初始化后执行? 第一个问题可以在spring bean的生命周期中找到答案&#xff1a; bean定义-实例化-初始化-销毁。注意&#xff1a; 这里的bean定义是指所有的bean定义完成&#xff0c;然后才继续执…

1.Linux是什么与如何学习

第 1 章 Linux 是什么与如何学习 历史部分略过。 1.2.5 Linux的内核版本 Linux的内核版本编号有点类似如下的样子&#xff1a; 3.10.0-123.el7.x86_64 主版本.次版本.发布版本-修改版本虽然编号就是如上的方式来编的&#xff0c;不过依据 Linux 内核的发展期程&#xff0c;…