最近有客户服务器使用RHEL8.5了。由于之前测试和编译的dotnetcore在Linux下绘图包libgdiplus都是在centos7.6编译的。把CentOS7.6编译的二进制程序之前试CentOS7.9使用没问题,然后RHEL8.5无法正常绘图。由于之前搞统信那些系统发现了包得在对应系统源码编译才行。所以就试着自己安装虚拟机编译。
安装虚拟机的过程很蛋疼,首先到网上下载一个800多兆的安装包,在安装系统时候需要输入机构名称和机构秘钥,看来企业版就是费劲额,我一个穷光蛋怎么可能为了编译程序去买个,为此就搁置了。
搁置几周后看项目搞虚拟机费劲,还得自己捣腾,为此问系统部要了个他们的系统下载地址,包有10个G,百度云盘限速100k下载了一天半只到3G,为此花了10块钱大洋提速,呜呜呜,真黑。
下载完成后正常虚拟机安装系统。安装完之后试着编译libgdiplus。执行yum安装编译环境时候提示没注册,不能运行yum,当时吓了一跳,不会还要买授权吧。。。
后面看是提示没注册、yum仓库不让用,就到网上配置成阿里云的yum。执行下面命令。
cd /etc/yum.repos.d/
rm *.repo
wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-vault-8.5.2111.repo
yum makecache
执行完之后可以用yum了,然后就编译:
yum -y install gcc automake autoconf libtool make
yum -y install gcc-c++
yum -y install zlib zlib-devel openssl openssl-devel pcre pcre-devel
yum install -y autoconf automake libtool
yum install -y freetype-devel fontconfig libXft-devel
yum install -y libjpeg-turbo-devel libpng-devel giflib-devel libtiff-devel libexif-devel
yum install -y glib2-devel cairo-devel
yum install -y pango-devel
yum install giflib
yum install libexif
yum install git
git clone https://github.com/mono/libgdiplus
cd libgdiplus
chmod +x autogen.sh
chmod +x configure
./autogen.sh --with-pango
make
make install
cd /usr/lib64/
ln -s /usr/local/lib/libgdiplus.so gdiplus.dll
编译完成后把src下生成的libs二进制拷贝出来和自己写的install.sh脚本打包,就得到了安装的二进制包。
传给项目测试发现还行不能画出图。然后就把自己写的最简单的画图测试控制台到虚拟机测试。
测试代码如下:
using System;
using System.Drawing;
namespace lisdrawtest
{
/// <summary>
/// 供检验测试绘图环境
/// </summary>
class Program
{
static void Main(string[] args)
{
Console.WriteLine("此程序为imedicallis提供用于测试linux下dotnetcore绘图环境");
Console.WriteLine("创建位图");
//创建空位图
Image img = new Bitmap(300, 140);
Console.WriteLine("创建画笔");
//获得画图句柄
Graphics g = Graphics.FromImage(img);
Console.WriteLine("填充白色");
g.Clear(Color.White);
Console.WriteLine("创建Pen");
Pen pen = new Pen(Color.Black);
pen.Width = 1;
//画横纵坐标线
Console.WriteLine("画一条竖线");
g.DrawLine(pen, 50, 100, 300, 100);
Console.WriteLine("画一条横线");
g.DrawLine(pen, 50, 100, 50, 0);
Console.WriteLine("创建字体");
Font myFont = new Font("宋体", 12, FontStyle.Regular);
Console.WriteLine("创建画刷");
Brush brush = new SolidBrush(Color.Black);
Console.WriteLine("绘制字符串");
g.DrawString("ZhangLainZhu test", myFont, brush, 10, 10);
Console.WriteLine("保存文件到:"+ System.IO.Path.Combine(AppContext.BaseDirectory, "lisdrawtest.bmp"));
if (System.IO.File.Exists(System.IO.Path.Combine(AppContext.BaseDirectory,"lisdrawtest.bmp")))
{
System.IO.File.Delete(System.IO.Path.Combine(AppContext.BaseDirectory, "lisdrawtest.bmp"));
}
img.Save(System.IO.Path.Combine(AppContext.BaseDirectory, "lisdrawtest.bmp"));
Console.WriteLine("测试完成,如果成功生成图片那么环境可用");
}
}
}
发现能成功绘图。。。我了个去,还能见鬼不成
然后又到项目服务器捣腾了几个小时,一直报“No codec available for format:b96b3cae-0728-11d3-9d7b-0000f81ef32e”,然后就百度、必应各种查资料,基本没资料,只知道b96b3cae-0728-11d3-9d7b-0000f81ef32e是图片的Format格式。然后六点没搞定就先回去了。
查资料过程很曲折:
把libgdiplus的源码也翻了翻
回去立马开机准备测试,首先整理思路:
1.项目服务器安装包后报No codec available for format:b96b3cae-0728-11d3-9d7b-0000f81ef32e
2.项目服务器卸载包后报没安装gdiplus。这就说明包安装有效。
3.项目服务器用简单绘图测试程序能画好图,检验在线预览画图报错,而且报format错。那么说明绘图库不存在问题,是不是预览的图形处理用到图片format了导致的。
然后就把图片Save加上指定图片Format测试,在本地虚拟机也没问题。
bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
看来只能在项目服务器测试了。和项目要了个远程,让测试登录个QQ,准备频繁编译dll测试。
先锁定大概位置
发现日志能走到44,说明得到img了,绘图是成功的,也和报format错误,而简单测试示例能成功印证。为了证实猜想,在img后面调用img.Save保存图片到/zlz.bmp查看。发现确实是检验报告图片。
然后测试点就到转Base64串了。在这里输出3个日志,然后发现是转换Base64异常了。这里原代码是指定图片格式是System.Drawing.Imaging.ImageFormat.Jpeg。
测试到这里那就应该是Jpeg的事,因为我画的是bmp。把代码改为Bmp编译测试后正常。这个问题应该是有的环境才会出,因为之前CentOS7.6是没毛病的。总算是跟到问题了。旷日持久的RHEL8.5编译libgdiplus以花10块钱提速和半天加班结束。开心,又成长了一丢丢
很多时候要有耐心,解决不了的时候可以从多方面论证来缩小范围,再整理整理心情可能接解决了。