教你使用MATLAB制作一款 图形验证码 生成器(app designer)
Posted slandarer
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了教你使用MATLAB制作一款 图形验证码 生成器(app designer)相关的知识,希望对你有一定的参考价值。
突然发现cla函数也可以应用到app designer控件上,因而对部分内容做出更改,将绘制隐藏像素刷新的方式改为用cla
原
hold(acAxes,'off');
image(acAxes,[-1,0],[-1,0],ones(1,1,3),'visible','off');
hold(acAxes,'on');
delete(findobj('tag','ax'));
新
cla(acAxes)
cla(ax)
0效果
1字符图片生成
如果我们单纯的用text绘制图形,就无法做到效果中符号和符号边缘两个颜色,也无法做到更大程度的变形,因此我们需要将字符转换为矩阵形式。
想要实现也非常简单,我们只需要创建一个不可视的fig,在其上绘制字符,保存fig为png格式图片,再通过imread读取图片,就能获得字符矩阵:
第一次运行程序因为要生成字符图片因而会比较慢,再次运行就可以读取之前已经生成过的图片啦:
% 字符图片矩阵构造 ========================================================
% 以下为字符图片创建过程
% 原理为构造隐藏的figure和axes
% 在其上用text绘制字符并保存figure为图片
% 导入图片
if ~exist('Materials','dir')
mkdir('Materials');
end
fig=figure('units','pixels',...
'position',[20 80 200 200],...
'Numbertitle','off',...
'Color',[1 1 1],...
'resize','off',...
'visible','off',...
'menubar','none');
ax=axes('Units','pixels',...
'parent',fig,...
'Color',[1 1 1],...
'Position',[0 0 200 200],...
'XLim',[0 200],...
'YLim',[0 200],...
'XColor',[1 1 1],...
'YColor',[1 1 1]);
strPic{length(strElement)}=[];
for i=1:length(strElement)
% 若是不存在该字符图片则生成,否则直接导入
if ~exist(['.\\Materials\\',strElement(i),'.png'],'file')
delete(findobj('tag','textStr'));
text(ax,100,100,strElement(i),'HorizontalAlignment',...
'center','FontSize',140,'tag','textStr','FontWeigh','bold')
saveas(fig,['.\\Materials\\',strElement(i),'.png']); % 保存图片
end
tempPic=imread(['.\\Materials\\',strElement(i),'.png']); % 读取图片
strPic{i}=imresize(tempPic,[150,150]); % 重新调整图片大小
end
2刷新按钮生成
大家可以看到这个按钮的样式与大部分按钮不同:
实际上这是一个html控件,输入html文件的位置就可以形成类似嵌入页面的效果:
acHTML=uihtml(acFigure);
acHTML.HTMLSource='.\\Materials\\textbtn.html';
acHTML.DataChangedFcn=@refresh;
acHTML.Position=[300 50 88 26];
如代码所示,我们导入的是Materials文件夹内的textbtn.html文件
textbtn.html长这样:
<!DOCTYPE html>
<html>
<head>
<meta charset=UTF-8>
<script type="text/javascript">
function setup(htmlComponent) {
document.getElementById("btnonclink").addEventListener("click", function(event) {
htmlComponent.Data="test";
});
}
</script>
</head>
<body>
<a href="" id="btnonclink">看不清?</a>
</body>
</html>
当然为了防止大家不会创建,我在m文件中写了一段能够自动创建html文件的代码,原理就是将字符串信息写入txt,再将txt文件后缀改为html:
% .html文件自动生成及引入 - - - - - - - - - - - - - - - - - - - - - - - - -
htmlContent={'<!DOCTYPE html><html><head><meta charset=UTF-8>';
'<script type="text/javascript">';
'function setup(htmlComponent){';
'document.getElementById("btnonclink").addEventListener("click",function(event){';
'htmlComponent.Data="test";});}</script></head>';
'<body><a href="" id="btnonclink">看不清?</a></body></html>'};
if ~exist('.\\Materials\\textbtn.html','file')
fid=fopen('.\\Materials\\textbtn.txt','w');
for i=1:length(htmlContent)
fprintf(fid,'%s\\r\\n',htmlContent{i});
end
fclose(fid);
copyfile('.\\Materials\\textbtn.txt','.\\Materials\\textbtn.html');
delete('.\\Materials\\textbtn.txt')
end
3图片处理
3.1图像任意方向拉伸
这部分原理就是将图像旋转一定角度后,在竖直方向进行拉伸后再旋转回去:
3.2字符边缘
这部分原理将字符均值滤波后,把不完全是黑色的部分设置为灰色,后期再设置为其他颜色:
3.3图像处理部分代码
randColor=@()randi([0,200],[1,3]); % 生成随机颜色的匿名函数
% 从图像集合中提取图像
tPic=strPic{randiNums(ii)};
tPic=tPic(:,:,1);
% 将图像旋转-拉伸-旋转
randiTheta1=randi([0,90]);
randiTheta2=randi([-30,30]);
randiLenth=randi([0,70]);
tPic=imrotate(255-tPic,randiTheta1,'bilinear','crop');
tPic=imresize(tPic,[150+randiLenth,150]);
tPic=imrotate(tPic,-randiTheta1+randiTheta2,'bilinear','crop');
% 将图像边缘进行模糊,并将模糊的部分数值设置为150
tPic=255-imfilter(tPic,I_5);
tPic(tPic~=0&tPic~=255)=150;
% 为符号和符号边缘赋予不同颜色
tempColor1=randColor();tempColor2=randColor();
tempPicR=tPic;tempPicG=tPic;tempPicB=tPic;
tempPicR(tPic==150)=tempColor1(1);tempPicR(tPic==0)=tempColor2(1);
tempPicG(tPic==150)=tempColor1(2);tempPicG(tPic==0)=tempColor2(2);
tempPicB(tPic==150)=tempColor1(3);tempPicB(tPic==0)=tempColor2(3);
tempPic_3=uint8(zeros([size(tPic),3]));
tempPic_3(:,:,1)=tempPicR;
tempPic_3(:,:,2)=tempPicG;
tempPic_3(:,:,3)=tempPicB;
4线条和散点生成
散点就是生成一堆随机位置点和一些随机颜色后用scatter函数绘制,线条是生成散点后使用’spline’插值方法插值成线后再绘制:
randColor=@()randi([0,200],[1,3]); % 生成随机颜色的匿名函数
randColor_n=@(n)randi([0,200],[n,3])./255; % 生成n个随机颜色的匿名函数
randPoint_n=@(n)[randi([5,195],[n,1]),randi([5,65],[n,1])];% 生成n个随机点的匿名函数
% 绘制散点
pPonintsNum=randi([6,10]);
pPoints=randPoint_n(pPonintsNum);
pPointsColor=randColor_n(pPonintsNum);
scatter(acAxes,pPoints(:,1),pPoints(:,2),6,'filled',...
'CData',pPointsColor,'AlphaData',0.6)
% 绘制线
lPonintsNum=randi([5,7]);
lPoints=randPoint_n(lPonintsNum);
lPointsColor=[randColor()./255,0.6];
x_lPoints=interp1(1:lPonintsNum,lPoints(:,1),1:0.01:lPonintsNum,'spline');
y_lPoints=interp1(1:lPonintsNum,lPoints(:,2),1:0.01:lPonintsNum,'spline');
plot(acAxes,x_lPoints,y_lPoints,'Color',lPointsColor,'LineWidth',1.5)
5关于图像存储
由于目前版本uifigure还不支持存储为图像,因此我们绘制图像是在figure和uifigure分别绘制一遍,其中figure依旧是不可见状态,主要用于将图片验证码保存为png格式,可以在完整代码中看出这一点。
同时,本程序的设置为,每次刷新图形验证码,都会刷新当前文件夹下authCode.png为最新的验证码,如需要保存请及时将其改名或复制另存:
6关于验证码对比
首先就是需要提取框内验证码:
codeInPut=acEditField.Value;
因为我们的验证码字符都是大写的,将输入的文本用upper函数变为大写:
codeInPut=upper(codeInPut);
同时我们因为0和O长的太像,所以不对其进行区分,直接将输入的验证码中的0改为O:
codeInPut(codeInPut=='0')='O';
之后就能够用strcmp函数将当前验证码和输入的验证码进行对比:
if strcmp(codeInPut,authCode)
msgbox('验证码正确')
else
msgbox('验证码错误')
end
7完整代码
function authCode
strElement=char([49:57,65:90]); % 1-9,A-Z的字符
randColor=@()randi([0,200],[1,3]); % 生成随机颜色的匿名函数
randColor_n=@(n)randi([0,200],[n,3])./255; % 生成n个随机颜色的匿名函数
randPoint_n=@(n)[randi([5,195],[n,1]),randi([5,65],[n,1])];% 生成n个随机点的匿名函数
global authCode; % 全局变量:验证码
% 字符图片矩阵构造 ========================================================
% 以下为字符图片创建过程
% 原理为构造隐藏的figure和axes
% 在其上用text绘制字符并保存figure为图片
% 导入图片
if ~exist('Materials','dir')
mkdir('Materials');
end
fig=figure('units','pixels',...
'position',[20 80 200 200],...
'Numbertitle','off',...
'Color',[1 1 1],...
'resize','off',...
'visible','off',...
'menubar','none');
ax=axes('Units','pixels',...
'parent',fig,...
'Color',[1 1 1],...
'Position',[0 0 200 200],...
'XLim',[0 200],...
'YLim',[0 200],...
'XColor',[1 1 1],...
'YColor',[1 1 1]);
strPic{length(strElement)}=[];
for i=1:length(strElement)
% 若是不存在该字符图片则生成,否则直接导入
if ~exist(['.\\Materials\\',strElement(i),'.png'],'file')
delete(findobj('tag','textStr'));
text(ax,100,100,strElement(i),'HorizontalAlignment',...
'center','FontSize',140,以上是关于教你使用MATLAB制作一款 图形验证码 生成器(app designer)的主要内容,如果未能解决你的问题,请参考以下文章