因為項目的原因了解到有一個python的flask框架,查了一下: 關于前端圖片上傳的canvas: 如下元素
< canvas id = " canvas" width = " 5" height = " 5" > </ canvas>
可以用這樣的方式獲取一個 data-URL
var canvas
= document
. getElementById ( "canvas" ) ;
var dataURL
= canvas
. toDataURL ( ) ;
console
. log ( dataURL
) ;
// “data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNby // blAAAADElEQVQImWNgoBMAAABpAAFEI8ARAAAAAElFTkSuQmCC” 設置jpegs圖片的質量
var fullQuality
= canvas
. toDataURL ( "image/jpeg" , 1.0 ) ;
var mediumQuality
= canvas
. toDataURL ( "image/jpeg" , 0.5 ) ;
var lowQuality
= canvas
. toDataURL ( "image/jpeg" , 0.1 ) ;
getContext() 方法返回一個用于在畫布上繪圖的環境。
語法 Canvas.getContext(contextID) 參數 參數 contextID 指定了您想要在畫布上繪制的類型。當前唯一的合法值是 “2d”,它指定了二維繪圖,并且導致這個方法返回一個環境對象,該對象導出一個二維繪圖 API。
提示:在未來,如果 < canvas> 標簽擴展到支持 3D 繪圖,getContext() 方法可能允許傳遞一個 “3d” 字符串參數。
返回值 一個 CanvasRenderingContext2D 對象,使用它可以繪制到 Canvas 元素中。 后端: 首先pip install Flask 然后新建文件:
from flask
import Flask
, make_response
, jsonify
from multiprocessing
import Process
app
= Flask
( __name__
)
def run_index ( ) : app
. run
( host
= '0.0.0.0' , port
= 5000 , threaded
= True ) def make_new_response ( data
) : res
= make_response
( jsonify
( { 'code' : 0 , 'data' : data
} ) ) res
. headers
[ 'Access-Control-Allow-Origin' ] = '*' res
. headers
[ 'Access-Control-Allow-Method' ] = '*' res
. headers
[ 'Access-Control-Allow-Headers' ] = '*' return res@app
. route
( '/' )
def hello_world ( ) : return { 'hello' : 'world!' } @app
. route
( "/test" )
def test ( ) : res
= "{'no':'dddd'}" return make_new_response
( res
) if __name__
== "__main__" : app
. run
( debug
= True )
打開瀏覽器:
向flask后端發請求接收圖片:(點擊按鈕觸發事件) flask:
from flask
import Flask
, make_response
, jsonify
from flask_cors
import CORS
import socket
import threading
import json
import os
from io
import BytesIO
from multiprocessing
import Process
import io
from PIL
import Image
app
= Flask
( __name__
)
def main ( ) : serversocket
= socket
. socket
( socket
. AF_INET
, socket
. SOCK_STREAM
) host
= socket
. gethostname
( ) port
= 5000 serversocket
. bind
( ( host
, port
) ) serversocket
. listen
( 5 ) myaddr
= serversocket
. getsockname
( ) print ( "服務器地址:%s" % str ( myaddr
) ) while True : clientsocket
, addr
= serversocket
. accept
( ) print ( "連接地址:%s" % str ( addr
) ) try : t
= ServerThreading
( clientsocket
) t
. start
( ) pass except Exception
as identifier
: print ( identifier
) pass pass serversocket
. close
( ) pass def run_index ( ) : app
. run
( host
= '0.0.0.0' , port
= 5000 , threaded
= True ) CORS
( app
, resources
= r
'/*' , supports_credentials
= True ) basedir
= os
. path
. abspath
( os
. path
. dirname
( __file__
) ) @app
. route
( '/getPic' , methods
= [ 'GET' , 'POST' ] )
def findpic ( ) : img_url
= basedir
+ '/data/tt/b/b_1.png' print ( img_url
) with open ( img_url
, 'rb' ) as f
: a
= f
. read
( ) '''對讀取的圖片進行處理''' img_stream
= io
. BytesIO
( a
) img
= Image
. open ( img_stream
) imgByteArr
= io
. BytesIO
( ) img
. save
( imgByteArr
, format = 'PNG' ) imgByteArr
= imgByteArr
. getvalue
( ) print ( imgByteArr
) return imgByteArr
if __name__
== "__main__" : app
. run
( debug
= True )
注意:Python在內存中讀寫數據,用到的模塊是StringIO和BytesIO,當為StringIO時getvalue()方法用于獲得寫入后的str。StringIO操作的只能是str,如果要操作二進制數據,就需要使用BytesIO。可以用一個bytes初始化BytesIO,然后,像讀文件一樣讀取:
>> > from io
import BytesIO
>> > f
= BytesIO
( b
'\xe4\xb8\xad\xe6\x96\x87' )
>> > f
. read
( )
b
'\xe4\xb8\xad\xe6\x96\x87'
BytesIO實現了在內存中讀寫bytes。
vue代碼:
< button @click = " getPic" > 獲取圖片
</ button> < img :src = " picurl" alt = " beachball" />
data ( ) { return { picurl
: "" , } } , methods
: { getPic ( ) { var that
= this ; this . $axios
. get ( 'http://127.0.0.1:5000/getPic' , { responseType
: "arraybuffer" , } ) . then ( function ( response
) { that
. picurl
= "data:image/jpeg;base64," + that
. arrayBufferToBase64 ( response
. data
) ; } ) ; } , arrayBufferToBase64 ( buffer
) { var binary
= "" ; var bytes
= new Uint8Array ( buffer
) ; var len
= bytes
. byteLength
; for ( var i
= 0 ; i
< len
; i
++ ) { binary
+= String
. fromCharCode ( bytes
[ i
] ) ; } return window
. btoa ( binary
) ; } ,
}
點擊按鈕后: 后端的顯示:
圖片傳給后端
搗鼓了半天終于把圖片傳給后端了,不過暫時用的java測試。中途遇到無數次cannot read property xxx xxx is not defined,懷疑是自己哪些代碼莫名出了問題,因為canvas是getelementbyid,所以如果寫的是ref的話是獲取不到的,然后注釋掉了一堆代碼,結果:
后端的響應:
flask獲取圖片數據:
flask獲取參數方式:
request.form.get(“key”, type=str, default=None) 獲取表單數據
request.args.get(“key”) 獲取get請求參數
request.values.get(“key”) 獲取所有參數
import base64
img1
= 'E:/nsfw_tensorflow/corpus/weibocore_WBC_IMAGE_DATA_SOURCE_6521.jpg' pimg
= open ( img1
, 'rb' ) . read ( ) print ( pimg
) # base64圖片加密
result
= base64
. b64encode ( pimg
) print ( result
) # 再把加密后的結果解碼
temp
= base64
. b64decode ( result
) print ( temp
)
現在出現一個問題,從前端發送圖片之后后端接收到的data一直是str類型,不知道怎么取出來:
@app
. route ( '/getpic' , methods
= [ 'POST' ] )
def
getpic ( ) : data
= flask
. request
. get_data ( ) . decode ( 'utf-8' ) data
= json
. loads ( data
) data_b64
= data
[ "data" ] print ( type ( data_b64
) )
修改:
def
getpic ( ) : data
= json
. loads ( flask
. request
. get_data ( "data" ) ) data_64
= str
. encode ( data
[ 'data' ] ) print ( type ( data_64
) ) print ( data_64
)
得到類型為bytes. 前端去掉base64前面的前綴:
var image
= this . thisCancas
. toDataURL ( "image/png" ) . split ( 'base64,' ) [ 1 ] ;
搞了好久試了好多方法終于把前端的圖片base碼解出來了!!!!!!激動 后端的代碼:
def decode_base64 ( data
) : """Decode base64, padding being optional.:param data: Base64 data as an ASCII byte string:returns: The decoded byte string.""" missing_padding
= len ( data
) % 4 if missing_padding
!= 0 : data
+= b
'=' * ( 4 - missing_padding
) return base64
. b64decode
( data
)
@app
. route
( '/getpic' , methods
= [ 'POST' ] )
def getpic ( ) : data
= json
. loads
( flask
. request
. get_data
( "data" ) ) data_64
= str . encode
( data
[ 'data' ] ) print ( type ( data_64
) ) print ( '------------------------' ) print ( str ( data_64
, 'utf8' ) ) imgdata
= decode_base64
( data_64
) file = open ( '1.jpg' , 'wb' ) file . write
( imgdata
) file . close
( )
其中注意前端發送的數據也經過了處理,使得去掉了img/jpeg前綴
現在載入模型進行拍照預測: 附上關鍵的代碼:
import torch
from torchvision
import transforms
def run_index ( ) : app
. run
( host
= '0.0.0.0' , port
= 5000 , threaded
= True )
def decode_base64 ( data
) : """Decode base64, padding being optional.:param data: Base64 data as an ASCII byte string:returns: The decoded byte string.""" missing_padding
= len ( data
) % 4 if missing_padding
!= 0 : data
+= b
'=' * ( 4 - missing_padding
) return base64
. b64decode
( data
)
transform
= transforms
. Compose
( [ transforms
. Resize
( 224 ) , transforms
. CenterCrop
( 224 ) , transforms
. ToTensor
( ) , transforms
. Normalize
( mean
= [ 0.485 , 0.456 , 0.406 ] , std
= [ 0.229 , 0.224 , 0.225 ] ) ] ) CORS
( app
, resources
= r
'/*' , supports_credentials
= True )
@app
. route
( '/getpic' , methods
= [ 'POST' ] )
def getpic ( ) : data
= json
. loads
( flask
. request
. get_data
( "data" ) ) data_64
= str . encode
( data
[ 'data' ] ) print ( type ( data_64
) ) print ( '------------------------' ) print ( str ( data_64
, 'utf8' ) ) imgdata
= decode_base64
( data_64
) file = open ( '1.jpg' , 'wb' ) file . write
( imgdata
) file . close
( ) image
= Image
. open ( r
"1.jpg" ) . convert
( 'RGB' ) image
= transform
( image
) . unsqueeze
( 0 ) modelme
= torch
. load
( 'modefresnet.pkl' ) modelme
. eval ( ) outputs
= modelme
( image
) _
, predict
= torch
. max ( outputs
. data
, 1 ) for j
in range ( image
. size
( ) [ 0 ] ) : print ( 'predicted: {}' . format ( class_names
[ predict
[ j
] ] ) ) return class_names
[ predict
[ j
] ]
if __name__
== "__main__" : app
. run
( debug
= True )
試了好多次,幾乎都與預測結果相符。 哈哈哈哈哈花了兩天弄這個,之前關于圖片解碼編碼一直沒弄出來,現在成功了還是挺開心的。
總結
以上是生活随笔 為你收集整理的【后端过程记录】用flask搭建服务器作后端接收数据 将base64字符串码解码为可读取文件 载入训练好的模型进行预测 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。