

在 PostgreSQL 中,解决图片二进制数据,由于bytea_output参数问题导致显示不正常的问...
source link: https://www.cnblogs.com/wuhuacong/p/18088886
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

在 PostgreSQL 中,bytea_output
参数控制在查询结果中 bytea
类型的显示格式。默认情况下,bytea_output
的值为 hex
,这意味着在查询结果中,bytea
类型的数据以十六进制格式显示。但是,如果你的应用程序期望以二进制格式获取图像数据,则将 bytea_output
设置为 escape
可能更适合。无论 bytea_output
参数设置为 hex
还是 escape
,你都可以通过 C# 访问 PostgreSQL 数据库,并且正常获取并显示图片。本篇随笔介绍这个问题的处理过程。
1、碰到的数据库图片在界面显示问题
在我们的Winform框架中,由于底层是支持多种数据库的设计,因此可以兼容MS SQLServer、Oracle、Mysql、PostgreSQL、SQLite等数据库的,但是一般我们用的是SQLServer、MySql居多,有客户切换到PostgreSQL数据库的时候,发现图片显示不正常,需要对图片进行十六进制转换才能正常显示。


默认的方式,这里方框在SQLServer等数据库上是正常显示图标的,打开编辑也是可以展示菜单的图表的,不过由于切换到PostgreSQL后,这里图标消失,检查数据库操作,默认的处理都是一致的,因此考虑是否为数据库参数配置问题。
2、解决问题
打开ChatGPT,或者百度、Google一下,细心都可以发现,在 PostgreSQL 中默认情况下,bytea_output
的值为 hex
,这意味着在查询结果中,bytea
类型的数据以十六进制格式显示。如果你的应用程序期望以二进制格式获取图像数据,则将 bytea_output
设置为 escape
可能更适合。
我们找到PostgreSQL的安装目录,找到 C:\Program Files\PostgreSQL\13\data\postgresql.conf里面的数据库配置文件,找到bytea_output
的值查看。

果然发现其默认值为hex,我们按要求修改为 escape,并去掉注释符号#,如下所示。

重启PostgreSQL,并测试系统数据库,显示和保存处理正常。

3、两种方式处理的差异
如果 bytea_output
参数设置为 hex
,你可以通过将读取到的十六进制字符串转换为字节数组,然后使用这些字节数组来创建图像对象。以下是一个示例代码,演示了如何在 C# 中获取并显示图片,即使 bytea_output
参数设置为 hex
:
class Program { static void Main() { string connString = "Host=myServerAddress;Port=myPort;Username=myUsername;Password=myPassword;Database=myDatabase"; using (var conn = new NpgsqlConnection(connString)) { conn.Open(); // 执行 SQL 查询以获取图像数据 string sql = "SELECT image_column FROM your_table WHERE id = @id"; int id = 1; // 替换为你要查询的图像的 ID using (var cmd = new NpgsqlCommand(sql, conn)) { cmd.Parameters.AddWithValue("@id", id); // 读取图像数据 using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess)) { if (reader.Read()) { // 获取十六进制字符串 string hexString = reader.GetString(0); // 将十六进制字符串转换为字节数组 byte[] imageData = StringToByteArray(hexString); // 创建图像对象 using (MemoryStream ms = new MemoryStream(imageData)) { Image image = Image.FromStream(ms); // 显示图像 ShowImage(image); } } } } } } static void ShowImage(Image image) { // 创建一个新的窗体 using (var form = new System.Windows.Forms.Form()) { // 创建 PictureBox 控件 var pictureBox = new System.Windows.Forms.PictureBox(); pictureBox.Dock = System.Windows.Forms.DockStyle.Fill; pictureBox.Image = image; // 将 PictureBox 添加到窗体中 form.Controls.Add(pictureBox); // 设置窗体大小并显示 form.Size = new System.Drawing.Size(image.Width, image.Height); form.ShowDialog(); } } static byte[] StringToByteArray(string hex) { int NumberChars = hex.Length / 2; byte[] bytes = new byte[NumberChars]; using (var sr = new StringReader(hex)) { for (int i = 0; i < NumberChars; i++) bytes[i] = Convert.ToByte(new string(new char[2] { (char)sr.Read(), (char)sr.Read() }), 16); } return bytes; } }
如果 bytea_output
参数设置为 escape
,则可以直接使用 Npgsql 从数据库中读取图像数据,并将其转换为字节数组,而不需要进行额外的处理。以下是示例代码:
using Npgsql; using System; using System.Data; using System.Drawing; using System.IO; class Program { static void Main() { string connString = "Host=myServerAddress;Port=myPort;Username=myUsername;Password=myPassword;Database=myDatabase"; using (var conn = new NpgsqlConnection(connString)) { conn.Open(); // 执行 SQL 查询以获取图像数据 string sql = "SELECT image_column FROM your_table WHERE id = @id"; int id = 1; // 替换为你要查询的图像的 ID using (var cmd = new NpgsqlCommand(sql, conn)) { cmd.Parameters.AddWithValue("@id", id); // 读取图像数据 using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess)) { if (reader.Read()) { // 获取图像数据字节数组 byte[] imageData = (byte[])reader["image_column"]; // 创建图像对象 using (MemoryStream ms = new MemoryStream(imageData)) { Image image = Image.FromStream(ms); // 显示图像 ShowImage(image); } } } } } } static void ShowImage(Image image) { // 创建一个新的窗体 using (var form = new System.Windows.Forms.Form()) { // 创建 PictureBox 控件 var pictureBox = new System.Windows.Forms.PictureBox(); pictureBox.Dock = System.Windows.Forms.DockStyle.Fill; pictureBox.Image = image; // 将 PictureBox 添加到窗体中 form.Controls.Add(pictureBox); // 设置窗体大小并显示 form.Size = new System.Drawing.Size(image.Width, image.Height); form.ShowDialog(); } } }
无论 bytea_output
参数设置为 hex
还是 escape
,你都可以通过 C# 访问 PostgreSQL 数据库,并且正常获取并显示图片。
Recommend
-
37
写在最前面(不看也不会少一个亿) 最开始的一个小需求前两天项目中有个小需求:前端下载后台小哥返回的二进制流文件。起...
-
36
故事背景 最近在一个技术交流群里遇到一个小兄弟请求问题,看着平淡无奇的问题,我建议查看mysql-server连接数是否正常,以及当前是否有活跃的慢连接在操作数据库。经过几次确认之后发现并没有什么异常。最后使用阿里开源的神器a...
-
8
解决Linux下RTL8111/8168/8411有线网卡工作不正常的问题 Linux下RTL8111/8168/8411这一系列的Realtek网卡可以说是通病了,在内核默认的r8169驱动下工作不正常,轻则不稳定,重则根本无法使用。今天...
-
4
数据表明,BSC Dapp上月由于闪电贷攻击损失了1.67亿美元 作者:Jamie Redman | 编译者:Maya | 来源:News.bitcoin.co...
-
7
请求一张图片,返回的数据类型是二进制,要将图片显示出来。图片 src 为二进制的处理这种场景下,首先想到图片的 src 为 base64 的情况,了解
-
11
V2EX › NAS 白群晖客户端数据同步不正常的问题 isler · 6 小时 47 分钟前 · 267 次点击
-
48
群晖的Video套件以及Emby套件、PLEX套件刮削器不正常显示的解决方法 2020年3月17日 7条评论 11.53k次阅读...
-
3
Jager · 3月18日 · 2015年windows · Windows,系统设置 983次已读最近一直很忙很忙,完全没时间打理博...
-
8
12 6月 2022 • Mac, 显示器 MacBook 外接显示器色彩不正...
-
20
Matrix 首页推荐 Matrix 是少数派的写作社区,我们主张分享真实的产品体验,有实用价值的经验与思考。我们会不定期挑选 Matrix 最优质的文章,展示来自用户的最真实的体验和观点。...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK