在 PostgreSQL中解决图片二进制数据由于bytea_output参数问题导致显示不正常的问题

 更新时间:2024年03月25日 09:22:58   作者:伍华聪  
无论 bytea_output 参数设置为 hex 还是 escape,你都可以通过 C# 访问 PostgreSQL 数据库,并且正常获取并显示图片,本篇随笔介绍这个问题的处理过程,感兴趣的朋友跟随小编一起看看吧

在 PostgreSQL 中,bytea_output 参数控制在查询结果中 bytea 类型的显示格式。默认情况下,bytea_output 的值为 hex,这意味着在查询结果中,bytea 类型的数据以十六进制格式显示。但是,如果你的应用程序期望以二进制格式获取图像数据,则将 bytea_output 设置为 escape 可能更适合。无论 bytea_output 参数设置为 hex 还是 escape,你都可以通过 C# 访问 PostgreSQL 数据库,并且正常获取并显示图片。本篇随笔介绍这个问题的处理过程。

在 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 数据库,并且正常获取并显示图片。

到此这篇关于在 PostgreSQL 中解决图片二进制数据由于bytea_output参数问题导致显示不正常的问题的文章就介绍到这了,更多相关PostgreSQL内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • PostgreSQL的 archive_mode 参数配置示例详解

    PostgreSQL的 archive_mode 参数配置示例详解

    本文详细介绍了PostgreSQL的archive_mode参数,包括其三个选项(off、on、always)的对比和使用场景,以及在不同模式下的配置和行为特点,感兴趣的朋友跟随小编一起看看吧
    2025-11-11
  • PostgreSQL防止WAL文件撑爆磁盘的策略指南

    PostgreSQL防止WAL文件撑爆磁盘的策略指南

    在 PostgreSQL 中,Write-Ahead Logging(WAL)是保障数据持久性与崩溃恢复的核心机制,若未合理配置和管理,WAL 文件可能持续累积,最终导致磁盘空间耗尽,本文将系统性地详解 如何防止 WAL 文件撑爆磁盘,涵盖原理、风险识别、核心配置、监控手段及最佳实践
    2026-02-02
  • postgresql SQL语句变量的使用说明

    postgresql SQL语句变量的使用说明

    这篇文章主要介绍了postgresql SQL语句变量的使用说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • 解决postgreSql远程连接数据库超时的问题

    解决postgreSql远程连接数据库超时的问题

    这篇文章主要介绍了解决postgreSql远程连接数据库超时的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • PostgreSQL判断字符串是否包含目标字符串的多种方法

    PostgreSQL判断字符串是否包含目标字符串的多种方法

    这篇文章主要介绍了PostgreSQL判断字符串是否包含目标字符串的多种方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-02-02
  • PostgreSQL有效地处理数据的加密和解密的常见方法

    PostgreSQL有效地处理数据的加密和解密的常见方法

    在信息化建设和等保建设中,都要求实现对用户数据的隐私保护,也就是我们常说的脱敏,那么在 PostgreSQL 数据库中有没有这样的方法或者策略可以实现呢,本文小编将给大家介绍一下PostgreSQL有效地处理数据的加密和解密的常见方法,需要的朋友可以参考下
    2025-03-03
  • PostgreSQL中offset...limit分页优化的一些常见手段

    PostgreSQL中offset...limit分页优化的一些常见手段

    我们在使用数据库进行分页查询时,随着offset过滤的数据越来越多,查询也会越来越慢,下面这篇文章主要给大家介绍了关于PostgreSQL中offset...limit分页优化的一些常见手段,需要的朋友可以参考下
    2023-05-05
  • PostgreSQL实现一个通用标签系统

    PostgreSQL实现一个通用标签系统

    这篇文章主要给大家介绍了关于利用PostgreSQL实现一个通用标签系统的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-01-01
  • Postgresql的日志配置教程详解

    Postgresql的日志配置教程详解

    这篇文章主要介绍了Postgresql的日志配置教程详解,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-01-01
  • PostgreSQL  JOIN 联表查询实战演练(内连接 / 外连接 / 交叉连接)

    PostgreSQL  JOIN 联表查询实战演练(内连接 / 外连接

    本文介绍了PostgreSQL中的JOIN查询,包括INNER JOIN、LEFT JOIN、RIGHT JOIN、FULL JOIN和CROSS JOIN,通过实际示例和Java代码,展示了如何在Java应用程序中执行这些JOIN操作,感兴趣的朋友跟随小编一起看看吧
    2026-03-03

最新评论