Skip to content

Commit 6b3754d

Browse files
committed
Support vectorial images for avatars
1 parent b0374d9 commit 6b3754d

File tree

5 files changed

+49
-32
lines changed

5 files changed

+49
-32
lines changed

logicaldoc-core/src/main/java/com/logicaldoc/core/util/UserUtil.java

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public class UserUtil {
4343
/**
4444
* A transparent 1x1 PNG
4545
*/
46-
private static final String TRANSPARENT_IMAGE = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=";
46+
private static final String TRANSPARENT_IMAGE = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=";
4747

4848
private static final Logger log = LoggerFactory.getLogger(UserUtil.class);
4949

@@ -118,22 +118,29 @@ public static File getUsersDir() {
118118
*
119119
* @param user The user to elaborate
120120
* @param avatarImageFile The file containing the avatar image
121+
* @param avatarImageFile The image type(eg png, svg)
121122
*/
122-
public static void saveAvatar(User user, File avatarImageFile) {
123+
public static void saveAvatar(User user, File avatarImageFile, String imageType) {
123124
UserDAO userDao = Context.get(UserDAO.class);
124125
TenantDAO tenantDao = Context.get(TenantDAO.class);
125126

126127
File tmpAvatarImage = null;
127128
try {
128129
userDao.initialize(user);
129-
String tenantName = tenantDao.getTenantName(user.getTenantId());
130-
int size = Context.get().getProperties().getInt(tenantName + ".gui.avatar.size", 128);
130+
if ("svg".equalsIgnoreCase(imageType)) {
131+
// In case of SVG we save the image as is
132+
user.setAvatar("data:image/svg+xml;base64," + ImageUtil.encodeImage(avatarImageFile));
133+
} else {
134+
// In case of raster image we crop and resize
135+
String tenantName = tenantDao.getTenantName(user.getTenantId());
136+
int size = Context.get().getProperties().getInt(tenantName + ".gui.avatar.size", 128);
137+
tmpAvatarImage = FileUtil.createTempFile(AVATAR, ".png");
138+
BufferedImage avatar = ImageIO.read(avatarImageFile);
139+
avatar = ImageUtil.cropCenterSquare(avatar, size);
140+
ImageIO.write(avatar, "png", tmpAvatarImage);
141+
user.setAvatar("data:image/png;base64," + ImageUtil.encodeImage(tmpAvatarImage));
142+
}
131143

132-
tmpAvatarImage = FileUtil.createTempFile(AVATAR, ".png");
133-
BufferedImage avatar = ImageIO.read(avatarImageFile);
134-
avatar = ImageUtil.cropCenterSquare(avatar, size);
135-
ImageIO.write(avatar, "png", tmpAvatarImage);
136-
user.setAvatar(ImageUtil.encodeImage(tmpAvatarImage));
137144
userDao.store(user);
138145
} catch (Exception t) {
139146
log.warn(ERROR_GENERATING_DEFAULT_THE_AVATAR_FOR_USER, user, t);
@@ -150,7 +157,7 @@ public static void saveAvatar(User user, File avatarImageFile) {
150157
*/
151158
public static void generateDefaultAvatar(User user) {
152159
UserDAO userDao = Context.get(UserDAO.class);
153-
160+
154161
File tmpAvatarImage = null;
155162
try {
156163
userDao.initialize(user);
@@ -162,7 +169,7 @@ public static void generateDefaultAvatar(User user) {
162169

163170
BufferedImage avatar = UserUtil.generateDefaultAvatarImage(user, size);
164171
ImageIO.write(avatar, "png", tmpAvatarImage);
165-
user.setAvatar(ImageUtil.encodeImage(tmpAvatarImage));
172+
user.setAvatar("data:image/png;base64," + ImageUtil.encodeImage(tmpAvatarImage));
166173

167174
if (user.getType() != User.TYPE_SYSTEM) {
168175
userDao.store(user);

logicaldoc-gui/src/main/java/com/logicaldoc/gui/common/client/beans/GUIBranding.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public class GUIBranding implements Serializable {
1616

1717
public static final String PNG_PREFIX = DATA_PREFIX + "png;base64,";
1818

19-
public static final String SVG_PREFIX = DATA_PREFIX + "svg+xml;base64,";
19+
private static final String SVG_PREFIX = DATA_PREFIX + "svg+xml;base64,";
2020

2121
private static final String LOGO_OEM = PNG_PREFIX
2222
+ "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";

logicaldoc-gui/src/main/java/com/logicaldoc/gui/common/client/widgets/UserAvatar.java

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,7 @@ public void onSuccess(Void arg) {
7979

8080
MenuItem update = new MenuItem();
8181
update.setTitle(I18N.message("update"));
82-
update.addClickHandler(event -> {
83-
Uploader uploader = new Uploader(userId);
84-
uploader.show();
85-
});
82+
update.addClickHandler(click -> new Uploader(userId).show());
8683

8784
Menu contextMenu = new Menu();
8885
contextMenu.setItems(reset, update);
@@ -110,7 +107,7 @@ public Uploader(long userId) {
110107
setAutoSize(true);
111108

112109
saveButton = new IButton(I18N.message("save"));
113-
saveButton.addClickHandler(event -> onSave());
110+
saveButton.addClickHandler(click -> onSave());
114111

115112
Label hint = new Label(I18N.message("avatarhint", Session.get().getConfig(GUI_AVATAR_SIZE),
116113
Session.get().getConfig(GUI_AVATAR_SIZE)));
@@ -175,7 +172,7 @@ public void onSuccess(Void result) {
175172
public boolean equals(Object other) {
176173
return super.equals(other);
177174
}
178-
175+
179176
@Override
180177
public int hashCode() {
181178
return super.hashCode();
@@ -186,7 +183,7 @@ public int hashCode() {
186183
public boolean equals(Object other) {
187184
return super.equals(other);
188185
}
189-
186+
190187
@Override
191188
public int hashCode() {
192189
return super.hashCode();

logicaldoc-webapp/src/main/java/com/logicaldoc/web/AvatarServlet.java

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
package com.logicaldoc.web;
22

3-
import java.awt.image.BufferedImage;
43
import java.io.ByteArrayInputStream;
54
import java.io.IOException;
65
import java.io.OutputStream;
76
import java.util.Base64;
87
import java.util.Base64.Decoder;
98

10-
import javax.imageio.ImageIO;
119
import javax.servlet.ServletException;
1210
import javax.servlet.http.HttpServlet;
1311
import javax.servlet.http.HttpServletRequest;
1412
import javax.servlet.http.HttpServletResponse;
1513

14+
import org.apache.commons.io.IOUtils;
1615
import org.slf4j.Logger;
1716
import org.slf4j.LoggerFactory;
1817

@@ -33,6 +32,8 @@ public class AvatarServlet extends HttpServlet {
3332

3433
private static final long serialVersionUID = -6956612970433309888L;
3534

35+
private static final String DATA_PREFIX = "data:image/";
36+
3637
private static final Logger log = LoggerFactory.getLogger(AvatarServlet.class);
3738

3839
/**
@@ -57,29 +58,40 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) thro
5758
try {
5859
String id = request.getParameter(USER_ID);
5960

60-
String fileName = "avatar-" + id + ".png";
61+
String content = UserUtil.getAvatarImage(id);
62+
String fileName = "avatar-" + id + "." + getExtension(content);
63+
6164
response.setContentType(MimeType.getByFilename(fileName));
6265
ServletUtil.setContentDisposition(request, response, fileName);
6366

64-
String content = UserUtil.getAvatarImage(id);
6567
saveImage(content, response.getOutputStream());
6668
} catch (Exception e) {
6769
log.error(e.getMessage(), e);
6870
ServletUtil.sendError(response, e.getMessage());
6971
}
7072
}
7173

74+
private String getExtension(String content) {
75+
String extension = "png";
76+
if (content.startsWith(DATA_PREFIX)) {
77+
extension = content.substring(content.indexOf('/') + 1, content.indexOf(';') - 1);
78+
if (extension.contains("+"))
79+
extension = extension.substring(0, extension.indexOf('+'));
80+
}
81+
82+
System.out.println(extension);
83+
84+
return extension;
85+
}
86+
7287
private void saveImage(String content, OutputStream out) throws IOException {
73-
BufferedImage image = null;
74-
byte[] imageByte;
88+
if (content.startsWith(DATA_PREFIX))
89+
content = content.substring(content.indexOf(',') + 1);
7590

7691
Decoder decoder = Base64.getDecoder();
77-
imageByte = decoder.decode(content);
92+
byte[] imageByte = decoder.decode(content);
7893
try (ByteArrayInputStream bis = new ByteArrayInputStream(imageByte)) {
79-
image = ImageIO.read(bis);
94+
IOUtils.write(imageByte, out);
8095
}
81-
82-
// write the image to a file
83-
ImageIO.write(image, "png", out);
8496
}
8597
}

logicaldoc-webapp/src/main/java/com/logicaldoc/web/service/SecurityServiceImpl.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@
8989
import com.logicaldoc.util.config.WebConfigurator;
9090
import com.logicaldoc.util.config.WebContextConfigurator;
9191
import com.logicaldoc.util.crypt.CryptUtil;
92+
import com.logicaldoc.util.io.FileUtil;
9293
import com.logicaldoc.util.security.PasswordCriteria;
9394
import com.logicaldoc.util.security.PasswordGenerator;
9495
import com.logicaldoc.util.security.PasswordValidator;
@@ -1572,12 +1573,12 @@ public void saveAvatar(long userId) throws ServerException {
15721573
Session session = validateSession();
15731574

15741575
Map<String, File> uploadedFilesMap = UploadServlet.getUploads(session.getSid());
1575-
File file = uploadedFilesMap.values().iterator().next();
1576+
Map.Entry<String, File> file = uploadedFilesMap.entrySet().iterator().next();
15761577
try {
15771578
UserDAO userDao = Context.get(UserDAO.class);
15781579
User user = userDao.findById(userId);
15791580
if (user != null)
1580-
UserUtil.saveAvatar(user, file);
1581+
UserUtil.saveAvatar(user, file.getValue(), FileUtil.getExtension(file.getKey()));
15811582
} catch (PersistenceException e) {
15821583
log.error("Unable to store the avatar", e);
15831584
} finally {

0 commit comments

Comments
 (0)