/**
* Copyright © 2002 Instituto Superior Técnico
*
* This file is part of FenixEdu Academic.
*
* FenixEdu Academic is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* FenixEdu Academic is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with FenixEdu Academic. If not, see <http://www.gnu.org/licenses/>.
*/
package org.fenixedu.academic.dto.person;
import java.awt.color.CMMException;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.util.Base64;
import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import org.fenixedu.academic.util.ContentType;
import org.fenixedu.academic.util.FileUtils;
import com.google.common.io.BaseEncoding;
import com.google.common.io.ByteStreams;
public class PhotographUploadBean implements Serializable {
public static class UnableToProcessTheImage extends Exception {
private static final long serialVersionUID = 1728978041377445492L;
}
private static final long serialVersionUID = 1207257680390113173L;
private static final int OUTPUT_PHOTO_WIDTH = 100;
private static final int OUTPUT_PHOTO_HEIGHT = 100;
private transient byte[] rawContents;
private transient byte[] compressedContents;
private File temporaryFile;
private File tempCompressedFile;
private String filename;
private String contentType;
private String base64RawThumbnail;
private String base64RawContent;
private String username;
public InputStream getFileInputStream() throws FileNotFoundException {
if (base64RawContent != null && base64RawThumbnail != null) {
this.rawContents = BaseEncoding.base64().decode(base64RawContent);
this.compressedContents = BaseEncoding.base64().decode(base64RawThumbnail);
return new ByteArrayInputStream(rawContents);
}
if (rawContents != null) {
return new ByteArrayInputStream(rawContents);
}
if (temporaryFile != null) {
return new FileInputStream(temporaryFile);
} else {
return null;
}
}
public String getBase64Photo() throws IOException {
try (InputStream stream = getFileInputStream()) {
return Base64.getEncoder().encodeToString(ByteStreams.toByteArray(stream));
}
}
public void setFileInputStream(InputStream inputStream) throws IOException {
this.rawContents = (inputStream != null) ? ByteStreams.toByteArray(inputStream) : null;
}
public String getBase64RawThumbnail() {
return base64RawThumbnail;
}
public void setBase64RawThumbnail(String base64RawThumbnail) {
this.base64RawThumbnail = base64RawThumbnail;
}
public String getBase64RawContent() {
return base64RawContent;
}
public void setBase64RawContent(String base64RawContent) {
this.base64RawContent = base64RawContent;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public InputStream getCompressedInputStream() throws FileNotFoundException {
if (compressedContents != null) {
return new ByteArrayInputStream(compressedContents);
}
if (tempCompressedFile != null) {
return new FileInputStream(tempCompressedFile);
} else {
return null;
}
}
public int getRawSize() {
return rawContents.length;
}
public String getFilename() {
return filename;
}
public void setFilename(String filename) {
this.filename = filename;
}
public void createTemporaryFiles() throws IOException {
temporaryFile = rawContents != null ? FileUtils.copyToTemporaryFile(new ByteArrayInputStream(rawContents)) : null;
tempCompressedFile =
compressedContents != null ? FileUtils.copyToTemporaryFile(new ByteArrayInputStream(compressedContents)) : null;
}
public File getTemporaryFile() {
return temporaryFile;
}
public File getTempCompressedFile() {
return tempCompressedFile;
}
public void deleteTemporaryFiles() {
if (temporaryFile != null) {
temporaryFile.delete();
}
if (tempCompressedFile != null) {
tempCompressedFile.delete();
}
}
public String getContentType() {
return contentType;
}
public void setContentType(String contentType) {
this.contentType = contentType;
}
public void processImage() throws IOException, UnableToProcessTheImage {
if (base64RawContent != null && base64RawThumbnail != null) {
return;
}
try {
BufferedImage image = ImageIO.read(new ByteArrayInputStream(rawContents));
if (image == null) {
throw new UnableToProcessTheImage();
}
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
// calculate resize factor
double resizeFactor =
Math.min((double) OUTPUT_PHOTO_WIDTH / image.getWidth(), (double) OUTPUT_PHOTO_HEIGHT / image.getHeight());
if (resizeFactor == 1) {
compressedContents = rawContents;
} else {
// resize image
AffineTransform tx = new AffineTransform();
tx.scale(resizeFactor, resizeFactor);
AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
image = op.filter(image, null);
// set compression
ImageWriter writer =
ImageIO.getImageWritersByMIMEType(ContentType.getContentType(contentType).getMimeType()).next();
ImageWriteParam param = writer.getDefaultWriteParam();
if (contentType.equals(ContentType.JPG)) {
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
param.setCompressionQuality(1);
}
// write to stream
writer.setOutput(ImageIO.createImageOutputStream(outputStream));
writer.write(null, new IIOImage(image, null, null), param);
compressedContents = outputStream.toByteArray();
}
} catch (final CMMException ex) {
throw new UnableToProcessTheImage();
}
}
}