实现:
可以参考官方文档:
https://avatars.dicebear.com/docs/http-api
具体api案例:
https://avatars.dicebear.com/api/male/1.svg
https://avatars.dicebear.com/api/avataaars/2.svg
https://avatars.dicebear.com/api/bottts/3.svg
https://avatars.dicebear.com/api/croodles/一.svg
https://avatars.dicebear.com/api/gridy/二.svg
https://avatars.dicebear.com/api/human/三.svg
https://avatars.dicebear.com/api/jdenticon/jeden.svg
当然还可以控制头像的一些属性,比如发型,肤色,鼻子,嘴巴等
具体可以参考:
https://avatars.dicebear.com/styles/avataaars
具体运用到实战:
首先是需要调这个第三方的api接口,它会返回给你一串字符串,我们拿到字符串,写入文件,注意后缀要以.svg结尾,否则这个图片无法查看。(一般区块链的图片,上链的大多都是svg文件)
然后我们需要将这个图片给前端展示,这里就需要将svg转成jpg(苹果前端和苹果前端也是可以处理的,不过比较麻烦,这里就需要我们处理一下)。
接着将图片转成jpg之后,还需要将它上传到图片存储服务器上,这里我以AWS的S3为例。
最后jpg图片上传成功以后,需要清理之前在服务器上生成的svg和jpg文件。
* @Description newsContentPicture为需要生成图片的内容
* @Author zhiwei Liao
* @Date 2021/9/14 16:28
@Override
public
String
uploadNewsContentPictureS3
(
String
newsContentPicture
)
throws
Exception
{
String
osName
=
System
.
getProperties
(
)
.
getProperty
(
"os.name"
)
;
String
svgPath
=
null
;
String
jpgPath
=
null
;
URL
url
=
null
;
log
.
info
(
"========操作系统:"
+
osName
)
;
String
fileName
=
String
.
valueOf
(
System
.
currentTimeMillis
(
)
)
;
if
(
osName
.
contains
(
"Linux"
)
)
{
svgPath
=
linuxSvgPath
+
fileName
+
".svg"
;
jpgPath
=
linuxJpgPath
+
fileName
+
".jpg"
;
}
else
if
(
osName
.
contains
(
"Windows"
)
)
{
svgPath
=
System
.
getProperty
(
"user.dir"
)
+
"\\svg\\"
+
fileName
+
".svg"
;
jpgPath
=
System
.
getProperty
(
"user.dir"
)
+
"\\jpg\\"
+
fileName
+
".jpg"
;
File
svgFile
=
readIoStringToFile
(
newsContentPicture
,
svgPath
)
;
if
(
svgFile
!=
null
)
{
File
jpgFile
=
SVGConverterUtils
.
svgFileChangeJpg
(
svgFile
,
jpgPath
)
;
if
(
jpgFile
!=
null
)
{
AWSCredentials
awsCredentials
=
new
BasicAWSCredentials
(
accessKey
,
secretKey
)
;
AmazonS3
s3Client
=
AmazonS3ClientBuilder
.
standard
(
)
.
withRegion
(
clientRegion
)
.
withCredentials
(
new
AWSStaticCredentialsProvider
(
awsCredentials
)
)
.
build
(
)
;
PutObjectRequest
request
=
new
PutObjectRequest
(
bucketName
,
fileName
,
jpgFile
)
;
ObjectMetadata
metadata
=
new
ObjectMetadata
(
)
;
metadata
.
addUserMetadata
(
"x-amz-meta-title"
,
"someTitle"
)
;
request
.
setMetadata
(
metadata
)
;
request
.
setKey
(
fileName
)
;
s3Client
.
putObject
(
request
)
;
url
=
s3Client
.
getUrl
(
bucketName
,
fileName
)
;
if
(
svgFile
.
exists
(
)
)
{
svgFile
.
delete
(
)
;
if
(
jpgFile
.
exists
(
)
)
{
jpgFile
.
delete
(
)
;
return
url
.
toString
(
)
;
* 把IO字符串输出到文件
* @param ioString
* @param filePath
public
static
File
readIoStringToFile
(
String
ioString
,
String
filePath
)
{
log
.
info
(
"========readIoStringToFile.filePath:"
+
filePath
)
;
File
file
=
null
;
FileOutputStream
fos
=
null
;
try
{
file
=
new
File
(
filePath
)
;
log
.
info
(
"========readIoStringToFile.file:"
+
file
)
;
if
(
file
.
exists
(
)
)
{
file
.
delete
(
)
;
}
else
{
file
.
getParentFile
(
)
.
mkdir
(
)
;
file
.
createNewFile
(
)
;
fos
=
new
FileOutputStream
(
file
)
;
fos
.
write
(
ioString
.
getBytes
(
"UTF-8"
)
)
;
fos
.
flush
(
)
;
}
catch
(
Exception
e
)
{
log
.
error
(
"readIoStringToFile.Exception异常了:"
+
e
.
getMessage
(
)
)
;
e
.
printStackTrace
(
)
;
}
finally
{
if
(
fos
!=
null
)
{
try
{
fos
.
close
(
)
;
}
catch
(
IOException
e
)
{
log
.
error
(
"readIoStringToFile.IOException异常了:"
+
e
.
getMessage
(
)
)
;
e
.
printStackTrace
(
)
;
return
file
;
svg转jpg依赖:
<!-- https://mvnrepository.com/artifact/org.apache.xmlgraphics/batik-all -->
<dependency>
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>batik-all</artifactId>
<version>1.12</version>
<type>pom</type>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.xmlgraphics/fop -->
<dependency>
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>fop</artifactId>
<version>2.4</version>
</dependency>
svg转jpg的工具类:
package com.common.entity.utils;
import lombok.extern.slf4j.Slf4j;
import org.apache.batik.transcoder.*;
import org.apache.batik.transcoder.image.JPEGTranscoder;
import org.apache.batik.transcoder.image.PNGTranscoder;
import org.apache.fop.render.ps.EPSTranscoder;
import org.apache.fop.render.ps.PSTranscoder;
import org.apache.fop.svg.PDFTranscoder;
import java.io.*;
* @author zhiwei Liao
* @version 1.0
* @Description 利用Apache Batik实现 SVG转PDF/PNG/JPG
* @Date 2021/9/13 16:26
@Slf4j
public class SVGConverterUtils {
public static void main(String[] args) throws Exception {
String svgpath = "E:\\svgfile\\c.svg";
File svgFile = new File(svgpath);
String name = svgFile.getName();
name = name.substring(0, name.lastIndexOf("."));
svg2JPEG(new File(svgpath), new File("E:/" + name + "_SVG文件转JPG.jpg"));
String svgCode = svg2String(new File(svgpath));
svgtoeps(svgCode, new FileOutputStream(new File("E:/svgfile/" + name + "_SVG代码转输出流.eps")));
public static File svgFileChangeJpg(File svgFile, String jpgPath){
log.info("========svgFileChangeJpg.jpgPath:" + jpgPath);
try {
File file = new File(jpgPath);
if (file.exists()) {
file.delete();
}else {
file.getParentFile().mkdir();
file.createNewFile();
log.info("========svgFileChangeJpg.jpgFile:" + file);
log.info("========svgFileChangeJpg.svgFile:" + svgFile);
svg2JPEG(svgFile, file);
return file;
} catch (Exception e) {
log.error(e.getMessage());
return null;
public static void svgtoeps(String svgCode, OutputStream os){
EPSTranscoder epsTranscoder = new EPSTranscoder();
try {
svgCode = svgCode.replaceAll(":rect", "rect");
TranscoderInput input = new TranscoderInput(new ByteArrayInputStream(svgCode.getBytes()));
TranscoderOutput output = new TranscoderOutput(os);
epsTranscoder.transcode(input, output);
os.flush();
os.close();
} catch (Exception e) {
* SVG转PNG
* @param svgCode SVG代码
* @param outpath 输出路径
* @throws TranscoderException
* @throws IOException
public void svg2PNG(String svgCode, String outpath) throws TranscoderException, IOException {
Transcoder transcoder = new PNGTranscoder();
svgConverte(svgCode, outpath, transcoder);
* SVG转PNG
* @param svgCode SVG代码
* @param out 输出流
* @throws TranscoderException
* @throws IOException
public void svg2PNG(String svgCode, OutputStream out) throws TranscoderException, IOException {
Transcoder transcoder = new PNGTranscoder();
svgConverte(svgCode, out, transcoder);
* SVG转PNG
* @param svgFile SVG文件
* @param outFile 输出文件
* @throws TranscoderException
* @throws IOException
public void svg2PNG(File svgFile, File outFile) throws TranscoderException, IOException {
Transcoder transcoder = new PNGTranscoder();
svgConverte(svgFile, outFile, transcoder);
* SVG转JPG
* @param svgCode SVG代码
* @param outpath 输出路径
* @throws TranscoderException
* @throws IOException
public void svg2JPEG(String svgCode, String outpath) throws TranscoderException, IOException {
Transcoder transcoder = new JPEGTranscoder();
transcoder.addTranscodingHint(JPEGTranscoder.KEY_QUALITY, 0.99f);
svgConverte(svgCode, outpath, transcoder);
* SVG转JPG
* @param svgCode SVG代码
* @param out 输出流
* @throws TranscoderException
* @throws IOException
public void svg2JPEG(String svgCode, OutputStream out) throws TranscoderException, IOException {
Transcoder transcoder = new JPEGTranscoder();
transcoder.addTranscodingHint(JPEGTranscoder.KEY_QUALITY, 0.99f);
svgConverte(svgCode, out, transcoder);
* SVG转JPG
* @param svgFile SVG文件
* @param outFile 输出文件
* @throws TranscoderException
* @throws IOException
public static void svg2JPEG(File svgFile, File outFile) throws TranscoderException, IOException {
Transcoder transcoder = new JPEGTranscoder();
transcoder.addTranscodingHint(JPEGTranscoder.KEY_QUALITY, 0.99f);
svgConverte(svgFile, outFile, transcoder);
* SVG转PDF
* @param svgCode SVG代码
* @param outpath 输出路径
* @throws TranscoderException
* @throws IOException
public void svg2PDF(String svgCode, String outpath) throws TranscoderException, IOException {
Transcoder transcoder = new PDFTranscoder();
svgConverte(svgCode, outpath, transcoder);
* SVG转PS
* @param svgCode
* @param outpath
* @throws TranscoderException
* @throws IOException
public void svg2PS(String svgCode, String outpath) throws TranscoderException, IOException {
Transcoder transcoder = new PSTranscoder();
svgConverte(svgCode, outpath, transcoder);
* SVG转PS
* @param svgCode SVG代码
* @param out 输出流
* @throws TranscoderException
* @throws IOException
public void svg2PS(String svgCode, OutputStream out) throws TranscoderException, IOException {
Transcoder transcoder = new PSTranscoder();
svgConverte(svgCode, out, transcoder);
* SVG转EPS
* @param svgCode SVG代码
* @param out 输出流
* @throws TranscoderException
* @throws IOException
public void svg2EPS(String svgCode, OutputStream out) throws TranscoderException, IOException {
Transcoder transcoder = new EPSTranscoder();
svgConverte(svgCode, out, transcoder);
* SVG转EPS
* @param svgCode
* @param outpath
* @throws TranscoderException
* @throws IOException
public void svg2EPS(String svgCode, String outpath) throws TranscoderException, IOException {
Transcoder transcoder = new EPSTranscoder();
svgConverte(svgCode, outpath, transcoder);
* SVG转PDF
* @param svgCode SVG代码
* @param out 输出流
* @throws TranscoderException
* @throws IOException
public void svg2PDF(String svgCode, OutputStream out) throws TranscoderException, IOException {
Transcoder transcoder = new PDFTranscoder();
svgConverte(svgCode, out, transcoder);
* SVG转PDF
* @param svgFile SVG文件
* @param outFile 输出文件
* @throws TranscoderException
* @throws IOException
public void svg2PDF(File svgFile, File outFile) throws TranscoderException, IOException {
Transcoder transcoder = new PDFTranscoder();
svgConverte(svgFile, outFile, transcoder);
private void svgConverte(String svgCode, String outpath, Transcoder transcoder) throws IOException, TranscoderException {
svgConverte(svgCode, getOutputStream(outpath), transcoder);
private static void svgConverte(File svg, File outFile, Transcoder transcoder) throws IOException, TranscoderException {
svgConverte(svg2String(getInputStream(svg)), getOutputStream(outFile), transcoder);
private static void svgConverte(String svgCode, OutputStream out, Transcoder transcoder) throws IOException, TranscoderException {
svgCode = svgCode.replaceAll(":rect", "rect");
TranscoderInput input = new TranscoderInput(new ByteArrayInputStream(svgCode.getBytes()));
TranscoderOutput output = new TranscoderOutput(out);
svgConverte(input, output, transcoder);
private static void svgConverte(TranscoderInput input, TranscoderOutput output, Transcoder transcoder) throws IOException, TranscoderException {
transcoder.transcode(input, output);
public static InputStream getInputStream(File file) throws IOException {
return new FileInputStream(file);
public InputStream getInputStream(String filepath) throws IOException {
File file = new File(filepath);
if (file.exists())
return getInputStream(file);
return null;
public static OutputStream getOutputStream(File outFile) throws IOException {
return new FileOutputStream(outFile);
public OutputStream getOutputStream(String outpath) throws IOException {
File file = new File(outpath);
if (!file.exists())
file.createNewFile();
return getOutputStream(file);
* 默认使用编码UTF-8 SVG文件输入流转String
* @param svgFile
* @return SVG代码
* @throws IOException
public static String svg2String(File svgFile) throws IOException {
InputStream in = getInputStream(svgFile);
return svg2String(in, "UTF-8");
* SVG文件输入流转String
* @param svgFile
* @return SVG代码
* @throws IOException
public String svg2String(File svgFile, String charset) throws IOException {
InputStream in = getInputStream(svgFile);
return svg2String(in, charset);
* 默认使用编码UTF-8SVG输入流转String
* @param in
* @return SVG代码
public static String svg2String(InputStream in) {
return svg2String(in, "UTF-8");
* 指定字符集SVG输入流转String
* @param in 输入流
* @param charset 字符编码
* @return SVG代码
public static String svg2String(InputStream in, String charset) {
StringBuffer svgBuffer = new StringBuffer();
BufferedReader bfr = null;
try {
InputStreamReader inputStreamReader = new InputStreamReader(in, charset);
bfr = new BufferedReader(inputStreamReader);
String line = "";
while ((line = bfr.readLine()) != null) {
svgBuffer.append(line);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (bfr != null)
bfr.close();
} catch (IOException e) {
e.printStackTrace();
return svgBuffer.toString();
这里有些配置的我就不公开了
看到这想必大家对这个功能有所了解了,接下来进阶需求,由设计师提供一个图像模板,比如:汽车,房屋等。对这类对象的属性进行切换,比如,汽车是否为敞篷,颜色,房屋的层高,风格等。
可以控制图像的属性,生成图片。如果给你做,你会如何实现?(这类功能有很多实现场景,比如:很多游戏中的模型切换(游戏中使用的技术是Cocos2d游戏开发引擎)等)
这里分享一个纯前端实现人形头像元素切换的功能:https://github.com/Ice-Hazymoon/random-avatar-generator
解剖功能实现原理(以人形头像为例):
将人像的元素拆分出来:发型,肤色,头像大小,鼻子,嘴巴等,给定一个人形模型模板,让每个元素套用在模型模板上面,实现控制人像切换。
同理(汽车和房屋也一样)
Java后端通过创建对象,列举对象属性,将数据填充到模板里面,然后通过模板生成对应的图片即可。
这个模板可以使用Freemarker技术实现,由前端给的一个html的文件,将文件内容复制到以.ftl为后缀的文件中,将参数替换成变量即可。
前端可以通过叠加样式或者图片实现人像切换,后端则负责给定对象属性以及参数。