【python3】 sqlite3操作SQLite数据库存取图片

  • 1.背景
  • 2.code
  • 3.运行结果

1.背景

SQLite 原生支持如下的类型: NULL,INTEGER,REAL,TEXT,BLOB。

因此可以将以下Python类型发送到SQLite而不会出现任何问题:

python存储binary_sqlite


这是SQLite类型默认转换为Python类型的方式:

python存储binary_sqlite_02


sqlite3 模块的类型系统可通过两种方式来扩展(本博文不涉及):你可以通过对象适配将额外的 Python 类型保存在 SQLite 数据库中,你也可以让 sqlite3 模块通过转换器将 SQLite 类型转换为不同的 Python 类型。

本博文
1.1 将读取图片二进制数据(bytes字节码)进行base64编码(仍然为bytes字节码),然后存到SQLite数据库。(将python的字节码要想存进SQLite数据库,对应的是上述BLOB的SQLite 类型。)
1.2 并从SQLite数据库读取图片的字节码,并转化opencv的数据类型;

2.code

#1.SQlite原生类型:BLOB对应python的bytes字节码
'''
date:2020.11.23
author:jn10010537
python3使用sqlite3保存图片以及从数据读取图片
'''
import sys
import sqlite3
import base64
import cv2
import numpy as np
print("python版本:",sys.version)#3.6.8 (tags/v3.6.8:3c6b436a57, Dec 24 2018, 00:16:47) [MSC v.1916 64 bit (AMD64)]
print("sqlite3模块的版本号:",sqlite3.version)#2.6.0
print("sqlite3模块的版本号,元组:",sqlite3.version_info)#(2, 6, 0)
print("使用中的 SQLite 库的版本号:",sqlite3.sqlite_version)#3.21.0

#1.打开数据库,获得连接对象
conn=sqlite3.connect("jn10010537.db")
#2.获得数据库的操作游标
c=conn.cursor()
#3.创建数据表
# 如果不存在数据表就创建
# 数据表名pictureTable,
# 字段:picName,width,height,image_bytes
symbol = 'pictureTable'
try:
    c.execute('create table IF NOT EXISTS %s(picName TEXT,width INTEGER, height INTEGER, image_bytes BLOB)'%symbol)
    #提交到数据库
    conn.commit()
    pass
except Exception as e:
    print(e)
    print("Create table failed")

# #4.打开图片编码成base64的字节码后存入
Pic_byte=None
with open('test.png', 'rb') as f:
     Pic_byte=f.read()
     print("数据类型:",type(Pic_byte))
     #字节码进行编码
     content = base64.b64encode(Pic_byte)
     print("数据类型:",type(content))
     #插入图片的二进制数据
     sql = f"INSERT INTO pictureTable (picName,width, height, image_bytes) VALUES (?,?,?,?);"
     #使用?占位符,是安全的sql语句
     c.execute(sql, ('test.png', 418, 412,content))
     conn.commit()
#5.读取数据库的图片数据
cursor = conn.cursor()
sql = f"SELECT image_bytes FROM pictureTable WHERE picName=?"
cursor.execute(sql,('test.png',))
value = cursor.fetchone()
print("value类型:",type(value))
if value:
    #base64编码对应的解码(解码完字符串)
    str_encode=base64.b64decode(value[0])
    print("判断解码完和之前存入的十六进制字节码是否一致:",str_encode==Pic_byte)
    # 将open方法读取的字节码转为opencv格式的数据
    nparr = np.fromstring(str_encode, np.uint8)
    img_decode = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
    '''
    或者采取如下方法:
    nparr = np.asarray(bytearray(str_encode), dtype="uint8")
    img_decode = cv2.imdecode(nparr, cv2.IMREAD_COLOR)    
    '''
    cv2.imshow("img",img_decode)
    cv2.waitKey(0)

3.运行结果

python存储binary_python存储binary_03


同时生成了jn10010537.db数据库文件,分别查看jn10010537.db的属性,以及被读取的图片属性如下:

python存储binary_sqlite_04


python存储binary_python存储binary_05

即base64编码是可以降低图片的存储大小的。(只是比png图片储存占用大了一点,远远小于168KiB)