在 PostgreSQL中解決圖片二進制數(shù)據(jù)由于bytea_output參數(shù)問題導(dǎo)致顯示不正常的問題
在 PostgreSQL 中,bytea_output 參數(shù)控制在查詢結(jié)果中 bytea 類型的顯示格式。默認情況下,bytea_output 的值為 hex,這意味著在查詢結(jié)果中,bytea 類型的數(shù)據(jù)以十六進制格式顯示。但是,如果你的應(yīng)用程序期望以二進制格式獲取圖像數(shù)據(jù),則將 bytea_output 設(shè)置為 escape 可能更適合。無論 bytea_output 參數(shù)設(shè)置為 hex 還是 escape,你都可以通過 C# 訪問 PostgreSQL 數(shù)據(jù)庫,并且正常獲取并顯示圖片。本篇隨筆介紹這個問題的處理過程。
在 PostgreSQL 中,bytea_output
參數(shù)控制在查詢結(jié)果中 bytea
類型的顯示格式。默認情況下,bytea_output
的值為 hex
,這意味著在查詢結(jié)果中,bytea
類型的數(shù)據(jù)以十六進制格式顯示。但是,如果你的應(yīng)用程序期望以二進制格式獲取圖像數(shù)據(jù),則將 bytea_output
設(shè)置為 escape
可能更適合。無論bytea_output
參數(shù)設(shè)置為hex
還是escape
,你都可以通過 C# 訪問 PostgreSQL 數(shù)據(jù)庫,并且正常獲取并顯示圖片。本篇隨筆介紹這個問題的處理過程。
1、碰到的數(shù)據(jù)庫圖片在界面顯示問題
在我們的Winform框架中,由于底層是支持多種數(shù)據(jù)庫的設(shè)計,因此可以兼容MS SQLServer、Oracle、Mysql、PostgreSQL、SQLite等數(shù)據(jù)庫的,但是一般我們用的是SQLServer、MySql居多,有客戶切換到PostgreSQL數(shù)據(jù)庫的時候,發(fā)現(xiàn)圖片顯示不正常,需要對圖片進行十六進制轉(zhuǎn)換才能正常顯示。
默認的方式,這里方框在SQLServer等數(shù)據(jù)庫上是正常顯示圖標的,打開編輯也是可以展示菜單的圖表的,不過由于切換到PostgreSQL后,這里圖標消失,檢查數(shù)據(jù)庫操作,默認的處理都是一致的,因此考慮是否為數(shù)據(jù)庫參數(shù)配置問題。
2、解決問題
打開ChatGPT,或者百度、Google一下,細心都可以發(fā)現(xiàn),在 PostgreSQL 中默認情況下,bytea_output
的值為 hex
,這意味著在查詢結(jié)果中,bytea
類型的數(shù)據(jù)以十六進制格式顯示。如果你的應(yīng)用程序期望以二進制格式獲取圖像數(shù)據(jù),則將 bytea_output
設(shè)置為 escape
可能更適合。
我們找到PostgreSQL的安裝目錄,找到 C:\Program Files\PostgreSQL\13\data\postgresql.conf里面的數(shù)據(jù)庫配置文件,找到bytea_output
的值查看。
果然發(fā)現(xiàn)其默認值為hex,我們按要求修改為escape,并去掉注釋符號#,如下所示。
重啟PostgreSQL,并測試系統(tǒng)數(shù)據(jù)庫,顯示和保存處理正常。
3、兩種方式處理的差異
如果 bytea_output
參數(shù)設(shè)置為 hex
,你可以通過將讀取到的十六進制字符串轉(zhuǎn)換為字節(jié)數(shù)組,然后使用這些字節(jié)數(shù)組來創(chuàng)建圖像對象。以下是一個示例代碼,演示了如何在 C# 中獲取并顯示圖片,即使 bytea_output
參數(shù)設(shè)置為 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(); // 執(zhí)行 SQL 查詢以獲取圖像數(shù)據(jù) 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); // 讀取圖像數(shù)據(jù) using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess)) { if (reader.Read()) { // 獲取十六進制字符串 string hexString = reader.GetString(0); // 將十六進制字符串轉(zhuǎn)換為字節(jié)數(shù)組 byte[] imageData = StringToByteArray(hexString); // 創(chuàng)建圖像對象 using (MemoryStream ms = new MemoryStream(imageData)) { Image image = Image.FromStream(ms); // 顯示圖像 ShowImage(image); } } } } } } static void ShowImage(Image image) { // 創(chuàng)建一個新的窗體 using (var form = new System.Windows.Forms.Form()) { // 創(chuàng)建 PictureBox 控件 var pictureBox = new System.Windows.Forms.PictureBox(); pictureBox.Dock = System.Windows.Forms.DockStyle.Fill; pictureBox.Image = image; // 將 PictureBox 添加到窗體中 form.Controls.Add(pictureBox); // 設(shè)置窗體大小并顯示 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
參數(shù)設(shè)置為 escape
,則可以直接使用 Npgsql 從數(shù)據(jù)庫中讀取圖像數(shù)據(jù),并將其轉(zhuǎn)換為字節(jié)數(shù)組,而不需要進行額外的處理。以下是示例代碼:
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(); // 執(zhí)行 SQL 查詢以獲取圖像數(shù)據(jù) 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); // 讀取圖像數(shù)據(jù) using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess)) { if (reader.Read()) { // 獲取圖像數(shù)據(jù)字節(jié)數(shù)組 byte[] imageData = (byte[])reader["image_column"]; // 創(chuàng)建圖像對象 using (MemoryStream ms = new MemoryStream(imageData)) { Image image = Image.FromStream(ms); // 顯示圖像 ShowImage(image); } } } } } } static void ShowImage(Image image) { // 創(chuàng)建一個新的窗體 using (var form = new System.Windows.Forms.Form()) { // 創(chuàng)建 PictureBox 控件 var pictureBox = new System.Windows.Forms.PictureBox(); pictureBox.Dock = System.Windows.Forms.DockStyle.Fill; pictureBox.Image = image; // 將 PictureBox 添加到窗體中 form.Controls.Add(pictureBox); // 設(shè)置窗體大小并顯示 form.Size = new System.Drawing.Size(image.Width, image.Height); form.ShowDialog(); } } }
無論 bytea_output
參數(shù)設(shè)置為 hex
還是 escape
,你都可以通過 C# 訪問 PostgreSQL 數(shù)據(jù)庫,并且正常獲取并顯示圖片。
到此這篇關(guān)于在 PostgreSQL 中解決圖片二進制數(shù)據(jù)由于bytea_output參數(shù)問題導(dǎo)致顯示不正常的問題的文章就介紹到這了,更多相關(guān)PostgreSQL內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SQL Server數(shù)據(jù)遷移至PostgreSQL出錯的解釋以及解決方案
最近對SQL Server到PostgreSQL的數(shù)據(jù)遷移時出現(xiàn)了問題,返回的錯誤為:invalid byte sequence for encoding "UTF8": 0x00。經(jīng)查證pg源代碼,該問題引起的原因是sql server的字符類型字段中含有空字符\0,該字符在pg中不支持。2014-09-09PostgreSQL怎么創(chuàng)建分區(qū)表詳解
數(shù)據(jù)庫表分區(qū)把一個大的物理表分成若干個小的物理表,并使得這些小物理表在邏輯上可以被當成一張表來使用,下面這篇文章主要給大家介紹了關(guān)于PostgreSQL怎么創(chuàng)建分區(qū)表的相關(guān)資料,需要的朋友可以參考下2022-06-06SpringBoot連接使用PostgreSql數(shù)據(jù)庫的方法
這篇文章主要介紹了SpringBoot連接使用PostgreSql數(shù)據(jù)庫的方法,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-01-01postgresql數(shù)據(jù)庫連接數(shù)和狀態(tài)查詢操作
這篇文章主要介紹了postgresql數(shù)據(jù)庫連接數(shù)和狀態(tài)查詢操作,具有很好的參考價值,對大家有所幫助。一起跟隨小編過來看看吧2021-02-02PostgreSQL教程(十四):數(shù)據(jù)庫維護
這篇文章主要介紹了PostgreSQL教程(十四):數(shù)據(jù)庫維護,本文講解了恢復(fù)磁盤空間、更新規(guī)劃器統(tǒng)計、VACUUM和ANALYZE的示例、定期重建索引等內(nèi)容,需要的朋友可以參考下2015-05-05