`

.NET Core 图片操作在 Linux/Docker 下的坑

 
阅读更多
上篇:net core Linux ( Centos 7 ) 下 验证码图片显示不出来
原因是:Unable to load shared library 'gdiplus'

但是即使安装上了这个dll,依然不能显示图片,为啥呢?
.NET Core 2.2 本身依然不包括和图片有关的 Image、Bitmap 等类型。
所以当处理图片的类中使用了ZKWeb.System.Drawing,就会提示:

Connection id "0HLPLMNTFQ8H5", Request id "0HLPLMNTFQ8H5:00000001": An unhandled exception was thrown by the application.
System.ArgumentException: No codec available for format:b96b3cae-0728-11d3-9d7b-0000f81ef32e
at System.DrawingCore.Image.Save(Stream stream, ImageFormat format)
为此百度好久,终于发现链接的文章。

此时如果你用了我的类库则只需切换到System.Drawing.Common库中并安装

sudo curl https://raw.githubusercontent.com/stulzq/awesome-dotnetcore-image/master/install/centos7.sh|sh


或者切换为ImageSharp,就可以避免此问题。


附带图片验证码helper类   使用System.Drawing.Common库
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;

public sealed class VerifyCodeHelper
    {
        #region 单例模式
        //创建私有化静态obj锁  
        private static readonly object _ObjLock = new object();
        //创建私有静态字段,接收类的实例化对象  
        private static VerifyCodeHelper _VerifyCodeHelper = null;
        //构造函数私有化  
        private VerifyCodeHelper() { }
        //创建单利对象资源并返回  
        public static VerifyCodeHelper GetSingleObj()
        {
            if (_VerifyCodeHelper == null)
            {
                lock (_ObjLock)
                {
                    if (_VerifyCodeHelper == null)
                        _VerifyCodeHelper = new VerifyCodeHelper();
                }
            }
            return _VerifyCodeHelper;
        }
        #endregion

        public enum VerifyCodeType { NumberVerifyCode, AbcVerifyCode, MixVerifyCode };

        #region 数字验证码
        /// <summary>
        /// 1.数字验证码
        /// </summary>
        /// <param name="length"></param>
        /// <returns></returns>
        private string CreateNumberVerifyCode(int length)
        {
            int[] randMembers = new int[length];
            int[] validateNums = new int[length];
            string validateNumberStr = "";
            //生成起始序列值  
            int seekSeek = unchecked((int)DateTime.Now.Ticks);
            Random seekRand = new Random(seekSeek);
            int beginSeek = seekRand.Next(0, Int32.MaxValue - length * 10000);
            int[] seeks = new int[length];
            for (int i = 0; i < length; i++)
            {
                beginSeek += 10000;
                seeks[i] = beginSeek;
            }
            //生成随机数字  
            for (int i = 0; i < length; i++)
            {
                Random rand = new Random(seeks[i]);
                int pownum = 1 * (int)Math.Pow(10, length);
                randMembers[i] = rand.Next(pownum, Int32.MaxValue);
            }
            //抽取随机数字  
            for (int i = 0; i < length; i++)
            {
                string numStr = randMembers[i].ToString();
                int numLength = numStr.Length;
                Random rand = new Random();
                int numPosition = rand.Next(0, numLength - 1);
                validateNums[i] = Int32.Parse(numStr.Substring(numPosition, 1));
            }
            //生成验证码  
            for (int i = 0; i < length; i++)
            {
                validateNumberStr += validateNums[i].ToString();
            }
            return validateNumberStr;
        }
        #endregion

        #region 字母验证码
        /// <summary>
        /// 2.字母验证码
        /// </summary>
        /// <param name="length">字符长度</param>
        /// <returns>验证码字符</returns>
        private string CreateAbcVerifyCode(int length)
        {
            char[] verification = new char[length];
            char[] dictionary = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
                'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'm', 'n', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'
            };
            Random random = new Random();
            for (int i = 0; i < length; i++)
            {
                verification[i] = dictionary[random.Next(dictionary.Length - 1)];
            }
            return new string(verification);
        }
        #endregion

        #region 混合验证码
        /// <summary>
        /// 3.混合验证码
        /// </summary>
        /// <param name="length">字符长度</param>
        /// <returns>验证码字符</returns>
        private string CreateMixVerifyCode(int length)
        {
            char[] verification = new char[length];
            char[] dictionary = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
                '2', '3', '4', '5', '6', '7', '8', '9',
                'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n','p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'
            };
            Random random = new Random();
            for (int i = 0; i < length; i++)
            {
                verification[i] = dictionary[random.Next(dictionary.Length - 1)];
            }
            return new string(verification);
        }
        #endregion

        #region 产生验证码(随机产生4-6位)
        /// <summary>
        /// 产生验证码(随机产生4-6位)
        /// </summary>
        /// <param name="type">验证码类型:数字,字符,符合</param>
        /// <returns></returns>
        public string CreateVerifyCode(VerifyCodeType type)
        {
            string verifyCode = string.Empty;
            Random random = new Random();
            int length = random.Next(4, 6);
            switch (type)
            {
                case VerifyCodeType.NumberVerifyCode:
                    verifyCode = GetSingleObj().CreateNumberVerifyCode(length);
                    break;
                case VerifyCodeType.AbcVerifyCode:
                    verifyCode = GetSingleObj().CreateAbcVerifyCode(length);
                    break;
                case VerifyCodeType.MixVerifyCode:
                    verifyCode = GetSingleObj().CreateMixVerifyCode(length);
                    break;
            }
            return verifyCode;
        }
        #endregion

        #region 验证码图片
        /// <summary>
        /// 验证码图片 => Bitmap
        /// </summary>
        /// <param name="verifyCode">验证码</param>
        /// <param name="width">宽</param>
        /// <param name="height">高</param>
        /// <returns>Bitmap</returns>
        public Bitmap CreateBitmapByImgVerifyCode(string verifyCode, int width, int height)
        {
            Font font = new Font("Arial", 14, (FontStyle.Bold | FontStyle.Italic));
            Brush brush;
            Bitmap bitmap = new Bitmap(width, height);
            Graphics g = Graphics.FromImage(bitmap);
            SizeF totalSizeF = g.MeasureString(verifyCode, font);
            SizeF curCharSizeF;
            PointF startPointF = new PointF(0, (height - totalSizeF.Height) / 2);
            Random random = new Random(); //随机数产生器
            g.Clear(Color.White); //清空图片背景色  
            for (int i = 0; i < verifyCode.Length; i++)
            {
                brush = new LinearGradientBrush(new Point(0, 0), new Point(1, 1), Color.FromArgb(random.Next(255), random.Next(255), random.Next(255)), Color.FromArgb(random.Next(255), random.Next(255), random.Next(255)));
                g.DrawString(verifyCode[i].ToString(), font, brush, startPointF);
                curCharSizeF = g.MeasureString(verifyCode[i].ToString(), font);
                startPointF.X += curCharSizeF.Width;
            }

            //画图片的干扰线  
            for (int i = 0; i < 10; i++)
            {
                int x1 = random.Next(bitmap.Width);
                int x2 = random.Next(bitmap.Width);
                int y1 = random.Next(bitmap.Height);
                int y2 = random.Next(bitmap.Height);
                g.DrawLine(new Pen(Color.Silver), x1, y1, x2, y2);
            }

            //画图片的前景干扰点  
            for (int i = 0; i < 100; i++)
            {
                int x = random.Next(bitmap.Width);
                int y = random.Next(bitmap.Height);
                bitmap.SetPixel(x, y, Color.FromArgb(random.Next()));
            }

            g.DrawRectangle(new Pen(Color.Silver), 0, 0, bitmap.Width - 1, bitmap.Height - 1); //画图片的边框线  
            g.Dispose();
            return bitmap;
        }

        /// <summary>
        /// 验证码图片 => byte[]
        /// </summary>
        /// <param name="verifyCode">验证码</param>
        /// <param name="width">宽</param>
        /// <param name="height">高</param>
        /// <returns>byte[]</returns>
        public byte[] CreateByteByImgVerifyCode(string verifyCode, int width, int height)
        {
            Font font = new Font("Arial", 14, (FontStyle.Bold | FontStyle.Italic));
            Brush brush;
            Bitmap bitmap = new Bitmap(width, height);
            Graphics g = Graphics.FromImage(bitmap);
            SizeF totalSizeF = g.MeasureString(verifyCode, font);
            SizeF curCharSizeF;
            PointF startPointF = new PointF(0, (height - totalSizeF.Height) / 2);
            Random random = new Random(); //随机数产生器
            g.Clear(Color.White); //清空图片背景色  
            for (int i = 0; i < verifyCode.Length; i++)
            {
                brush = new LinearGradientBrush(new Point(0, 0), new Point(1, 1), Color.FromArgb(random.Next(255), random.Next(255), random.Next(255)), Color.FromArgb(random.Next(255), random.Next(255), random.Next(255)));
                g.DrawString(verifyCode[i].ToString(), font, brush, startPointF);
                curCharSizeF = g.MeasureString(verifyCode[i].ToString(), font);
                startPointF.X += curCharSizeF.Width;
            }

            //画图片的干扰线  
            for (int i = 0; i < 10; i++)
            {
                int x1 = random.Next(bitmap.Width);
                int x2 = random.Next(bitmap.Width);
                int y1 = random.Next(bitmap.Height);
                int y2 = random.Next(bitmap.Height);
                g.DrawLine(new Pen(Color.Silver), x1, y1, x2, y2);
            }

            //画图片的前景干扰点  
            for (int i = 0; i < 100; i++)
            {
                int x = random.Next(bitmap.Width);
                int y = random.Next(bitmap.Height);
                bitmap.SetPixel(x, y, Color.FromArgb(random.Next()));
            }

            g.DrawRectangle(new Pen(Color.Silver), 0, 0, bitmap.Width - 1, bitmap.Height - 1); //画图片的边框线  
            g.Dispose();

            //保存图片数据  
            MemoryStream stream = new MemoryStream();
            bitmap.Save(stream, ImageFormat.Jpeg);
            //输出图片流  
            return stream.ToArray();

        }
        #endregion
    }


附带前端调用
string code = VerifyCodeHelper.GetSingleObj().CreateVerifyCode(VerifyCodeHelper.VerifyCodeType.NumberVerifyCode);
byte[] codeImage = VerifyCodeHelper.GetSingleObj().CreateByteByImgVerifyCode(code, 100, 40);


原文:https://www.cnblogs.com/stulzq/p/10172550.html
分享到:
评论

相关推荐

    Linux服务器下利用Docker部署.net Core项目的全过程

    主要给大家介绍了关于在Linux服务器下利用Docker部署.net Core项目的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用.net Core具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧

    centos下使用docker部署.net core项目.docx

    CentOS 下使用 Docker 部署 .NET Core 项目 本文将详细介绍如何在 CentOS 系统中使用 Docker 部署 .NET Core 项目,涵盖 Docker 的安装、 .NET Core 程序的安装、Nginx 的配置等重要知识点。 一、基本知识储备 在...

    ASP.NET Core 3.1中文教程.pdf

    * 跨平台:ASP.NET Core 支持多种操作系统,包括 Windows、Linux 和 macOS 等。 * 高性能:ASP.NET Core 使用了最新的 .NET Core 运行库,具有高性能和高效率的特点。 * 轻量级:ASP.NET Core 的架构轻量级,易于...

    腾讯支付基于.Net Core重新构建基础框架以实现更灵活可拓展

    腾讯支付基于.Net Core重新构建基础框架以实现更灵活可拓展 ...传统.NET确实不适合互联网,就看新一代.NET Core on Linux/docker的表演了, 腾讯支付应用微软.Net Core重新构建基础框架以实现更灵活可拓展

    Linux/Docker 中使用 System.Drawing.Common 踩坑记录分享

    在项目迁移到 .net core 上面后,我们可以使用 System.Drawing.Common 组件来操作 Image,Bitmap 类型,实现生成验证码、二维码,图片操作等功能。System.Drawing.Common 组件它是依赖于 GDI+ 的,然后在 Linux 上并...

    dotnet-docker:.NET Core和.NET Core工具的Docker映像

    作为.NET 5.0版本的一部分,所有.NET Docker映像(包括.NET Core 2.1和3.1)都已过渡到下面描述的一组新的Docker存储库。为了向后兼容,将继续对旧存储库位置中的受支持标签进行更新。请更新对这些新名称的所有存储...

    Pro C# 7 With .NET and .NET Core 原版pdf

    《Pro C# 7 With .NET and .NET Core》是一本深入探讨C# 7编程语言及其在.NET和.NET Core框架下应用的专业书籍。这本书详细介绍了C# 7的新特性和.NET Core平台的关键概念,旨在帮助开发者提升技能,构建高效且可移植...

    docker一键安装hadoop集群

    【Dockerfile详解】 Dockerfile 是一个文本文件,包含了构建 Docker 映像的指令序列。...通过 Docker 安装 Hadoop 集群,可以在不改变主机系统的情况下快速部署和测试,方便开发者和运维人员进行开发、测试和演示。

    第七版.net Core MVC2.pdf

    .NET Core是微软推出的开源、跨平台的开发框架,它允许开发者在Windows、Linux和macOS等操作系统上构建和运行应用程序。相比传统的.NET Framework,.NET Core具有更轻量级、高性能和模块化的特性。而MVC(Model-View...

    C# .net core开发的分布式游戏服务端

    .NET Core支持Windows、Linux和macOS等操作系统,具备高度的可移植性,为分布式系统的部署提供了极大的灵活性。 二、分布式游戏服务端的设计 1. **微服务架构**:分布式游戏服务端通常采用微服务架构,将复杂的...

    坑人,彻底明白:Linux服务器:k8s(Kubernetes)安装网络插件calico无法下载,无法启动的问题解决:

    解决地址如下: https://blog.csdn.net/qq120631157/article/details/128672524 无积分的同学,请联系我。 1. 首先确定 k8s的版本,我的为1.20.9 ```sh kubectl get nodes ...6. 所以需要去下载 离线的docker文件。

    asp.net core 2.1教程(全中文版).pdf

    能够在 IIS 、 Nginx 、 Apache 、 Docker 上进行托管或在自己的进程中进行自托管。 定目标到 .NET Core 时,可以使用并行应用版本控制。 简化新式 Web 开发的工具。 能够在 Windows 、 macOS 和 Linux 进行生成...

    .net core 3.1中文教程.pdf

    跨平台:可在 Windows、macOS 和 Linux 操作系统上运行。 开放源代码: .NET Core 框架是开放源代码,使用 MIT 和 Apache 2 许可证。 .NET Core 是一个 .NETFoundation 项目。 现代:它实现了异步编程、使用结构的无...

    Real-Time Web Development -.NET Core, SignalR, Docker

    .NET Core具备模块化、高性能和跨平台的特点,它支持多种操作系统,包括Windows、Linux和macOS。.NET Core以其轻量级、易于集成到持续集成/持续部署(CI/CD)流程中而受到开发者的喜爱。其灵活性和模块化特性使得...

    asp.net core部署在linux(centos)环境搭建手册.docx

    本篇将详细讲解如何在Linux(CentOS 8.2 64bit)环境下部署ASP.NET Core应用,并结合MySQL作为数据库。 **1. ASP.NET Core应用版本准备** 确保你的应用基于.NET Core 5.0进行开发。此版本提供了许多性能优化和新特性...

    C# 7 and .NET Core: Modern Cross-Platform Development - Second Edition

    C# 7 and .NET Core: Modern Cross-Platform Development - Second Edition by Mark J. Price English | 24 Mar. 2017 | ASIN: B01N8UG78Q | 594 Pages | AZW3 | 23.26 MB Modern Cross-Platform Development ...

    .net core2.1中文高清完整版

    1. **安装与配置**:如何在不同操作系统上安装.NET Core SDK,以及设置开发环境,包括Visual Studio、Visual Studio Code或命令行工具dotnet CLI。 2. **项目结构与创建**:讲解.NET Core项目的基本结构,以及如何...

Global site tag (gtag.js) - Google Analytics