Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
cloud-platform
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
youjj
cloud-platform
Commits
7c873ac9
Commit
7c873ac9
authored
Dec 20, 2019
by
jiaorz
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
新增二维码
parent
ad728eb4
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
831 additions
and
0 deletions
+831
-0
CaptchaType.java
...ava/com/xxfc/platform/universal/constant/CaptchaType.java
+40
-0
CaptchaBaseParam.java
...ava/com/xxfc/platform/universal/dto/CaptchaBaseParam.java
+22
-0
ImageUtils.java
...in/java/com/xxfc/platform/universal/utils/ImageUtils.java
+54
-0
RandomUtils.java
...n/java/com/xxfc/platform/universal/utils/RandomUtils.java
+31
-0
BlockPuzzleCaptchaVO.java
.../com/xxfc/platform/universal/vo/BlockPuzzleCaptchaVO.java
+33
-0
CaptchaBaseVO.java
...in/java/com/xxfc/platform/universal/vo/CaptchaBaseVO.java
+24
-0
ClickWordCaptchaVO.java
...va/com/xxfc/platform/universal/vo/ClickWordCaptchaVO.java
+34
-0
CaptchaController.java
...xxfc/platform/universal/controller/CaptchaController.java
+52
-0
CaptchaException.java
...xxfc/platform/universal/interceptor/CaptchaException.java
+26
-0
AbstractCaptcha.java
.../com/xxfc/platform/universal/service/AbstractCaptcha.java
+105
-0
BlockPuzzleCaptcha.java
...m/xxfc/platform/universal/service/BlockPuzzleCaptcha.java
+226
-0
CaptchaFactory.java
...a/com/xxfc/platform/universal/service/CaptchaFactory.java
+22
-0
ClickWordCaptcha.java
...com/xxfc/platform/universal/service/ClickWordCaptcha.java
+147
-0
ICaptchaFactory.java
.../com/xxfc/platform/universal/service/ICaptchaFactory.java
+15
-0
No files found.
xx-universal/xx-universal-api/src/main/java/com/xxfc/platform/universal/constant/CaptchaType.java
0 → 100644
View file @
7c873ac9
package
com
.
xxfc
.
platform
.
universal
.
constant
;
/**
* 验证码类型
* @author stx
* @date 2018/11/5 11:07
* @desc
*/
public
enum
CaptchaType
{
BLOCK_PUZZLE
(
"BLOCK_PUZZLE"
,
"滑块拼图"
),
CLICK_WORD
(
"CLICK_WORD"
,
"点选文字"
),
;
private
String
name
;
private
String
desc
;
CaptchaType
(
String
name
,
String
desc
)
{
this
.
name
=
name
;
this
.
desc
=
desc
;
}
public
String
getName
()
{
return
name
;
}
public
void
setName
(
String
name
)
{
this
.
name
=
name
;
}
public
String
getDesc
()
{
return
desc
;
}
public
void
setDesc
(
String
desc
)
{
this
.
desc
=
desc
;
}
}
xx-universal/xx-universal-api/src/main/java/com/xxfc/platform/universal/dto/CaptchaBaseParam.java
0 → 100644
View file @
7c873ac9
package
com
.
xxfc
.
platform
.
universal
.
dto
;
import
java.io.Serializable
;
/**
* 基础入参对象
* @author stx
* @date 2018/11/5 16:35
* @desc
*/
public
class
CaptchaBaseParam
implements
Serializable
{
private
String
urlOrPath
;
public
String
getUrlOrPath
()
{
return
urlOrPath
;
}
public
void
setUrlOrPath
(
String
urlOrPath
)
{
this
.
urlOrPath
=
urlOrPath
;
}
}
xx-universal/xx-universal-api/src/main/java/com/xxfc/platform/universal/utils/ImageUtils.java
0 → 100644
View file @
7c873ac9
package
com
.
xxfc
.
platform
.
universal
.
utils
;
import
java.io.File
;
/**
* @author stx
* @date 2018/11/5 15:01
* @desc
*/
public
class
ImageUtils
{
public
static
String
getClickWordBgPath
(){
String
imagePath
=
"D:\\Downloads\\light_yan-captcha-master\\captcha\\images\\pic-click"
;
File
file
=
new
File
(
imagePath
);
String
[]
files
=
file
.
list
();
int
randomNum
=
RandomUtils
.
getRandomInt
(
1
,
files
.
length
);
String
path
=
files
[
randomNum
];
return
imagePath
+
"\\"
+
path
;
}
public
static
String
getBlockPuzzleBgPath
(){
String
imagePath
=
"D:\\Downloads\\light_yan-captcha-master\\captcha\\images\\jigsaw\\original"
;
File
file
=
new
File
(
imagePath
);
String
[]
files
=
file
.
list
();
int
randomNum
=
RandomUtils
.
getRandomInt
(
1
,
files
.
length
);
String
path
=
files
[
randomNum
];
return
imagePath
+
"\\"
+
path
;
}
public
static
String
getBlockPuzzleJigsawPath
(){
String
imagePath
=
"D:\\Downloads\\light_yan-captcha-master\\captcha\\images\\jigsaw\\slidingBlock"
;
File
file
=
new
File
(
imagePath
);
String
[]
files
=
file
.
list
();
int
randomNum
=
RandomUtils
.
getRandomInt
(
1
,
files
.
length
);
String
path
=
files
[
randomNum
];
return
imagePath
+
"\\"
+
path
;
}
public
static
void
main
(
String
[]
args
)
{
System
.
out
.
println
(
getBlockPuzzleBgPath
());
}
}
xx-universal/xx-universal-api/src/main/java/com/xxfc/platform/universal/utils/RandomUtils.java
0 → 100644
View file @
7c873ac9
package
com
.
xxfc
.
platform
.
universal
.
utils
;
import
java.util.Random
;
/**
* @author stx
* @date 2018/11/5 11:39
* @desc
*/
public
class
RandomUtils
{
/**
* 获取随机中文
*
* @return
*/
public
static
String
getRandomHan
(
String
hanZi
)
{
String
ch
=
hanZi
.
charAt
(
new
Random
().
nextInt
(
hanZi
.
length
()))
+
""
;
return
ch
;
}
/**
* 随机范围内数字
* @param startNum
* @param endNum
* @return
*/
public
static
Integer
getRandomInt
(
int
startNum
,
int
endNum
)
{
return
new
Random
().
nextInt
(
endNum
-
startNum
)
+
startNum
;
}
}
xx-universal/xx-universal-api/src/main/java/com/xxfc/platform/universal/vo/BlockPuzzleCaptchaVO.java
0 → 100644
View file @
7c873ac9
package
com
.
xxfc
.
platform
.
universal
.
vo
;
import
java.awt.*
;
/**
* @author stx
* @date 2018/11/5 17:15
* @desc
*/
public
class
BlockPuzzleCaptchaVO
extends
CaptchaBaseVO
{
/** 点选坐标 */
private
Point
point
;
/** 滑块图片base64 */
private
String
jigsawImageBase64
;
public
Point
getPoint
()
{
return
point
;
}
public
void
setPoint
(
Point
point
)
{
this
.
point
=
point
;
}
public
String
getJigsawImageBase64
()
{
return
jigsawImageBase64
;
}
public
void
setJigsawImageBase64
(
String
jigsawImageBase64
)
{
this
.
jigsawImageBase64
=
jigsawImageBase64
;
}
}
xx-universal/xx-universal-api/src/main/java/com/xxfc/platform/universal/vo/CaptchaBaseVO.java
0 → 100644
View file @
7c873ac9
package
com
.
xxfc
.
platform
.
universal
.
vo
;
import
java.io.Serializable
;
/**
* 验证码返回基础对象
* @author stx
* @date 2018/11/5 11:14
* @desc
*/
public
class
CaptchaBaseVO
implements
Serializable
{
/** 原生图片base64 */
private
String
originalImageBase64
;
public
String
getOriginalImageBase64
()
{
return
originalImageBase64
;
}
public
void
setOriginalImageBase64
(
String
originalImageBase64
)
{
this
.
originalImageBase64
=
originalImageBase64
;
}
}
xx-universal/xx-universal-api/src/main/java/com/xxfc/platform/universal/vo/ClickWordCaptchaVO.java
0 → 100644
View file @
7c873ac9
package
com
.
xxfc
.
platform
.
universal
.
vo
;
import
java.awt.*
;
import
java.util.List
;
/**
* @author stx
* @date 2018/11/5 16:27
* @desc
*/
public
class
ClickWordCaptchaVO
extends
CaptchaBaseVO
{
/** 点选文字 */
private
List
<
String
>
wordList
;
/** 点选坐标 */
private
List
<
Point
>
pointList
;
public
List
<
String
>
getWordList
()
{
return
wordList
;
}
public
void
setWordList
(
List
<
String
>
wordList
)
{
this
.
wordList
=
wordList
;
}
public
List
<
Point
>
getPointList
()
{
return
pointList
;
}
public
void
setPointList
(
List
<
Point
>
pointList
)
{
this
.
pointList
=
pointList
;
}
}
xx-universal/xx-universal-server/src/main/java/com/xxfc/platform/universal/controller/CaptchaController.java
0 → 100644
View file @
7c873ac9
package
com
.
xxfc
.
platform
.
universal
.
controller
;
import
com.github.wxiaoqi.security.common.msg.ObjectRestResponse
;
import
com.xxfc.platform.universal.constant.CaptchaType
;
import
com.xxfc.platform.universal.dto.CaptchaBaseParam
;
import
com.xxfc.platform.universal.service.AbstractCaptcha
;
import
com.xxfc.platform.universal.service.CaptchaFactory
;
import
com.xxfc.platform.universal.service.ICaptchaFactory
;
import
com.xxfc.platform.universal.utils.ImageUtils
;
import
com.xxfc.platform.universal.vo.CaptchaBaseVO
;
import
org.springframework.stereotype.Controller
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.ResponseBody
;
/**
* @author stx
* @date 2018/11/5 14:58
* @desc
*/
@Controller
@RequestMapping
(
value
=
"/captcha"
)
public
class
CaptchaController
{
@RequestMapping
(
"/app/unauth/blockPuzzle"
)
@ResponseBody
ObjectRestResponse
blockPuzzle
()
{
ICaptchaFactory
captchaFactory
=
new
CaptchaFactory
();
AbstractCaptcha
captcha
=
captchaFactory
.
getInstance
(
CaptchaType
.
BLOCK_PUZZLE
);
CaptchaBaseParam
captchaBaseParam
=
new
CaptchaBaseParam
();
captchaBaseParam
.
setUrlOrPath
(
ImageUtils
.
getBlockPuzzleBgPath
());
captcha
.
setJigsawUrlOrPath
(
ImageUtils
.
getBlockPuzzleJigsawPath
());
CaptchaBaseVO
dataVO
=
captcha
.
create
(
captchaBaseParam
);
return
ObjectRestResponse
.
succ
(
dataVO
);
}
@RequestMapping
(
"/app/unauth/clickWord"
)
@ResponseBody
ObjectRestResponse
clickWord
()
{
ICaptchaFactory
captchaFactory
=
new
CaptchaFactory
();
AbstractCaptcha
captcha
=
captchaFactory
.
getInstance
(
CaptchaType
.
CLICK_WORD
);
CaptchaBaseParam
captchaBaseParam
=
new
CaptchaBaseParam
();
captchaBaseParam
.
setUrlOrPath
(
ImageUtils
.
getClickWordBgPath
());
captcha
.
setFontColorRandom
(
false
);
CaptchaBaseVO
dataVO
=
captcha
.
create
(
captchaBaseParam
);
return
ObjectRestResponse
.
succ
(
dataVO
);
}
}
xx-universal/xx-universal-server/src/main/java/com/xxfc/platform/universal/interceptor/CaptchaException.java
0 → 100644
View file @
7c873ac9
package
com
.
xxfc
.
platform
.
universal
.
interceptor
;
/**
* @author stx
* @date 2018/11/5 11:15
* @desc
*/
public
class
CaptchaException
extends
RuntimeException
{
private
static
final
long
serialVersionUID
=
5950168740799888303L
;
public
CaptchaException
(){
super
();
}
public
CaptchaException
(
String
message
){
super
(
message
);
}
public
CaptchaException
(
String
message
,
Throwable
cause
){
super
(
message
,
cause
);
}
public
CaptchaException
(
Throwable
cause
){
super
(
cause
);
}
}
xx-universal/xx-universal-server/src/main/java/com/xxfc/platform/universal/service/AbstractCaptcha.java
0 → 100644
View file @
7c873ac9
package
com
.
xxfc
.
platform
.
universal
.
service
;
import
com.xxfc.platform.universal.dto.CaptchaBaseParam
;
import
com.xxfc.platform.universal.interceptor.CaptchaException
;
import
com.xxfc.platform.universal.vo.CaptchaBaseVO
;
import
org.apache.commons.lang3.StringUtils
;
import
sun.misc.BASE64Encoder
;
import
javax.imageio.ImageIO
;
import
java.awt.*
;
import
java.awt.image.BufferedImage
;
import
java.io.ByteArrayOutputStream
;
import
java.io.File
;
import
java.io.IOException
;
import
java.net.URL
;
import
java.util.List
;
/**
* 图行验证码抽象方法
* @author stx
* @date 2018/10/26 22:19
* @desc
*/
public
abstract
class
AbstractCaptcha
{
protected
static
final
String
URL_PREFIX_HTTP
=
"http://"
;
protected
static
final
String
URL_PREFIX_HTTPS
=
"https://"
;
protected
static
final
String
IMAGE_TYPE_PNG
=
"png"
;
/** 滑块拼图图片地址 */
private
String
jigsawUrlOrPath
;
/** 点选文字 字体总个数 */
private
int
wordTotalCount
=
4
;
/** 点选文字 字体颜色是否随机 */
private
boolean
fontColorRandom
=
Boolean
.
TRUE
;
public
abstract
CaptchaBaseVO
create
(
CaptchaBaseParam
captchaParam
);
public
abstract
boolean
verification
(
List
<
Point
>
pointList
,
List
<
Point
>
pointList1
);
/**
*
* 获取原生图片
* @param urlOrPath
* @return
*/
protected
static
BufferedImage
getBufferedImage
(
String
urlOrPath
)
{
if
(
StringUtils
.
isBlank
(
urlOrPath
))
{
throw
new
CaptchaException
(
"urlOrPath is empty."
);
}
BufferedImage
sampleImage
=
null
;
try
{
if
(
urlOrPath
.
startsWith
(
URL_PREFIX_HTTP
)
||
urlOrPath
.
startsWith
(
URL_PREFIX_HTTPS
))
{
sampleImage
=
ImageIO
.
read
(
new
URL
(
urlOrPath
));
}
else
{
sampleImage
=
ImageIO
.
read
(
new
File
(
urlOrPath
));
}
}
catch
(
IOException
e
){
throw
new
CaptchaException
(
"urlOrPath is url or path error."
);
}
// todo 可以考虑验证下尺寸 300 * 155
return
sampleImage
;
}
/**
* 图片转base64 字符串
* @param templateImage
* @return
*/
protected
String
getImageToBase64Str
(
BufferedImage
templateImage
){
ByteArrayOutputStream
baos
=
new
ByteArrayOutputStream
();
try
{
ImageIO
.
write
(
templateImage
,
"jpg"
,
baos
);
}
catch
(
IOException
e
)
{
throw
new
CaptchaException
(
"ImageIO.write is error"
,
e
);
}
byte
[]
bytes
=
baos
.
toByteArray
();
BASE64Encoder
encoder
=
new
BASE64Encoder
();
return
encoder
.
encodeBuffer
(
bytes
).
trim
();
}
public
String
getJigsawUrlOrPath
()
{
return
jigsawUrlOrPath
;
}
public
void
setJigsawUrlOrPath
(
String
jigsawUrlOrPath
)
{
this
.
jigsawUrlOrPath
=
jigsawUrlOrPath
;
}
public
int
getWordTotalCount
()
{
return
wordTotalCount
;
}
public
void
setWordTotalCount
(
int
wordTotalCount
)
{
this
.
wordTotalCount
=
wordTotalCount
;
}
public
boolean
isFontColorRandom
()
{
return
fontColorRandom
;
}
public
void
setFontColorRandom
(
boolean
fontColorRandom
)
{
this
.
fontColorRandom
=
fontColorRandom
;
}
}
xx-universal/xx-universal-server/src/main/java/com/xxfc/platform/universal/service/BlockPuzzleCaptcha.java
0 → 100644
View file @
7c873ac9
package
com
.
xxfc
.
platform
.
universal
.
service
;
import
com.alibaba.fastjson.JSON
;
import
com.xxfc.platform.universal.dto.CaptchaBaseParam
;
import
com.xxfc.platform.universal.interceptor.CaptchaException
;
import
com.xxfc.platform.universal.vo.BlockPuzzleCaptchaVO
;
import
com.xxfc.platform.universal.vo.CaptchaBaseVO
;
import
org.apache.commons.lang3.StringUtils
;
import
sun.misc.BASE64Encoder
;
import
javax.imageio.ImageIO
;
import
java.awt.*
;
import
java.awt.image.BufferedImage
;
import
java.io.ByteArrayOutputStream
;
import
java.util.List
;
import
java.util.Random
;
/**
* 滑块拼图验证码
* @author stx
* @date 2018/11/5 11:12
* @desc
*/
public
class
BlockPuzzleCaptcha
extends
AbstractCaptcha
{
@Override
public
CaptchaBaseVO
create
(
CaptchaBaseParam
captchaParam
)
{
if
(
captchaParam
==
null
||
StringUtils
.
isBlank
(
captchaParam
.
getUrlOrPath
()))
{
throw
new
CaptchaException
(
"参数不正确,captchaParam:"
+
JSON
.
toJSONString
(
captchaParam
));
}
if
(
StringUtils
.
isBlank
(
getJigsawUrlOrPath
())){
throw
new
CaptchaException
(
"参数不正确,请设置jigsawUrlOrPath 参数"
);
}
//原生图片
BufferedImage
originalImage
=
getBufferedImage
(
captchaParam
.
getUrlOrPath
());
//抠图图片
BufferedImage
jigsawImage
=
getBufferedImage
(
getJigsawUrlOrPath
());
return
pictureTemplatesCut
(
originalImage
,
jigsawImage
);
}
@Override
public
boolean
verification
(
List
<
Point
>
pointList
,
List
<
Point
>
pointList1
)
{
return
false
;
}
/**
* 根据模板切图
*
* @throws Exception
*/
public
static
CaptchaBaseVO
pictureTemplatesCut
(
BufferedImage
originalImage
,
BufferedImage
jigsawImage
){
try
{
BlockPuzzleCaptchaVO
dataVO
=
new
BlockPuzzleCaptchaVO
();
int
originalWidth
=
originalImage
.
getWidth
();
int
originalHeight
=
originalImage
.
getHeight
();
int
jigsawWidth
=
jigsawImage
.
getWidth
();
int
jigsawHeight
=
jigsawImage
.
getHeight
();
//随机生成拼图坐标
Point
point
=
generateJigsawPoint
(
originalWidth
,
originalHeight
,
jigsawWidth
,
jigsawHeight
);
int
x
=
(
int
)
point
.
getX
();
int
y
=
(
int
)
point
.
getY
();
//生成新的拼图图像
BufferedImage
newJigsawImage
=
new
BufferedImage
(
jigsawWidth
,
jigsawHeight
,
jigsawImage
.
getType
());
Graphics2D
graphics
=
newJigsawImage
.
createGraphics
();
graphics
.
setBackground
(
Color
.
white
);
int
bold
=
5
;
BufferedImage
subImage
=
originalImage
.
getSubimage
(
x
,
0
,
jigsawWidth
,
jigsawHeight
);
// 获取拼图区域
newJigsawImage
=
DealCutPictureByTemplate
(
subImage
,
jigsawImage
,
newJigsawImage
);
// 设置“抗锯齿”的属性
graphics
.
setRenderingHint
(
RenderingHints
.
KEY_ANTIALIASING
,
RenderingHints
.
VALUE_ANTIALIAS_ON
);
graphics
.
setStroke
(
new
BasicStroke
(
bold
,
BasicStroke
.
CAP_BUTT
,
BasicStroke
.
JOIN_BEVEL
));
graphics
.
drawImage
(
newJigsawImage
,
0
,
0
,
null
);
graphics
.
dispose
();
ByteArrayOutputStream
os
=
new
ByteArrayOutputStream
();
//新建流。
ImageIO
.
write
(
newJigsawImage
,
IMAGE_TYPE_PNG
,
os
);
//利用ImageIO类提供的write方法,将bi以png图片的数据模式写入流。
byte
[]
jigsawImages
=
os
.
toByteArray
();
// 源图生成遮罩
byte
[]
oriCopyImages
=
DealOriPictureByTemplate
(
originalImage
,
jigsawImage
,
x
,
0
);
BASE64Encoder
encoder
=
new
BASE64Encoder
();
dataVO
.
setOriginalImageBase64
(
encoder
.
encode
(
oriCopyImages
));
dataVO
.
setPoint
(
point
);
dataVO
.
setJigsawImageBase64
(
encoder
.
encode
(
jigsawImages
));
return
dataVO
;
}
catch
(
Exception
e
){
throw
new
CaptchaException
(
e
);
}
}
/**
* 抠图后原图生成
*
* @param oriImage
* @param templateImage
* @param x
* @param y
* @return
* @throws Exception
*/
private
static
byte
[]
DealOriPictureByTemplate
(
BufferedImage
oriImage
,
BufferedImage
templateImage
,
int
x
,
int
y
)
throws
Exception
{
// 源文件备份图像矩阵 支持alpha通道的rgb图像
BufferedImage
ori_copy_image
=
new
BufferedImage
(
oriImage
.
getWidth
(),
oriImage
.
getHeight
(),
BufferedImage
.
TYPE_4BYTE_ABGR
);
// 源文件图像矩阵
int
[][]
oriImageData
=
getData
(
oriImage
);
// 模板图像矩阵
int
[][]
templateImageData
=
getData
(
templateImage
);
//copy 源图做不透明处理
for
(
int
i
=
0
;
i
<
oriImageData
.
length
;
i
++)
{
for
(
int
j
=
0
;
j
<
oriImageData
[
0
].
length
;
j
++)
{
int
rgb
=
oriImage
.
getRGB
(
i
,
j
);
int
r
=
(
0xff
&
rgb
);
int
g
=
(
0xff
&
(
rgb
>>
8
));
int
b
=
(
0xff
&
(
rgb
>>
16
));
//无透明处理
rgb
=
r
+
(
g
<<
8
)
+
(
b
<<
16
)
+
(
255
<<
24
);
ori_copy_image
.
setRGB
(
i
,
j
,
rgb
);
}
}
for
(
int
i
=
0
;
i
<
templateImageData
.
length
;
i
++)
{
for
(
int
j
=
0
;
j
<
templateImageData
[
0
].
length
-
5
;
j
++)
{
int
rgb
=
templateImage
.
getRGB
(
i
,
j
);
//对源文件备份图像(x+i,y+j)坐标点进行透明处理
if
(
rgb
!=
16777215
&&
rgb
<=
0
)
{
int
rgb_ori
=
ori_copy_image
.
getRGB
(
x
+
i
,
y
+
j
);
int
r
=
(
0xff
&
rgb_ori
);
int
g
=
(
0xff
&
(
rgb_ori
>>
8
));
int
b
=
(
0xff
&
(
rgb_ori
>>
16
));
rgb_ori
=
r
+
(
g
<<
8
)
+
(
b
<<
16
)
+
(
150
<<
24
);
ori_copy_image
.
setRGB
(
x
+
i
,
y
+
j
,
rgb_ori
);
}
else
{
//do nothing
}
}
}
ByteArrayOutputStream
os
=
new
ByteArrayOutputStream
();
//新建流。
ImageIO
.
write
(
ori_copy_image
,
"png"
,
os
);
//利用ImageIO类提供的write方法,将bi以png图片的数据模式写入流。
byte
b
[]
=
os
.
toByteArray
();
//从流中获取数据数组。
return
b
;
}
/**
* 根据模板图片抠图
* @param oriImage
* @param templateImage
* @param targetImage
* @return
* @throws Exception
*/
private
static
BufferedImage
DealCutPictureByTemplate
(
BufferedImage
oriImage
,
BufferedImage
templateImage
,
BufferedImage
targetImage
)
throws
Exception
{
// 源文件图像矩阵
int
[][]
oriImageData
=
getData
(
oriImage
);
// 模板图像矩阵
int
[][]
templateImageData
=
getData
(
templateImage
);
// 模板图像宽度
for
(
int
i
=
0
;
i
<
templateImageData
.
length
;
i
++)
{
// 模板图片高度
for
(
int
j
=
0
;
j
<
templateImageData
[
0
].
length
;
j
++)
{
// 如果模板图像当前像素点不是白色 copy源文件信息到目标图片中
int
rgb
=
templateImageData
[
i
][
j
];
if
(
rgb
!=
16777215
&&
rgb
<=
0
)
{
targetImage
.
setRGB
(
i
,
j
,
oriImageData
[
i
][
j
]);
}
}
}
return
targetImage
;
}
/**
* 生成图像矩阵
* @param
* @return
* @throws Exception
*/
private
static
int
[][]
getData
(
BufferedImage
bimg
){
int
[][]
data
=
new
int
[
bimg
.
getWidth
()][
bimg
.
getHeight
()];
for
(
int
i
=
0
;
i
<
bimg
.
getWidth
();
i
++)
{
for
(
int
j
=
0
;
j
<
bimg
.
getHeight
();
j
++)
{
data
[
i
][
j
]
=
bimg
.
getRGB
(
i
,
j
);
}
}
return
data
;
}
/**
* 随机生成拼图坐标
* @param originalWidth
* @param originalHeight
* @param jigsawWidth
* @param jigsawHeight
* @return
*/
private
static
Point
generateJigsawPoint
(
int
originalWidth
,
int
originalHeight
,
int
jigsawWidth
,
int
jigsawHeight
)
{
Random
random
=
new
Random
();
int
widthDifference
=
originalWidth
-
jigsawWidth
;
int
heightDifference
=
originalHeight
-
jigsawHeight
;
int
x
,
y
=
0
;
if
(
widthDifference
<=
0
)
{
x
=
5
;
}
else
{
x
=
random
.
nextInt
(
originalWidth
-
jigsawWidth
)
+
5
;
}
if
(
heightDifference
<=
0
)
{
y
=
5
;
}
else
{
y
=
random
.
nextInt
(
originalHeight
-
jigsawHeight
)
+
5
;
}
return
new
Point
(
x
,
y
);
}
}
xx-universal/xx-universal-server/src/main/java/com/xxfc/platform/universal/service/CaptchaFactory.java
0 → 100644
View file @
7c873ac9
package
com
.
xxfc
.
platform
.
universal
.
service
;
import
com.xxfc.platform.universal.constant.CaptchaType
;
/**
* @author stx
* @date 2018/11/5 11:11
* @desc
*/
public
class
CaptchaFactory
implements
ICaptchaFactory
{
@Override
public
AbstractCaptcha
getInstance
(
CaptchaType
captchaType
)
{
if
(
CaptchaType
.
CLICK_WORD
.
getName
().
equals
(
captchaType
.
getName
())){
return
new
ClickWordCaptcha
();
}
else
if
(
CaptchaType
.
BLOCK_PUZZLE
.
getName
().
equals
(
captchaType
.
getName
()))
{
return
new
BlockPuzzleCaptcha
();
}
return
null
;
}
}
xx-universal/xx-universal-server/src/main/java/com/xxfc/platform/universal/service/ClickWordCaptcha.java
0 → 100644
View file @
7c873ac9
package
com
.
xxfc
.
platform
.
universal
.
service
;
import
com.alibaba.fastjson.JSON
;
import
com.xxfc.platform.universal.dto.CaptchaBaseParam
;
import
com.xxfc.platform.universal.interceptor.CaptchaException
;
import
com.xxfc.platform.universal.utils.RandomUtils
;
import
com.xxfc.platform.universal.vo.CaptchaBaseVO
;
import
com.xxfc.platform.universal.vo.ClickWordCaptchaVO
;
import
org.apache.commons.lang3.StringUtils
;
import
java.awt.*
;
import
java.awt.geom.AffineTransform
;
import
java.awt.image.BufferedImage
;
import
java.util.ArrayList
;
import
java.util.HashSet
;
import
java.util.List
;
import
java.util.Set
;
/**
* 点选文字验证码
* @author stx
* @date 2018/11/5 11:13
* @desc
*/
public
class
ClickWordCaptcha
extends
AbstractCaptcha
{
private
static
String
HAN_ZI
=
"\u7684\u4e00\u4e86\u662f\u6211\u4e0d\u5728\u4eba\u4eec\u6709\u6765\u4ed6\u8fd9\u4e0a\u7740\u4e2a\u5730\u5230\u5927\u91cc\u8bf4\u5c31\u53bb\u5b50\u5f97\u4e5f\u548c\u90a3\u8981\u4e0b\u770b\u5929\u65f6\u8fc7\u51fa\u5c0f\u4e48\u8d77\u4f60\u90fd\u628a\u597d\u8fd8\u591a\u6ca1\u4e3a\u53c8\u53ef\u5bb6\u5b66\u53ea\u4ee5\u4e3b\u4f1a\u6837\u5e74\u60f3\u751f\u540c\u8001\u4e2d\u5341\u4ece\u81ea\u9762\u524d\u5934\u9053\u5b83\u540e\u7136\u8d70\u5f88\u50cf\u89c1\u4e24\u7528\u5979\u56fd\u52a8\u8fdb\u6210\u56de\u4ec0\u8fb9\u4f5c\u5bf9\u5f00\u800c\u5df1\u4e9b\u73b0\u5c71\u6c11\u5019\u7ecf\u53d1\u5de5\u5411\u4e8b\u547d\u7ed9\u957f\u6c34\u51e0\u4e49\u4e09\u58f0\u4e8e\u9ad8\u624b\u77e5\u7406\u773c\u5fd7\u70b9\u5fc3\u6218\u4e8c\u95ee\u4f46\u8eab\u65b9\u5b9e\u5403\u505a\u53eb\u5f53\u4f4f\u542c\u9769\u6253\u5462\u771f\u5168\u624d\u56db\u5df2\u6240\u654c\u4e4b\u6700\u5149\u4ea7\u60c5\u8def\u5206\u603b\u6761\u767d\u8bdd\u4e1c\u5e2d\u6b21\u4eb2\u5982\u88ab\u82b1\u53e3\u653e\u513f\u5e38\u6c14\u4e94\u7b2c\u4f7f\u5199\u519b\u5427\u6587\u8fd0\u518d\u679c\u600e\u5b9a\u8bb8\u5feb\u660e\u884c\u56e0\u522b\u98de\u5916\u6811\u7269\u6d3b\u90e8\u95e8\u65e0\u5f80\u8239\u671b\u65b0\u5e26\u961f\u5148\u529b\u5b8c\u5374\u7ad9\u4ee3\u5458\u673a\u66f4\u4e5d\u60a8\u6bcf\u98ce\u7ea7\u8ddf\u7b11\u554a\u5b69\u4e07\u5c11\u76f4\u610f\u591c\u6bd4\u9636\u8fde\u8f66\u91cd\u4fbf\u6597\u9a6c\u54ea\u5316\u592a\u6307\u53d8\u793e\u4f3c\u58eb\u8005\u5e72\u77f3\u6ee1\u65e5\u51b3\u767e\u539f\u62ff\u7fa4\u7a76\u5404\u516d\u672c\u601d\u89e3\u7acb\u6cb3\u6751\u516b\u96be\u65e9\u8bba\u5417\u6839\u5171\u8ba9\u76f8\u7814\u4eca\u5176\u4e66\u5750\u63a5\u5e94\u5173\u4fe1\u89c9\u6b65\u53cd\u5904\u8bb0\u5c06\u5343\u627e\u4e89\u9886\u6216\u5e08\u7ed3\u5757\u8dd1\u8c01\u8349\u8d8a\u5b57\u52a0\u811a\u7d27\u7231\u7b49\u4e60\u9635\u6015\u6708\u9752\u534a\u706b\u6cd5\u9898\u5efa\u8d76\u4f4d\u5531\u6d77\u4e03\u5973\u4efb\u4ef6\u611f\u51c6\u5f20\u56e2\u5c4b\u79bb\u8272\u8138\u7247\u79d1\u5012\u775b\u5229\u4e16\u521a\u4e14\u7531\u9001\u5207\u661f\u5bfc\u665a\u8868\u591f\u6574\u8ba4\u54cd\u96ea\u6d41\u672a\u573a\u8be5\u5e76\u5e95\u6df1\u523b\u5e73\u4f1f\u5fd9\u63d0\u786e\u8fd1\u4eae\u8f7b\u8bb2\u519c\u53e4\u9ed1\u544a\u754c\u62c9\u540d\u5440\u571f\u6e05\u9633\u7167\u529e\u53f2\u6539\u5386\u8f6c\u753b\u9020\u5634\u6b64\u6cbb\u5317\u5fc5\u670d\u96e8\u7a7f\u5185\u8bc6\u9a8c\u4f20\u4e1a\u83dc\u722c\u7761\u5174\u5f62\u91cf\u54b1\u89c2\u82e6\u4f53\u4f17\u901a\u51b2\u5408\u7834\u53cb\u5ea6\u672f\u996d\u516c\u65c1\u623f\u6781\u5357\u67aa\u8bfb\u6c99\u5c81\u7ebf\u91ce\u575a\u7a7a\u6536\u7b97\u81f3\u653f\u57ce\u52b3\u843d\u94b1\u7279\u56f4\u5f1f\u80dc\u6559\u70ed\u5c55\u5305\u6b4c\u7c7b\u6e10\u5f3a\u6570\u4e61\u547c\u6027\u97f3\u7b54\u54e5\u9645\u65e7\u795e\u5ea7\u7ae0\u5e2e\u5566\u53d7\u7cfb\u4ee4\u8df3\u975e\u4f55\u725b\u53d6\u5165\u5cb8\u6562\u6389\u5ffd\u79cd\u88c5\u9876\u6025\u6797\u505c\u606f\u53e5\u533a\u8863\u822c\u62a5\u53f6\u538b\u6162\u53d4\u80cc\u7ec6"
;
private
static
String
HAN_ZI_FONT
=
"宋体"
;
private
static
int
HAN_ZI_SIZE
=
30
;
private
static
int
HAN_ZI_SIZE_HALF
=
30
/
2
;
@Override
public
CaptchaBaseVO
create
(
CaptchaBaseParam
captchaParam
)
{
if
(
captchaParam
==
null
||
StringUtils
.
isBlank
(
captchaParam
.
getUrlOrPath
()))
{
throw
new
CaptchaException
(
"参数不正确,captchaParam:"
+
JSON
.
toJSONString
(
captchaParam
));
}
BufferedImage
bufferedImage
=
getBufferedImage
(
captchaParam
.
getUrlOrPath
());
return
getImageData
(
bufferedImage
);
}
@Override
public
boolean
verification
(
List
<
Point
>
pointList
,
List
<
Point
>
pointList1
)
{
if
(
pointList
==
null
||
pointList1
==
null
||
pointList
.
size
()
==
0
||
pointList
.
size
()
!=
pointList1
.
size
())
{
throw
new
CaptchaException
(
"点选文字验证码坐标信息为空或者不相等,pointList:"
+
JSON
.
toJSON
(
pointList
)+
",pointList1:"
+
JSON
.
toJSONString
(
pointList1
));
}
for
(
int
i
=
0
;
i
<
pointList
.
size
();
i
++){
Point
point
=
pointList
.
get
(
i
);
Point
point1
=
pointList1
.
get
(
i
);
int
x
=
(
int
)
point
.
getX
();
int
y
=
(
int
)
point
.
getY
();
int
x1
=
(
int
)
point1
.
getX
();
int
y1
=
(
int
)
point1
.
getY
();
if
(
Math
.
abs
(
x
-
x1
)
>=
HAN_ZI_SIZE_HALF
||
Math
.
abs
(
y
-
y1
)
>=
HAN_ZI_SIZE_HALF
){
return
false
;
}
}
return
false
;
}
private
CaptchaBaseVO
getImageData
(
BufferedImage
backgroundImage
)
{
ClickWordCaptchaVO
dataVO
=
new
ClickWordCaptchaVO
();
List
<
String
>
wordList
=
new
ArrayList
<
String
>();
List
<
Point
>
pointList
=
new
ArrayList
();
Graphics
backgroundGraphics
=
backgroundImage
.
getGraphics
();
int
width
=
backgroundImage
.
getWidth
();
int
height
=
backgroundImage
.
getHeight
();
Font
font
=
new
Font
(
HAN_ZI_FONT
,
Font
.
BOLD
,
HAN_ZI_SIZE
);
int
wordCount
=
getWordTotalCount
();
//定义随机1到arr.length某一个字不参与校验
int
num
=
RandomUtils
.
getRandomInt
(
1
,
wordCount
);
Set
<
String
>
currentWords
=
new
HashSet
<
String
>();
for
(
int
i
=
0
;
i
<
wordCount
;
i
++)
{
String
word
;
do
{
word
=
RandomUtils
.
getRandomHan
(
HAN_ZI
);
currentWords
.
add
(
word
);
}
while
(!
currentWords
.
contains
(
word
));
//随机字体坐标
Point
point
=
randomWordPoint
(
width
,
height
,
i
,
wordCount
);
//随机字体颜色
if
(
isFontColorRandom
()){
backgroundGraphics
.
setColor
(
new
Color
(
RandomUtils
.
getRandomInt
(
1
,
255
),
RandomUtils
.
getRandomInt
(
1
,
255
),
RandomUtils
.
getRandomInt
(
1
,
255
)));
}
else
{
backgroundGraphics
.
setColor
(
Color
.
BLACK
);
}
//设置角度
AffineTransform
affineTransform
=
new
AffineTransform
();
affineTransform
.
rotate
(
Math
.
toRadians
(
RandomUtils
.
getRandomInt
(
50
,
85
)),
0
,
0
);
Font
rotatedFont
=
font
.
deriveFont
(
affineTransform
);
backgroundGraphics
.
setFont
(
rotatedFont
);
backgroundGraphics
.
drawString
(
word
,
(
int
)
point
.
getX
(),
(
int
)
point
.
getY
());
if
((
num
-
1
)
!=
i
)
{
wordList
.
add
(
word
);
pointList
.
add
(
point
);
}
}
//创建合并图片
BufferedImage
combinedImage
=
new
BufferedImage
(
width
,
height
,
BufferedImage
.
TYPE_INT_RGB
);
Graphics
combinedGraphics
=
combinedImage
.
getGraphics
();
combinedGraphics
.
drawImage
(
backgroundImage
,
0
,
0
,
null
);
dataVO
.
setOriginalImageBase64
(
getImageToBase64Str
(
backgroundImage
));
dataVO
.
setPointList
(
pointList
);
dataVO
.
setWordList
(
wordList
);
return
dataVO
;
}
/**
* 随机字体循环排序下标
* @param imageWidth 图片宽度
* @param imageHeight 图片高度
* @param wordSortIndex 字体循环排序下标(i)
* @param wordCount 字数量
* @return
*/
private
static
Point
randomWordPoint
(
int
imageWidth
,
int
imageHeight
,
int
wordSortIndex
,
int
wordCount
)
{
int
avgWidth
=
imageWidth
/
(
wordCount
+
1
);
int
x
,
y
;
if
(
avgWidth
<
HAN_ZI_SIZE_HALF
){
x
=
RandomUtils
.
getRandomInt
(
1
,
imageWidth
);
}
else
{
if
(
wordSortIndex
==
0
)
{
x
=
RandomUtils
.
getRandomInt
(
1
,
avgWidth
*
(
wordSortIndex
+
1
)
);
}
else
{
x
=
RandomUtils
.
getRandomInt
(
avgWidth
*
wordSortIndex
,
avgWidth
*
(
wordSortIndex
+
1
)
);
}
}
y
=
RandomUtils
.
getRandomInt
(
1
,
imageHeight
-
HAN_ZI_SIZE_HALF
);
return
new
Point
(
x
,
y
);
}
}
xx-universal/xx-universal-server/src/main/java/com/xxfc/platform/universal/service/ICaptchaFactory.java
0 → 100644
View file @
7c873ac9
package
com
.
xxfc
.
platform
.
universal
.
service
;
import
com.xxfc.platform.universal.constant.CaptchaType
;
/**
* 获取验证码实例工厂类
* @author stx
* @date 2018/11/5 11:06
* @desc
*/
public
interface
ICaptchaFactory
{
AbstractCaptcha
getInstance
(
CaptchaType
captchaType
);
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment