Skip to content

Commit 5eb9ad9

Browse files
Handle image returned by web services and rotate jpg images
Issue: 104250
1 parent 48dc702 commit 5eb9ad9

File tree

1 file changed

+61
-16
lines changed

1 file changed

+61
-16
lines changed

java/src/main/java/com/genexus/GxImageUtil.java

Lines changed: 61 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@
77
import java.awt.image.AffineTransformOp;
88
import java.awt.image.BufferedImage;
99
import java.io.*;
10+
import java.net.HttpURLConnection;
1011
import java.net.URL;
1112
import java.net.URLConnection;
13+
import java.util.regex.Pattern;
1214

1315
import com.genexus.db.driver.ResourceAccessControlList;
1416
import com.genexus.util.GxFileInfoSourceType;
@@ -111,20 +113,41 @@ public static String crop(String imageFile, int x, int y, int width, int height)
111113
return "";
112114
}
113115

114-
private static String writeImage(BufferedImage croppedImage, String destinationFilePathOrUrl) throws IOException {
115-
String newFileName = PrivateUtilities.getTempFileName(CommonUtil.getFileType(destinationFilePathOrUrl));
116+
private static final Pattern IMAGE_PATTERN = Pattern.compile("\\.(jpg|jpeg|png|bmp|webp|jfif)([/?]|$)", Pattern.CASE_INSENSITIVE);
117+
118+
private static String writeImage(BufferedImage bufferedImage, String destinationFilePathOrUrl) throws IOException {
116119
IHttpContext httpContext = com.genexus.ModelContext.getModelContext().getHttpContext();
117-
try (ByteArrayOutputStream outStream = new ByteArrayOutputStream()){
118-
ImageIO.write(croppedImage, CommonUtil.getFileType(newFileName), outStream);
119-
if (destinationFilePathOrUrl.toLowerCase().startsWith("http://") || destinationFilePathOrUrl.toLowerCase().startsWith("https://") ||
120-
(httpContext.isHttpContextWeb() && destinationFilePathOrUrl.startsWith(httpContext.getContextPath()))){
120+
if (destinationFilePathOrUrl.toLowerCase().startsWith("http://") || destinationFilePathOrUrl.toLowerCase().startsWith("https://") || (httpContext.isHttpContextWeb() && destinationFilePathOrUrl.startsWith(httpContext.getContextPath()))){
121+
122+
String newFileName;
123+
if (!IMAGE_PATTERN.matcher(destinationFilePathOrUrl).find()) {
124+
URL imageUrl = new URL(destinationFilePathOrUrl);
125+
HttpURLConnection connection = null;
126+
String format;
127+
try {
128+
connection = (HttpURLConnection) imageUrl.openConnection();
129+
format = connection.getContentType().split("/")[1];
130+
} finally {
131+
if (connection != null) connection.disconnect();
132+
}
133+
newFileName = PrivateUtilities.getTempFileName(format);
134+
} else
135+
newFileName = PrivateUtilities.getTempFileName(CommonUtil.getFileType(destinationFilePathOrUrl));
136+
137+
try (ByteArrayOutputStream outStream = new ByteArrayOutputStream()) {
138+
ImageIO.write(bufferedImage, CommonUtil.getFileType(newFileName), outStream);
121139
try (ByteArrayInputStream inStream = new ByteArrayInputStream(outStream.toByteArray())) {
122140
GXFile file = getGXFile(newFileName);
123141
file.create(inStream, true);
124142
file.close();
125143
return file.getURI();
126144
}
127-
} else {
145+
}
146+
147+
} else {
148+
String newFileName = PrivateUtilities.getTempFileName(CommonUtil.getFileType(destinationFilePathOrUrl));
149+
try (ByteArrayOutputStream outStream = new ByteArrayOutputStream()) {
150+
ImageIO.write(bufferedImage, CommonUtil.getFileType(newFileName), outStream);
128151
outStream.flush();
129152
byte[] imageInByte = outStream.toByteArray();
130153
return GXutil.blobFromBytes(imageInByte,CommonUtil.getFileType(newFileName));
@@ -166,19 +189,33 @@ public static String flipVertically(String imageFile) {
166189
return "";
167190
}
168191

169-
public static String roundBorders(String imageFile, int topLeftRadius, int topRightRadius, int bottomLeftRadius, int bottomRightRadius) {
170-
if (!isValidInput(imageFile)) return "";
192+
private static BufferedImage jpgToPng(String imageFile){
171193
try {
172-
// Rounded images are basically images with transparent rounded borders and jpg and jpeg formats do not
173-
// support transparency, so we have to create a new identical image but in png format
174194
BufferedImage originalImage = createBufferedImageFromURI(imageFile);
175195
if (imageFile.indexOf(".jpg") > 0 || imageFile.indexOf(".jpeg") > 0)
176196
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()){
177197
ImageIO.write(originalImage, "png", baos);
178198
byte[] bytes = baos.toByteArray();
179199
try (InputStream is = new ByteArrayInputStream(bytes)) {originalImage = ImageIO.read(is);}
180-
imageFile = imageFile.replace(".jpg",".png").replace(".jpeg",".png");
181200
}
201+
return originalImage;
202+
} catch (IOException ioe) {
203+
log.error("format conversion for " + imageFile + " failed" , ioe);
204+
return null;
205+
}
206+
}
207+
208+
public static String roundBorders(String imageFile, int topLeftRadius, int topRightRadius, int bottomLeftRadius, int bottomRightRadius) {
209+
if (!isValidInput(imageFile)) return "";
210+
try {
211+
// Rounded images are basically images with transparent rounded borders and jpg and jpeg formats do not
212+
// support transparency, so we have to create a new identical image but in png format if working with a jpg image
213+
BufferedImage originalImage = jpgToPng(imageFile);
214+
String newImageFile = imageFile;
215+
if (imageFile.indexOf(".jpg") != -1)
216+
newImageFile = imageFile.substring(0, imageFile.indexOf(".jpg")) + ".png";
217+
else if (imageFile.indexOf(".jpeg") != -1)
218+
newImageFile = imageFile.substring(0, imageFile.indexOf(".jpeg")) + ".png";
182219

183220
int w = originalImage.getWidth();
184221
int h = originalImage.getHeight();
@@ -205,7 +242,7 @@ public static String roundBorders(String imageFile, int topLeftRadius, int topRi
205242
g2.drawImage(originalImage, 0, 0, null);
206243
g2.dispose();
207244

208-
return writeImage(roundedImage,imageFile);
245+
return writeImage(roundedImage,newImageFile);
209246

210247
} catch (Exception e){
211248
log.error("round borders for " + imageFile + " failed" , e);
@@ -258,9 +295,17 @@ public static String rotate(String imageFile, short angle) {
258295
if (!isValidInput(imageFile))
259296
return "";
260297
try {
261-
BufferedImage image = createBufferedImageFromURI(imageFile);
262-
BufferedImage rotatedImage = rotateImage(image, angle);
263-
return writeImage(rotatedImage, imageFile);
298+
// The process of rotating an image implies fitting it inside a rectangle and filling the excess
299+
// with transparent background and jpg and jpeg formats do not transparency, so we have to create a new
300+
// identical image but in png format if working with a jpg image
301+
BufferedImage originalImage = jpgToPng(imageFile);
302+
String newImageFile = imageFile;
303+
if (imageFile.indexOf(".jpg") != -1)
304+
newImageFile = imageFile.substring(0, imageFile.indexOf(".jpg")) + ".png";
305+
else if (imageFile.indexOf(".jpeg") != -1)
306+
newImageFile = imageFile.substring(0, imageFile.indexOf(".jpeg")) + ".png";
307+
BufferedImage rotatedImage = rotateImage(originalImage, angle);
308+
return writeImage(rotatedImage, newImageFile);
264309
}
265310
catch (Exception e) {
266311
log.error("rotate " + imageFile + " failed" , e);

0 commit comments

Comments
 (0)