xml - 如何在 BYTEA 的 PostgreSQL 数据库中编码 JPG 图像
问题描述
所以我有一些 JPG 图像存储在BYTEA
PostgreSQL 数据库表的列中。我想提取二进制文件并将其放入<img\>
标签中。这是其中一个文件的第一个位...
mydb=# SELECT LEFT(encode(image_file, 'escape'), 80) FROM image_files WHERE id = '53';
left
----------------------------------------------------------------------------------
x/ffd8ffe000104a46494600010100000100010000ffdb004300100b0c0e0c0a100e0d0e12111013
(1 row)
这个二进制数据非常符合我在实际图像文件中看到的内容(使用 Vim 的“转换为十六进制”)......
但是当我尝试将其编码为base64
(以便我可以通过 XSLT 使用数据以包含在网页中)时,它似乎已损坏。这是我的查询中的一个片段......
xmlelement(NAME "pictures",
xmlagg(
xmlelement(NAME "src", CONCAT('data:image/jpg;base64,', encode(image_file, 'base64')))
)
)
在 HTML 中,我看到...
<img src="data:image/jpg;base64,eC9mZmQ4ZmZlMDAwMTA0YTQ2NDk0NjAwMDEwMTAwMDAwMTAwMDEwMDAwZmZkYjAwNDMwMDEwMGIw+
YzB..."/>
...而不是看到我所期望的...
<img src="data:image/jpg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERAT..."/>
我不知何故发现(我不记得怎么做了!)如果我在开头用 '\x' 替换上面的 'x/',我会得到我期待的字符串......
mydb=# SELECT encode('\xffd8ffe000104a46494600010100000100010000ffdb004300100b0c0e0c0a100e0d0e12111013', 'base64');
encode
------------------------------------------------------
/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABALDA4MChAODQ4SERAT
(1 row)
所以我想知道,当 PG 尝试将十六进制字节数组编码为 时base64
,它是否也可能在字节数组中看到“ x/
”,这是否会导致它被丢弃?但对于我的一生,我无法弄清楚如何在查询中纠正这个问题。
我敢肯定这是每天都会发生的事情,现在不应该让我挠头将近一个星期!如果我遗漏了任何内容或需要任何版本信息,请告诉我。
解决方案
首先将您的文件保存到数据库中的任何内容都将它们搞砸了。它们可能保存在 bytea 列中,但它实际上是存储十六进制数字的文本数据,带有 2 个文字字符x
,/
无用且误导性地添加到前面。所以有些东西对二进制进行了十六进制编码,但随后存储了十六进制编码的字符串,就好像它仍然是二进制一样。
您需要切掉前 2 个字节,然后将结果字符串从 bytea 转换回文本。然后将保存十六进制数字的文本转换为真正的二进制,然后返回 base64。
SELECT encode(decode(substring(image_file,3)::text,'hex'),'base64') FROM image_file WHERE id = whatever;
(您实际上也可以在子字符串之前对文本进行强制转换)
但不是每次都进行这种转换,您可能应该重构您的表以保存更合理的数据。“更明智”将意味着存储在 bytea 列中的 bytea 数据,或者(如果您只想处理 base64)存储在文本列中的 base64 数据。
推荐阅读
- python - pyspark 在数据框中删除行以在一列中只有 X 个不同的值
- nginx - nginx docker 容器无法读取 certbot 证书
- r - 如何交叉制表跨同一字段的汇总值
- sh - 将变量分配给 shell 脚本中的每一行并稍后使用它们
- c# - .NET Core API 使用多个身份验证方案的问题
- c# - 将 avalonia 应用程序与某个自定义扩展名相关联,并在双击或使用 osX 中 finder 中的选项打开时处理文件
- autodesk-forge - 为什么更新的伪造查看器的模型浏览器隔离项目而不是选择?
- javascript - 如何防止用户输入重复的电子邮件?
- reactjs - styled-components:使用额外的样式扩展现有组件
- java - Can't import "import com.google.firebase.firestore.MetadataChanges" 原来的问题仍然没有答案