Django中上传的图片经过OpenCV处理后在前端显示

  OpenCV打开的图片都是以Mat(矩阵)的形式打开,直接传到前端就是一堆矩阵数字,不能正常显示。众所周知,在HTML上显示图片,用到的img标签都是以src的形式写的,base64格式可以代替src中需要填写的地址。因此,可以将OpenCV处理之后的图片转为base64再传输
  JavaScript的写法如下:dataType是从后端传回到前端的数据格式,必须以text的形式,这样传递的数据就能够直接在dom渲染的地方使用。$(’#newpic’)处表示的就是对dom进行新的渲染。

 $.ajax({
            url: "/getimg", //请求路径
            type: 'POST', // 请求类型
            data: formData, // 请求数据
            //dataType: "JSON", // JSON格式不对
            dataType: "text", // 返回数据格式
            contentType: false, //表示不处理数据
            processData: false,
            cache: false,
            success: function (data) {
                console.log("上传成功打印:"+data);
                if (data != null){
                    console.log("返回的数据:"+data)
                    $('#newpic').append("<img src="+'"data:image/jpg;base64,'+data+'">')
                }
                if (data == null){
                    console.log("返回数据为空")
                }
            },
            error: function (data) {
                console.log("数据返回失败")
                console.log(data);
            }
        });

  Django的后端代码如下,注释已经很清楚了。

def getimg(request):
    print("in")
    try:
        # 当不使用JS时
        # image = request.FILES.get('images')
        # 当使用ajax时
        # 得到img文件
        image = request.FILES['img']
  		# path需要修改
  		# path表示的是图片从前端上传之后,在服务器某处存储(这里写的比较简单,可换用数据库等等)
        path = default_storage.save('static/' + image.name, ContentFile(image.read()))
        print(path.__str__())
        # 保存图像
        os.path.join(settings.MEDIA_ROOT, path)
        # 调用opencv库
        # face_xml_location = os.path.join('.','haarcascade_frontalface_default.xml')
        # 声明cascadeclassifie对象face_cascade,用于检测人脸
        face_cascade = cv2.CascadeClassifier('DjangoBlog/haarcascade_frontalface_default.xml')
        img = cv2.imread('static/'+image.name)
        # openCV识别灰度图片,也就是黑白图片,所以要进行转换
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        faces = face_cascade.detectMultiScale(gray, 1.3, 5)
        # 在人脸周围绘制矩形
        for (x, y, w, h) in faces:
            #得到的是矩阵形式的图片
            img = cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 0)
        # 此处是核心部分:OPENCV转BASE64
        img1 = cv2.imencode('.jpg',img)[1]
        back_2 = base64.b64encode(img1)
        print(back_2)
        
        return HttpResponse(back_2)
    except:
        return HttpResponse("<p>图片上传不成功</p>")

  话外:在新插入一个dom的时候,需要实现写好这个dom的CSS样式,或者用于渲染的代码上需要写上该dom的css样式。

  关于dom的base64渲染

$('#newpic').append("<img src="+'"data:image/jpg;base64,'+data+'">')

data:,文本数据
data:text/plain,文本数据
data:text/html,HTML代码
data:text/html;base64,base64编码的HTML代码
data:text/css,CSS代码
data:text/css;base64,base64编码的CSS代码
data:text/javascript,Javascript代码
data:text/javascript;base64,base64编码的Javascript代码
data:image/gif;base64,base64编码的gif图片数据
data:image/png;base64,base64编码的png图片数据
data:image/jpeg;base64,base64编码的jpeg图片数据
data:image/x-icon;base64,base64编码的icon图片数据
但是这种方法不兼容IE6/7,使用时要注意!



在项目之外,记载PIL/OpenCV/base64相互转换(非原创),转自:https://blog.csdn.net/haveanybody/article/details/86494063

##PIL读取、保存图片方法
from PIL import Image
img = Image.open(img_path)
img.save(img_path2)
 
 
##cv2读取、保存图片方法
import cv2
img = cv2.imread(img_path)
cv2.imwrite(img_path2, img)
 
 
##图片文件打开为base64
import base64
 
def img_base64(img_path):
    with open(img_path,"rb") as f:
        base64_str = base64.b64encode(f.read())
    return base64_str 

1、PIL和cv2转换

##PIL转cv2
import cv2
from PIL import Image
import numpy as np
 
def pil_cv2(img_path):
    image = Image.open(img_path)
    img = cv2.cvtColor(np.asarray(image),cv2.COLOR_RGB2BGR)
    return img
 
 
##cv2转PIL
import cv2
from PIL import Image
 
def cv2_pil(img_path):
    image = cv2.imread(img_path)
    image = Image.fromarray(cv2.cvtColor(image,cv2.COLOR_BGR2RGB))
    return image

2、PIL和base64转换

##PIL转base64
import base64
from io import BytesIO
 
def pil_base64(image):
    img_buffer = BytesIO()
    image.save(img_buffer, format='JPEG')
    byte_data = img_buffer.getvalue()
    base64_str = base64.b64encode(byte_data)
    return base64_str
 
 
##base64转PIL
import base64
from io import BytesIO
from PIL import Image
 
def base64_pil(base64_str):
    image = base64.b64decode(base64_str)
    image = BytesIO(image)
    image = Image.open(image)
    return image

3、cv2和base64转换

##cv2转base64
import cv2
 
def cv2_base64(image):
    base64_str = cv2.imencode('.jpg',image)[1].tostring()
    base64_str = base64.b64encode(base64_str)
    return base64_str 
 
 
##base64转cv2
import base64
import numpy as np
import cv2
 
def base64_cv2(base64_str):
    imgString = base64.b64decode(base64_str)
    nparr = np.fromstring(imgString,np.uint8)  
    image = cv2.imdecode(nparr,cv2.IMREAD_COLOR)
    return image

其他有价值的参考:
图像前后端的数据交互及图像格式的转换(python、opencv)
https://blog.csdn.net/zsycode/article/details/91320053
通过template渲染的形式从后端写入图片
https://blog.csdn.net/liuweiyuxiang/article/details/71152956
使用Django StreamingHttpResponse实现opencv处理图片后进行web视频流播放
http://javabin.cn/2018/django_steam.html
python cv2展示网络图片、图片编解码、及与base64转换
https://www.cnblogs.com/gmhappy/p/11863946.html

  • 6
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值