在 PostgreSQL 中,办理图片二进制数据,由于bytea_output参数问题导致表现 ...

打印 上一主题 下一主题

主题 857|帖子 857|积分 2571

在 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:
  1. class Program
  2. {
  3.     static void Main()
  4.     {
  5.         string connString = "Host=myServerAddress;Port=myPort;Username=myUsername;Password=myPassword;Database=myDatabase";
  6.         using (var conn = new NpgsqlConnection(connString))
  7.         {
  8.             conn.Open();
  9.             // 执行 SQL 查询以获取图像数据
  10.             string sql = "SELECT image_column FROM your_table WHERE id = @id";
  11.             int id = 1; // 替换为你要查询的图像的 ID
  12.             using (var cmd = new NpgsqlCommand(sql, conn))
  13.             {
  14.                 cmd.Parameters.AddWithValue("@id", id);
  15.                 // 读取图像数据
  16.                 using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess))
  17.                 {
  18.                     if (reader.Read())
  19.                     {
  20.                         // 获取十六进制字符串
  21.                         string hexString = reader.GetString(0);
  22.                         // 将十六进制字符串转换为字节数组
  23.                         byte[] imageData = StringToByteArray(hexString);
  24.                         // 创建图像对象
  25.                         using (MemoryStream ms = new MemoryStream(imageData))
  26.                         {
  27.                             Image image = Image.FromStream(ms);
  28.                             // 显示图像
  29.                             ShowImage(image);
  30.                         }
  31.                     }
  32.                 }
  33.             }
  34.         }
  35.     }
  36.     static void ShowImage(Image image)
  37.     {
  38.         // 创建一个新的窗体
  39.         using (var form = new System.Windows.Forms.Form())
  40.         {
  41.             // 创建 PictureBox 控件
  42.             var pictureBox = new System.Windows.Forms.PictureBox();
  43.             pictureBox.Dock = System.Windows.Forms.DockStyle.Fill;
  44.             pictureBox.Image = image;
  45.             // 将 PictureBox 添加到窗体中
  46.             form.Controls.Add(pictureBox);
  47.             // 设置窗体大小并显示
  48.             form.Size = new System.Drawing.Size(image.Width, image.Height);
  49.             form.ShowDialog();
  50.         }
  51.     }
  52.     static byte[] StringToByteArray(string hex)
  53.     {
  54.         int NumberChars = hex.Length / 2;
  55.         byte[] bytes = new byte[NumberChars];
  56.         using (var sr = new StringReader(hex))
  57.         {
  58.             for (int i = 0; i < NumberChars; i++)
  59.                 bytes[i] = Convert.ToByte(new string(new char[2] { (char)sr.Read(), (char)sr.Read() }), 16);
  60.         }
  61.         return bytes;
  62.     }
  63. }
复制代码
假如 bytea_output 参数设置为 escape,则可以直接使用 Npgsql 从数据库中读取图像数据,并将其转换为字节数组,而不需要进行额外的处置惩罚。以下是示例代码:
  1. using Npgsql;
  2. using System;
  3. using System.Data;
  4. using System.Drawing;
  5. using System.IO;
  6. class Program
  7. {
  8.     static void Main()
  9.     {
  10.         string connString = "Host=myServerAddress;Port=myPort;Username=myUsername;Password=myPassword;Database=myDatabase";
  11.         using (var conn = new NpgsqlConnection(connString))
  12.         {
  13.             conn.Open();
  14.             // 执行 SQL 查询以获取图像数据
  15.             string sql = "SELECT image_column FROM your_table WHERE id = @id";
  16.             int id = 1; // 替换为你要查询的图像的 ID
  17.             using (var cmd = new NpgsqlCommand(sql, conn))
  18.             {
  19.                 cmd.Parameters.AddWithValue("@id", id);
  20.                 // 读取图像数据
  21.                 using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess))
  22.                 {
  23.                     if (reader.Read())
  24.                     {
  25.                         // 获取图像数据字节数组
  26.                         byte[] imageData = (byte[])reader["image_column"];
  27.                         // 创建图像对象
  28.                         using (MemoryStream ms = new MemoryStream(imageData))
  29.                         {
  30.                             Image image = Image.FromStream(ms);
  31.                             // 显示图像
  32.                             ShowImage(image);
  33.                         }
  34.                     }
  35.                 }
  36.             }
  37.         }
  38.     }
  39.     static void ShowImage(Image image)
  40.     {
  41.         // 创建一个新的窗体
  42.         using (var form = new System.Windows.Forms.Form())
  43.         {
  44.             // 创建 PictureBox 控件
  45.             var pictureBox = new System.Windows.Forms.PictureBox();
  46.             pictureBox.Dock = System.Windows.Forms.DockStyle.Fill;
  47.             pictureBox.Image = image;
  48.             // 将 PictureBox 添加到窗体中
  49.             form.Controls.Add(pictureBox);
  50.             // 设置窗体大小并显示
  51.             form.Size = new System.Drawing.Size(image.Width, image.Height);
  52.             form.ShowDialog();
  53.         }
  54.     }
  55. }
复制代码
无论 bytea_output 参数设置为 hex 照旧 escape,你都可以通过 C# 访问 PostgreSQL 数据库,并且正常获取并表现图片。
 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

惊落一身雪

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表