思路詳解
直奔主題吧,就不瞎侃了。
整個流程的思路呢,就是將圖片批量保存到數據庫,但是呢又想學習一下加密算法,不過先不加密先,先將圖片轉爲字符再保存到數據庫。起初用4M大小的圖片試了下,不試不知道,一試嚇一跳,一張4M多的圖片,轉爲字符有整整5百多萬個字符。
嘗試着把它存到數據庫,成是成了,就是用SqliteSpy打開該數據庫並且點擊該列查看詳情時直接導致該軟件崩潰。
此路行不通,沒辦法,只能另尋闢徑。思來想去只好把圖片壓縮了,可憐了我的高清大圖,不過沒大礙,我已經上升到了心中無碼的強大境地。
但是爲了不至於壓縮到眯着眼都看不清楚,使用cv2庫進行了多個壓縮比的探究,最後得出幾個比較實用的壓縮比。在下面的成果圖我們就可以看到將4M多的圖片按40的壓縮比進行壓縮時圖片變成了400多k,整整少了十倍左右。當然,400多k的圖片看起來還是挺不錯的,不過200多k的圖片按40的壓縮比成了50多k,感覺有點過度了,應該將70改爲80甚至90更爲合適。
成果截圖
模塊代碼
解釋
話就不多說了,基本上都寫有註釋,按邏輯思路一步一步來,適合無聊時打發時間消遣學習使用。
整體
from img_date_sql import *
import base64,time,os,cv2
def get_time():
"""
該函數返回當前時間戳
時間戳轉爲可視化時間
time_stamps=time.strftime('%Y-%m-%d %H:%M:%S ',time.localtime(float(time_stamp)))
"""
return str(time.time())
def get_FileSize(filePath):
"""
該函數返回當前文件大小,單位M
1M=0.1
"""
fsize = os.path.getsize(filePath)
fsize = fsize/float(1024*1024)
return round(fsize,2)
def get_ratio(img_size):
"""
該函數根據圖片大小返回壓縮比
壓縮比越高壓縮率越低
單位 M
1M=0.1
"""
if 0<img_size<=0.1:
return 95
elif 0.1<img_size<=0.5:
return 70
elif 0.5<img_size<=1.5:
return 55
elif 1.5<img_size<=2.5:
return 50
elif 2.5<img_size<=3.5:
return 45
elif 3.5<img_size<=5.0:
return 40
else:
return 30
def img_compress(img_path,ratio):
new_img_path=''
"""
img_path:圖片地址
ratio:壓縮比率0-100,
該函數返回已壓縮後的圖片路徑
jpg是有損壓縮
0時圖像可以得到極大地壓縮,但是圖像的品質會被大大降低。
"""
img=cv2.imread(img_path,1)
new_img_path=img_path.replace('.', '_%s_'%str(ratio))+'.jpg'
cv2.imwrite(new_img_path,img,[cv2.IMWRITE_JPEG_QUALITY,ratio])
return new_img_path
def str_img(imaStr,img_name):
"""
從數據庫獲取圖片數據並解碼
"""
imadata = base64.b64decode(imaStr)#解碼
with open(img_name, 'wb') as f:
f.write(imadata)
def img_str(img_path):
"""
img_paath:圖片路徑
1.獲取當前時間
2.獲取當前圖片大小
3.根據圖片大小進行得到壓縮比
4.獲取壓縮後的圖片路徑
5.將該圖進行字符轉化並保存到數據庫
"""
time_stamp=get_time() #1
img_size=get_FileSize(img_path) #2
ratio=get_ratio(img_size) #3
new_img_path=img_compress(img_path,ratio) #4
with open(new_img_path, 'rb') as f:
base64_data = base64.b64encode(f.read())
s = base64_data.decode()
imgstrLen=str(len(s))
img_insertData(new_img_path,time_stamp,imgstrLen,s) #5
#保存後刪除該文件
os.remove(new_img_path)
if __name__=='__main__':
#存儲圖片
img_path="1.jpg"
img_str(img_path)
#從數據庫提取圖片
#返回數據庫已存在的全部圖片名稱信息,是一個列表[('2_jpg.jpg',), ('1_jpg.jpg',)] a[0][0]就獲取到圖片名稱
a=img_selectImgname()
try:
for i in a:
#根據圖片名稱返回圖片字符信息 [0][0]就獲取到具體圖片字符信息
b=img_showBase64(i[0])[0][0]
#將得到的信息轉化爲圖片
str_img(b,i[0])
print('已完成,沒問題喲!')
except:
print('出bug啦!')
數據庫(img_date_sql.py)
# -*- coding:utf-8 -*-
import sqlite3
def img_opendb():
conn = sqlite3.connect("img_date.db")
cur = conn.execute("""create table if not exists img_info(imgName varchar(126),addTime char(30),imgstrLen char(30),imgBase64 text)""")
return cur,conn
# 往數據庫中添加內容
def img_insertData(imgName,addTime,imgstrLen,imgBase64):
hel = img_opendb()
hel[1].execute("insert into img_info(imgName,addTime,imgstrLen,imgBase64) values ('%s','%s','%s','%s')"%(imgName,addTime,imgstrLen,imgBase64))
hel[1].commit()
hel[1].close()
# 刪除數據庫中的全部內容
def img_delall():
hel = img_opendb() # 返回遊標conn
hel[1].execute("delete from img_info")
print("刪庫跑路Cxk我最帥")
hel[1].commit()
hel[1].close()
#查詢圖片字符信息
def img_showBase64(imgName):
hel = img_opendb()
cur = hel[1].cursor()
cur.execute("select imgBase64 from img_info where imgName='%s'"%imgName)
res = cur.fetchall()
cur.close()
return res
def img_selectImgname():
hel = img_opendb()
cur = hel[1].cursor()
cur.execute("select imgName from img_info")
res = cur.fetchall()
cur.close()
return res
後記
總體來說這很滑稽,因爲用字符來存圖片用在項目上實現的話我覺得不太可靠,不過用來存用戶頭像的話還是可行的,當然對於分辨率不高的圖片在這方面還是挺有用處的,或者你想存點私密的圖片,保存好後直接保存一個db文件就ok了。
好了,暫時侃到這裏,代碼還有很多可以改進的地方,數據庫隨便寫的,加個GUI還可以批量處理圖片,當然這些都不去弄了,有空再看看加密算法的應用,嘗試用在這裏看看效果怎麼樣,或者自己寫個加密算法上去,ヽミ ´∀`ミノ<。