7
7
import java .awt .image .AffineTransformOp ;
8
8
import java .awt .image .BufferedImage ;
9
9
import java .io .*;
10
+ import java .net .HttpURLConnection ;
10
11
import java .net .URL ;
11
12
import java .net .URLConnection ;
13
+ import java .util .regex .Pattern ;
12
14
13
15
import com .genexus .db .driver .ResourceAccessControlList ;
14
16
import com .genexus .util .GxFileInfoSourceType ;
@@ -111,20 +113,41 @@ public static String crop(String imageFile, int x, int y, int width, int height)
111
113
return "" ;
112
114
}
113
115
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 {
116
119
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 );
121
139
try (ByteArrayInputStream inStream = new ByteArrayInputStream (outStream .toByteArray ())) {
122
140
GXFile file = getGXFile (newFileName );
123
141
file .create (inStream , true );
124
142
file .close ();
125
143
return file .getURI ();
126
144
}
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 );
128
151
outStream .flush ();
129
152
byte [] imageInByte = outStream .toByteArray ();
130
153
return GXutil .blobFromBytes (imageInByte ,CommonUtil .getFileType (newFileName ));
@@ -166,19 +189,33 @@ public static String flipVertically(String imageFile) {
166
189
return "" ;
167
190
}
168
191
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 ){
171
193
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
174
194
BufferedImage originalImage = createBufferedImageFromURI (imageFile );
175
195
if (imageFile .indexOf (".jpg" ) > 0 || imageFile .indexOf (".jpeg" ) > 0 )
176
196
try (ByteArrayOutputStream baos = new ByteArrayOutputStream ()){
177
197
ImageIO .write (originalImage , "png" , baos );
178
198
byte [] bytes = baos .toByteArray ();
179
199
try (InputStream is = new ByteArrayInputStream (bytes )) {originalImage = ImageIO .read (is );}
180
- imageFile = imageFile .replace (".jpg" ,".png" ).replace (".jpeg" ,".png" );
181
200
}
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" ;
182
219
183
220
int w = originalImage .getWidth ();
184
221
int h = originalImage .getHeight ();
@@ -205,7 +242,7 @@ public static String roundBorders(String imageFile, int topLeftRadius, int topRi
205
242
g2 .drawImage (originalImage , 0 , 0 , null );
206
243
g2 .dispose ();
207
244
208
- return writeImage (roundedImage ,imageFile );
245
+ return writeImage (roundedImage ,newImageFile );
209
246
210
247
} catch (Exception e ){
211
248
log .error ("round borders for " + imageFile + " failed" , e );
@@ -258,9 +295,17 @@ public static String rotate(String imageFile, short angle) {
258
295
if (!isValidInput (imageFile ))
259
296
return "" ;
260
297
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 );
264
309
}
265
310
catch (Exception e ) {
266
311
log .error ("rotate " + imageFile + " failed" , e );
0 commit comments