python显示图片二进制流乱码_使用Ajax获取二进制数据流图片渲染到img标签

这里我用的是python3.6+Flask。实现一个登录时的验证码,点击通过Ajax的方式获取后台传来的二进制数据

python绘制图片验证码,具体解释都有     Code.py

# -*- encoding:utf8 -*-

import random

import string

from PIL import Image, ImageDraw, ImageFont

# Image:画布 ImageDraw:画笔 ImageFont:画笔的字体

# print(list(string.ascii_letters))

class Captcha(object):

number = 4 # 生成几位数的验证码

size = (150, 40) # 验证码图片的宽度和高度

fontsize = 35 # 验证码字体大小

line_number = 2 # 加入干扰线的条数

SOURCE = list(string.ascii_letters+"123456789") # 构建一个验证码源文本,包括大小写数字

# classmethod 修饰符对应的函数不需要实例化,不需要 self 参数,

# 但第一个参数需要是表示自身类的 cls 参数,可以来调用类的属性,类的方法,实例化对象等。

@classmethod

def __gene_line(cls, draw, width, height):

# 开始点 X,Y

begin = (random.randint(0, width), random.randint(0, height))

# 结束点

end = (random.randint(0, width), random.randint(0, height))

# 画线条,开始 结束点 线条颜色 线条宽度

draw.line([begin, end], fill=cls.__gene_random_color(), width=2)

@classmethod

def __gene_points(cls, draw, point_chance, width, height):

# 大小限制

chance = min(50, max(0, int(point_chance)))

for w in range(width):

for h in range(height):

tmp = random.randint(0, 100)

if tmp > 100 - chance:

draw.point((w, h), fill=cls.__gene_random_color())

# 生成随机的颜色

@classmethod

# 起始颜色 最终颜色

def __gene_random_color(cls, start=0, end=255):

# 初始化随机数

random.seed()

# 按范围生成随机输R G  B

return (random.randint(start, end), random.randint(start, end), random.randint(start, end))

# 随机选择一个字体

@classmethod

def __gene_random_font(cls):

fonts = [

'STCAIYUN.TTF',

'STFANGSO.TTF',

'STLITI.TTF',

'framd.ttf'

]

# 随机选一个 字体

font = random.choice(fonts)

return font

# 用来随机生成一个字符串(包括英文和数字)

@classmethod

def gene_text(cls, number):

# cls.SOURCE生成list A-Z a-z 0-9 number是生成验证码的位数

return ''.join(random.sample(cls.SOURCE, number))

# 生成验证码

@classmethod

def gene_graph_captcha(cls):

# 验证码图片的宽和高

width, height = cls.size

# 创建图片

# R:Red(红色)0-255 G:G(绿色)0-255 B:B(蓝色)0-255 A:Alpha(透明度),添加了A,则就只能生成png图片

image = Image.new('RGB', (width, height), cls.__gene_random_color(0, 100))

# 验证码的字体 随机产生字体 字体大小

font = ImageFont.truetype(cls.__gene_random_font(), cls.fontsize)

# 创建画笔

draw = ImageDraw.Draw(image)

# 随机生成4为字符串

text = cls.gene_text(cls.number)

# 获取字体的尺寸

font_width, font_height = font.getsize(text)

# 填充字符串 x y坐标 文本 字体 字体颜色

draw.text(((width - font_width) / 2, (height - font_height) / 2),

text, font=font, fill=cls.__gene_random_color(150, 255))

# 绘制干扰线 绘制多少条干扰线

for x in range(0, cls.line_number):

cls.__gene_line(draw, width, height)

# 绘制噪点

cls.__gene_points(draw, 10, width, height)

return text, image

下面是我验证码对应的视图函数

from Code import Captcha

import base64 # Base64是一种任意二进制到文本字符串的编码方法,常用于在URL、Cookie、网页中传输少量二进制数据。

# 开启图片验证码

@csrf.exempt

@app.route("/Captcha", methods=["GET", "POST"])

def auth_code():

# 获取验证码图片,和验证码值

code, img = Captcha.gene_graph_captcha()

buf = BytesIO() # 构建一个输入输出流

img.save(buf, "jpeg") # 将图片保存到输入输出流,也就是内存中

bur_str = buf.getvalue() # 获得输入输出流里面的内容

# session["Code"] = code # 将验证码值存储到session中

print(str(base64.b64encode(bur_str)))

data = str(base64.b64encode(bur_str))[1:].strip("'")

return data

视图函数中我们需要把二进制数据进行编码,这里python2和python3可以有点区别,或者是我生成的图片二进制数据有和别的有点区别,我打印出来的 base64.b64encode(bur_str)是由b' '所包括的,就如下图所示

这样就导致我的img标签src链接是这样的一种情况-----> src="https://img-blog.csdnimg.cn/2022010707244887654.jpg'/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGzBQgHBwcJCQgKDBQNDAsLDBk ......' "

这样的话就导致网页上显示不了图片,但是去掉了 b' '就能正常显示图片了,所以我在视图函数中将其转换为字符串,然后切片去掉两边的单引号,最后再返回到HTML中去,

下面是我HTML中对应的img标签代码,以及Ajax代码

$("#img").click(function () {

$.ajax({

url: "/Captcha",

type: "POST",

data: {},

dataType:"text",

success: function (data) {

$("#img").attr("src","data:image/jpg;base64,"+data)

}, error: function () {

alert("没有获取返回数据");

}

});

// $.post(

// "/Captcha",{},function (data) {

// $("#img").attr("src","data:image/jpg;base64,"+data)

// }

// )

});

使用jQuery中的$.post()方法也可以实现,代码很简单,js中点击图片则就会触发Ajax,然后post请求,获取数据,使用jQuery的attr()方法替换对应img标签的src属性,这样图片就可以显示在页面中了,

这里需要注意的是,如果你Ajax获取的数据不是乱码而是正常的数据,但是就是不显示图片,你就得去看看img标签src属性是否是正确,像我就出现了上面 那样的,图片数据被 b' '

包括  然后再被双引号包括,这样就导致了显示不了图片

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值