Also adds an output parameter to allow viewing images directly in the browser (values octet to download as an attachment, and inline_octet to view inline)
This commit is contained in:
committed by
Vishwas Babu A J
parent
c2c2f65c13
commit
f9dfd409db
+13
-7
@@ -16,6 +16,7 @@ import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.Response.ResponseBuilder;
|
||||
@@ -106,7 +107,10 @@ public class ImagesApiResource {
|
||||
@GET
|
||||
@Consumes({ MediaType.TEXT_PLAIN, MediaType.TEXT_HTML, MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.TEXT_PLAIN })
|
||||
public String retrieveClientImage(@PathParam("clientId") final Long clientId) {
|
||||
public Response retrieveClientImage(@PathParam("clientId") final Long clientId, @QueryParam("maxWidth") final Integer maxWidth,
|
||||
@QueryParam("maxHeight") final Integer maxHeight, @QueryParam("output") final String output) {
|
||||
if (output != null && (output.equals("octet") || output.equals("inline_octet"))) { return downloadClientImage(clientId, maxWidth,
|
||||
maxHeight, output); }
|
||||
|
||||
this.context.authenticatedUser().validateHasReadPermission("CLIENTIMAGE");
|
||||
|
||||
@@ -120,21 +124,23 @@ public class ImagesApiResource {
|
||||
imageDataURISuffix = ContentRepositoryUtils.IMAGE_DATA_URI_SUFFIX.PNG.getValue();
|
||||
}
|
||||
|
||||
final String clientImageAsBase64Text = imageDataURISuffix + Base64.encodeBytes(imageData.getContent());
|
||||
return clientImageAsBase64Text;
|
||||
final String clientImageAsBase64Text = imageDataURISuffix + Base64.encodeBytes(imageData.getContentOfSize(maxWidth, maxHeight));
|
||||
return Response.ok(clientImageAsBase64Text).build();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_OCTET_STREAM })
|
||||
public Response downloadClientImage(@PathParam("clientId") final Long clientId) {
|
||||
public Response downloadClientImage(@PathParam("clientId") final Long clientId, @QueryParam("maxWidth") final Integer maxWidth,
|
||||
@QueryParam("maxHeight") final Integer maxHeight, @QueryParam("output") String output) {
|
||||
|
||||
this.context.authenticatedUser().validateHasReadPermission("CLIENTIMAGE");
|
||||
final ImageData imageData = this.imageReadPlatformService.retrieveClientImage(clientId);
|
||||
|
||||
final ResponseBuilder response = Response.ok(imageData.getContent());
|
||||
response.header("Content-Disposition", "attachment; filename=\"" + imageData.getEntityDisplayName() + IMAGE_FILE_EXTENSION.JPEG
|
||||
+ "\"");
|
||||
final ResponseBuilder response = Response.ok(imageData.getContentOfSize(maxWidth, maxHeight));
|
||||
String dispositionType = "inline_octet".equals(output) ? "inline" : "attachment";
|
||||
response.header("Content-Disposition", dispositionType + "; filename=\"" + imageData.getEntityDisplayName()
|
||||
+ IMAGE_FILE_EXTENSION.JPEG + "\"");
|
||||
|
||||
// TODO: Need a better way of determining image type
|
||||
|
||||
|
||||
+31
@@ -28,6 +28,20 @@ public class ContentRepositoryUtils {
|
||||
public String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public static IMAGE_MIME_TYPE fromFileExtension(IMAGE_FILE_EXTENSION fileExtension) {
|
||||
switch (fileExtension) {
|
||||
case GIF:
|
||||
return IMAGE_MIME_TYPE.GIF;
|
||||
case JPG:
|
||||
case JPEG:
|
||||
return IMAGE_MIME_TYPE.JPEG;
|
||||
case PNG:
|
||||
return IMAGE_MIME_TYPE.PNG;
|
||||
default:
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static enum IMAGE_FILE_EXTENSION {
|
||||
@@ -42,6 +56,23 @@ public class ContentRepositoryUtils {
|
||||
public String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public String getValueWithoutDot() {
|
||||
return this.value.substring(1);
|
||||
}
|
||||
|
||||
public IMAGE_FILE_EXTENSION getFileExtension() {
|
||||
switch (this) {
|
||||
case GIF:
|
||||
return IMAGE_FILE_EXTENSION.GIF;
|
||||
case JPEG:
|
||||
return IMAGE_FILE_EXTENSION.JPEG;
|
||||
case PNG:
|
||||
return IMAGE_FILE_EXTENSION.PNG;
|
||||
default:
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static enum IMAGE_DATA_URI_SUFFIX {
|
||||
|
||||
+72
-16
@@ -1,9 +1,17 @@
|
||||
package org.mifosplatform.infrastructure.documentmanagement.data;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.poi.util.IOUtils;
|
||||
@@ -19,7 +27,7 @@ public class ImageData {
|
||||
private final String entityDisplayName;
|
||||
|
||||
private File file;
|
||||
private String contentType;
|
||||
private ContentRepositoryUtils.IMAGE_FILE_EXTENSION fileExtension;
|
||||
private InputStream inputStream;
|
||||
|
||||
public ImageData(final Long imageId, final String location, final Integer storageType, final String entityDisplayName) {
|
||||
@@ -43,23 +51,76 @@ public class ImageData {
|
||||
}
|
||||
}
|
||||
|
||||
private String setImageContentType() {
|
||||
String contentType = ContentRepositoryUtils.IMAGE_MIME_TYPE.JPEG.getValue();
|
||||
public byte[] resizeImage(InputStream in, int maxWidth, int maxHeight) throws IOException {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
resizeImage(in, out, maxWidth, maxHeight);
|
||||
return out.toByteArray();
|
||||
}
|
||||
|
||||
if (this.file != null) {
|
||||
final String fileName = this.file.getName();
|
||||
public void resizeImage(InputStream in, OutputStream out, int maxWidth, int maxHeight) throws IOException {
|
||||
|
||||
if (StringUtils.endsWith(fileName, ContentRepositoryUtils.IMAGE_FILE_EXTENSION.GIF.getValue())) {
|
||||
contentType = ContentRepositoryUtils.IMAGE_MIME_TYPE.GIF.getValue();
|
||||
} else if (StringUtils.endsWith(fileName, ContentRepositoryUtils.IMAGE_FILE_EXTENSION.PNG.getValue())) {
|
||||
contentType = ContentRepositoryUtils.IMAGE_MIME_TYPE.PNG.getValue();
|
||||
BufferedImage src = ImageIO.read(in);
|
||||
if (src.getWidth() <= maxWidth && src.getHeight() <= maxHeight) {
|
||||
out.write(getContent());
|
||||
return;
|
||||
}
|
||||
float widthRatio = (float) src.getWidth() / maxWidth;
|
||||
float heightRatio = (float) src.getHeight() / maxHeight;
|
||||
float scaleRatio = widthRatio > heightRatio ? widthRatio : heightRatio;
|
||||
|
||||
// TODO(lindahl): Improve compressed image quality (perhaps quality
|
||||
// ratio)
|
||||
|
||||
int newWidth = (int) (src.getWidth() / scaleRatio);
|
||||
int newHeight = (int) (src.getHeight() / scaleRatio);
|
||||
int colorModel = fileExtension == ContentRepositoryUtils.IMAGE_FILE_EXTENSION.JPEG ? BufferedImage.TYPE_INT_RGB
|
||||
: BufferedImage.TYPE_INT_ARGB;
|
||||
BufferedImage target = new BufferedImage(newWidth, newHeight, colorModel);
|
||||
Graphics2D g = target.createGraphics();
|
||||
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
|
||||
g.drawImage(src, 0, 0, newWidth, newHeight, Color.BLACK, null);
|
||||
g.dispose();
|
||||
ImageIO.write(target, fileExtension != null ? fileExtension.getValueWithoutDot() : "jpeg", out);
|
||||
}
|
||||
|
||||
public byte[] getContentOfSize(Integer maxWidth, Integer maxHeight) {
|
||||
if (maxWidth == null && maxHeight == null) { return getContent(); }
|
||||
FileInputStream fis = null;
|
||||
try {
|
||||
fis = new FileInputStream(this.file);
|
||||
byte[] out = resizeImage(fis, maxWidth != null ? maxWidth : Integer.MAX_VALUE, maxHeight != null ? maxHeight
|
||||
: Integer.MAX_VALUE);
|
||||
return out;
|
||||
} catch (IOException ex) {
|
||||
return null;
|
||||
} finally {
|
||||
if (fis != null) {
|
||||
try {
|
||||
fis.close();
|
||||
} catch (IOException ex) {}
|
||||
}
|
||||
}
|
||||
return contentType;
|
||||
}
|
||||
|
||||
private void setImageContentType(String filename) {
|
||||
fileExtension = ContentRepositoryUtils.IMAGE_FILE_EXTENSION.JPEG;
|
||||
|
||||
if (StringUtils.endsWith(filename.toLowerCase(), ContentRepositoryUtils.IMAGE_FILE_EXTENSION.GIF.getValue())) {
|
||||
fileExtension = ContentRepositoryUtils.IMAGE_FILE_EXTENSION.GIF;
|
||||
} else if (StringUtils.endsWith(filename, ContentRepositoryUtils.IMAGE_FILE_EXTENSION.PNG.getValue())) {
|
||||
fileExtension = ContentRepositoryUtils.IMAGE_FILE_EXTENSION.PNG;
|
||||
}
|
||||
}
|
||||
|
||||
public void updateContent(final File file) {
|
||||
this.file = file;
|
||||
if (this.file != null) {
|
||||
setImageContentType(this.file.getName());
|
||||
}
|
||||
}
|
||||
|
||||
public String contentType() {
|
||||
return this.contentType;
|
||||
return ContentRepositoryUtils.IMAGE_MIME_TYPE.fromFileExtension(this.fileExtension).getValue();
|
||||
}
|
||||
|
||||
public StorageType storageType() {
|
||||
@@ -78,11 +139,6 @@ public class ImageData {
|
||||
this.inputStream = objectContent;
|
||||
}
|
||||
|
||||
public void updateContent(final File file) {
|
||||
this.file = file;
|
||||
setImageContentType();
|
||||
}
|
||||
|
||||
public String getEntityDisplayName() {
|
||||
return this.entityDisplayName;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user