在 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参数问题导致显示不正常的问题。的更多相关文章

  1. [原创]PostgreSQL中十进制、二进制、十六进制之间的相互转换

    在PostgreSQL中,二进制.十进制.十六进制之间的转换是非常方便的,如下: 十进制转十六进制和二进制 mydb=# SELECT to_hex(10); to_hex -------- a (1 ...

  2. pgmagick,pil不保存图片并且获取图片二进制数据记录

    PIL和pgmagick都是python中图像处理的库,只不过PIL功能更强大 pgmagick和PIL中对数据进行调整后经常需要调用write或者save方法保存图片,然后在读取图片的内容,这样很麻 ...

  3. 分页(将数据库中的多条数据一页一页的显示在jsp页面中)

    一.显示数据库中的多条数据为什么要用分页 在真正的开发中,数据库中所存储的数据绝对不像我们平时所写的那样,仅仅有几条数据,而是有几十条甚至上百条,像淘宝京东的用户把都是上几十万甚至百万的.如果这时候在 ...

  4. ModelForm 中选择框的数据 以及 instance 参数

    ModelForm 中选择框的数据 print(list(self.fields['customer'].choices)) # [('', '---------'), (1, '张飞'), (2, ...

  5. react中引入图片路劲正确但是页面上不显示或者打包后不能正常显示的问题

    一.react中图片引入方式 以前我们用img引入图片只需要如下即可,在react中这样写会报错: <img src="../assets/zzsc1.png" /> ...

  6. 前端H5中JS用FileReader对象读取blob对象二进制数据,文件传输

    HTML5中的Blob对象只是二进制数据的容器,本身并不能操作二进制,故本篇将对其操作对象FileReader进行介绍. FileReader FileReader主要用于将文件内容读入内存,通过一系 ...

  7. [ActionScript 3.0] AS向php发送二进制数据方法之——在URLRequest中构造HTTP协议发送数据

    主类 HTTPSendPHP.as package { import com.JPEGEncoder.JPGEncoder; import com.fylib.httpRequest.HttpRequ ...

  8. C++ Redis mset 二进制数据接口封装方案

    C++ Redis mset 二进制数据接口封装方案 需求 C++中使用hiredis客户端接口访问redis: 需要使用mset一次设置多个二进制数据 以下给出三种封装实现方案: 简单拼接方案 在r ...

  9. mssql sqlserver 可以存储二进制数据的字段类型详解

    转自: http://www.maomao365.com/?p=6738 摘要: 下文将从数据库的数据类型着手,剖析在sqlserver数据库中可以存储二进制数据的数据类型,如下所示: mssql s ...

  10. nodeJS-使用buffer类处理二进制数据

    使用buffer类处理二进制数据 在客户端javascript脚本代码中,对于二进制数据并没有提供一个很好的支持.然后在nodejs中需要处理像TCP流或文件流时,必须要处理二进制数据.因此在node ...

随机推荐

  1. 2023年多校联训NOIP层测试3+「SFCOI-3」Sadness Fan Club Round 3

    2023年多校联训NOIP层测试3 T1 数列变换 \(10pts\) 考虑暴力,发现 \(f\) 数列进行一次变换 \(A\) ,再进行一次变换 \(B\) 后,恢复成了原数列: \(f\) 数列进 ...

  2. 使用V2R做反向代理内网穿透

    环境 内网服务器Prob1位于内网LAN1, 内网服务器Prob2位于内网LAN2, 外网服务器Serv1位于IP 123.123.123.123 内网节点配置 内网节点没有inbound,只需要配置 ...

  3. 团队协作如何确保项目Node版本的一致性?

    前言 想必大家在工作过程中都遇到过node版本带来的各种各样的问题,对于团队协作项目,你不能保证所有人的本地node版本都相同,所以在项目文档中往往会写上以下内容: 为与线上环境一致,请保证以下版本 ...

  4. Java JVM——4.程序计数器

    简介 JVM中的程序计数寄存器(Program Counter Register),Register的命名源于CPU的寄存器,寄存器存储指令相关的现场信息,CPU只有把数据装载到寄存器才能够运行. 这 ...

  5. ASP.NET 读取FTP文件流

    参考资料 ASP.NET 上传文件到共享文件夹 工具类代码 /// <summary> /// 读取ftp文件流 /// </summary> /// <param na ...

  6. logback中使用MDC自定义日志输出格式

    logback-MDC 相当于自定义日志格式输出 写在过滤器中 示例: try { Context context = createContext(request, response); proces ...

  7. MAUI发布APK初体验

    目的 很早就有想编写安卓程序玩玩的念头了,所以这次学习将MAUI程序生成apk包来玩. 本文apk下载地址:https://azrng.lanzouv.com/iBQRe0eeg8wf ,内容很简单, ...

  8. UI自动化测试中图片验证码的处理?

    首先定位验证码image的元素,然后通过element.screenshot('a.png')截图保存到本地,通过第三方接口识别本地图片验证码

  9. Mysql常用存储引擎以及区别?

    InnoDB:是Mysql的默认存储引擎,支持事务.外键.如果应用对事务的完整性有比较高的要求,在并发条件下要求数据的一致性,数据操作除了插入和查询之外,还包含很多的更新.删除操作,那么InnoDB存 ...

  10. FolkMQ 作个简单的消息中间件(最简单的那种), v1.3.1 发布

    功能简介 角色 功能 生产端(或发起端) 发布消息.定时消息(或叫延时).顺序消息.可过期消息.事务消息.发送消息(rpc)支持 Qos0.Qos1 消费端(或接收端) 订阅.取消订阅.消费-ACK( ...