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.Path;
|
||||||
import javax.ws.rs.PathParam;
|
import javax.ws.rs.PathParam;
|
||||||
import javax.ws.rs.Produces;
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.QueryParam;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
import javax.ws.rs.core.Response.ResponseBuilder;
|
import javax.ws.rs.core.Response.ResponseBuilder;
|
||||||
@@ -106,7 +107,10 @@ public class ImagesApiResource {
|
|||||||
@GET
|
@GET
|
||||||
@Consumes({ MediaType.TEXT_PLAIN, MediaType.TEXT_HTML, MediaType.APPLICATION_JSON })
|
@Consumes({ MediaType.TEXT_PLAIN, MediaType.TEXT_HTML, MediaType.APPLICATION_JSON })
|
||||||
@Produces({ MediaType.TEXT_PLAIN })
|
@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");
|
this.context.authenticatedUser().validateHasReadPermission("CLIENTIMAGE");
|
||||||
|
|
||||||
@@ -120,21 +124,23 @@ public class ImagesApiResource {
|
|||||||
imageDataURISuffix = ContentRepositoryUtils.IMAGE_DATA_URI_SUFFIX.PNG.getValue();
|
imageDataURISuffix = ContentRepositoryUtils.IMAGE_DATA_URI_SUFFIX.PNG.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
final String clientImageAsBase64Text = imageDataURISuffix + Base64.encodeBytes(imageData.getContent());
|
final String clientImageAsBase64Text = imageDataURISuffix + Base64.encodeBytes(imageData.getContentOfSize(maxWidth, maxHeight));
|
||||||
return clientImageAsBase64Text;
|
return Response.ok(clientImageAsBase64Text).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Consumes({ MediaType.APPLICATION_JSON })
|
@Consumes({ MediaType.APPLICATION_JSON })
|
||||||
@Produces({ MediaType.APPLICATION_OCTET_STREAM })
|
@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");
|
this.context.authenticatedUser().validateHasReadPermission("CLIENTIMAGE");
|
||||||
final ImageData imageData = this.imageReadPlatformService.retrieveClientImage(clientId);
|
final ImageData imageData = this.imageReadPlatformService.retrieveClientImage(clientId);
|
||||||
|
|
||||||
final ResponseBuilder response = Response.ok(imageData.getContent());
|
final ResponseBuilder response = Response.ok(imageData.getContentOfSize(maxWidth, maxHeight));
|
||||||
response.header("Content-Disposition", "attachment; filename=\"" + imageData.getEntityDisplayName() + IMAGE_FILE_EXTENSION.JPEG
|
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
|
// TODO: Need a better way of determining image type
|
||||||
|
|
||||||
|
|||||||
+31
@@ -28,6 +28,20 @@ public class ContentRepositoryUtils {
|
|||||||
public String getValue() {
|
public String getValue() {
|
||||||
return this.value;
|
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 {
|
public static enum IMAGE_FILE_EXTENSION {
|
||||||
@@ -42,6 +56,23 @@ public class ContentRepositoryUtils {
|
|||||||
public String getValue() {
|
public String getValue() {
|
||||||
return this.value;
|
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 {
|
public static enum IMAGE_DATA_URI_SUFFIX {
|
||||||
|
|||||||
+72
-16
@@ -1,9 +1,17 @@
|
|||||||
package org.mifosplatform.infrastructure.documentmanagement.data;
|
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.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.apache.poi.util.IOUtils;
|
import org.apache.poi.util.IOUtils;
|
||||||
@@ -19,7 +27,7 @@ public class ImageData {
|
|||||||
private final String entityDisplayName;
|
private final String entityDisplayName;
|
||||||
|
|
||||||
private File file;
|
private File file;
|
||||||
private String contentType;
|
private ContentRepositoryUtils.IMAGE_FILE_EXTENSION fileExtension;
|
||||||
private InputStream inputStream;
|
private InputStream inputStream;
|
||||||
|
|
||||||
public ImageData(final Long imageId, final String location, final Integer storageType, final String entityDisplayName) {
|
public ImageData(final Long imageId, final String location, final Integer storageType, final String entityDisplayName) {
|
||||||
@@ -43,23 +51,76 @@ public class ImageData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String setImageContentType() {
|
public byte[] resizeImage(InputStream in, int maxWidth, int maxHeight) throws IOException {
|
||||||
String contentType = ContentRepositoryUtils.IMAGE_MIME_TYPE.JPEG.getValue();
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
resizeImage(in, out, maxWidth, maxHeight);
|
||||||
|
return out.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
if (this.file != null) {
|
public void resizeImage(InputStream in, OutputStream out, int maxWidth, int maxHeight) throws IOException {
|
||||||
final String fileName = this.file.getName();
|
|
||||||
|
|
||||||
if (StringUtils.endsWith(fileName, ContentRepositoryUtils.IMAGE_FILE_EXTENSION.GIF.getValue())) {
|
BufferedImage src = ImageIO.read(in);
|
||||||
contentType = ContentRepositoryUtils.IMAGE_MIME_TYPE.GIF.getValue();
|
if (src.getWidth() <= maxWidth && src.getHeight() <= maxHeight) {
|
||||||
} else if (StringUtils.endsWith(fileName, ContentRepositoryUtils.IMAGE_FILE_EXTENSION.PNG.getValue())) {
|
out.write(getContent());
|
||||||
contentType = ContentRepositoryUtils.IMAGE_MIME_TYPE.PNG.getValue();
|
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() {
|
public String contentType() {
|
||||||
return this.contentType;
|
return ContentRepositoryUtils.IMAGE_MIME_TYPE.fromFileExtension(this.fileExtension).getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public StorageType storageType() {
|
public StorageType storageType() {
|
||||||
@@ -78,11 +139,6 @@ public class ImageData {
|
|||||||
this.inputStream = objectContent;
|
this.inputStream = objectContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateContent(final File file) {
|
|
||||||
this.file = file;
|
|
||||||
setImageContentType();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getEntityDisplayName() {
|
public String getEntityDisplayName() {
|
||||||
return this.entityDisplayName;
|
return this.entityDisplayName;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user