database - 使用 TypeORM Cordova 数据库将图像保存为 Blob
问题描述
概要
我的图像没有正确保存到我的 Cordova SQLite 数据库中。我正在使用 typeorm。数据(Uint8Array)被转换为字符串,因此我无法再次将其解码。
长版
我通过 typeorm 将以下 Uint8Array 保存到我的 Cordova SQLite 数据库中:
Uint8Array(4144617) [255, 216, 255, 224, 0, 16, 74, 70, 73, 70, 0, 1, 1, 0,
0, 1, 0, 1, 0, 0, 255, 219, 0, 67, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 255, 219,...]
我再次得到的是字符串类型:
���� JFIF �� C �� C...
当我将此 via 转换Buffer.from(image)
为 Uint8Array 时,它的大小几乎翻了一番:
Uint8Array(7723287) [239, 191, 189, 239, 191, 189, 239, 191, 189, 239, 191,
189, 0, 16, 74, 70, 73, 70, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 239, 191, 189, 239,
191, 189, 0, 67, 0, 1, 1, 1, 1,...]
上面的字符串是相同的 Uint8Array 表示,就好像我将它作为字符串打印到控制台一样。我尝试了不同的编码(utf8、ascii、windows-1253、utf-16le)将这个字符串解码为一个 Uint8Array,但都比以前产生更多。插入的日志消息看起来很好:
query: INSERT INTO someEntity (id, name, created, createdby,
lastchangedby, lastchanged, status, graphic) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
-- PARAMETERS: ["1","some name","2018-05-28T22:46:38.896Z","username","username",
"2018-05-28T22:46:38.896Z","1",
{"type":"Buffer","data":[255,216,255,224,0,16,74,70,73,70,0,1,1,0,0,1,0,1,0,0,255,219,0,67,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,255,219,...]]
但是无论我使用哪种方法,数据库中的结果始终是一个字符串:
connection.manager.query("INSERT INTO ... (...) VALUES (?, ?, ...)", [parameters...])
connection.manager.save(entity)
connection.manager.createQueryBuilder().insert().into(entity).values({parameters...}).execute()
我从我的 Android 设备中提取数据库并使用 DB Browser for SQLite 检查它以验证问题出在插入语句中,而不是在选择中。
在我的实体中,图像字段定义如下:
@Column("blob",{
nullable:true,
name:"graphic"
})
graphic: Buffer;
我为此苦苦挣扎了 2 周,并尝试了几种不同的方法。
问题
所以我的问题浓缩为:是否有任何技巧或解决方法将图像/文件保存为数据库中的真正 blob/字节数组,或者有没有办法将保存的字符串转换回可显示的图像?
提前致谢!
解决方案
我终于能够让它在带有 typeorm 的 sqljs 中工作。这是转换为base64字符串以显示来自数据库的缓冲区数据的方法。
BufferToBase64(buffer) {
var binary = '';
var byte = new Uint8Array( buffer );
var byteLen = byte.byteLength;
for (var i = 0; i < byteLen; i++) {
binary += String.fromCharCode( byte[ i ] );
}
return window.btoa( binary );
}
然后想办法显示base64字符串。就我而言,我需要做的就是设置一个图像前缀,然后传递该方法。这是一个示例
<img [src]="'data:image/png;base64,'+BufferToBase64(graphic)" />
关键是将 byte[] 转换为 base64。干杯。
推荐阅读
- c# - 在 C# 中实现两个接口的对象的方法重载
- javascript - 在 R Shiny 应用程序中加载模态对话框后,如何将焦点设置在文本输入字段上?
- python - 在 QTextEdit 上设置鼠标指针光标
- laravel - 如何解决 cors 在 vue js 和 laravel 应用程序中允许访问控制
- c - 从 const 指针释放分配的内存
- swift - 替换 .navigationBarItems SwiftUI 视图修饰符
- php - Laravel 和 Angular 从请求中获取图像
- amazon-web-services - 在 aws fargate 中的容器启动时创建文件
- ios - 我们如何决定使用 UICollectionViewController 还是 UIViewController?
- javascript - 如何以方便的方式在 html 页面中加载大型视频文件