package helpers; import java.awt.Color; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.nio.file.Files; import java.nio.file.StandardCopyOption; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import javax.imageio.ImageIO; import models.Image; import play.Logger; public class FileHelper { public final static String FILE_DIRECTORY = "data" + File.separator + "pictures"; public final static String THUMBS_DIRECTORY = "data" + File.separator + "thumbnails"; public final static String REFS_DIRECTORY = "data" + File.separator + "refs"; public final static String SOBEL_DIRECTORY = "data" + File.separator + "sobel"; public final static String COLORS_DIRECTORY = "data" + File.separator + "colors"; private FileHelper() { } public static Image save(final String filename, final File file, final String contentType) { checkFolders(); String checksum = null; try { checksum = getChecksum(MessageDigest.getInstance("SHA-256"), file); } catch (NoSuchAlgorithmException e) { Logger.error(e.getLocalizedMessage(), e); } catch (IOException e) { Logger.error(e.getLocalizedMessage(), e); } if (checksum != null && file != null && contentType.contains("image")) { String ext = contentType.replace("image/", "").trim(); File newFile = new File(FILE_DIRECTORY + File.separator + checksum + "." + ext); try { Files.copy(file.toPath(), newFile.toPath(), StandardCopyOption.REPLACE_EXISTING); } catch (IOException e) { Logger.error(e.getLocalizedMessage(), e); } Image img = Image.findOrCreate(checksum); img.extension = ext; img.imagePath = newFile.getAbsolutePath(); img.name = filename; File thumbnail = ImageHelper.thumbnail(img); if(thumbnail != null) { img.thumbnailPath = thumbnail.getAbsolutePath(); } File sobel = ImageHelper.edgeImage(img); if(sobel != null) { img.sobelImagePath = sobel.getAbsolutePath(); } try { Set dims = getDims(newFile); if(dims.size() == 2) { Iterator dimIter = dims.iterator(); img.imageHeight = dimIter.next(); img.imageWidth = dimIter.next(); } dims = getDims(thumbnail); if(dims.size() == 2) { Iterator dimIter = dims.iterator(); img.thumbnailHeight = dimIter.next(); img.thumbnailWidth = dimIter.next(); } File refImage = ImageHelper.referenceImage(img); if(refImage != null) { img.refImagePath = refImage.getAbsolutePath(); Color[][] signature = ImageHelper.createSignature(img); img.setSignature(signature); } } catch (IOException e) { Logger.error(e.getLocalizedMessage(), e); } img.save(); ImageHelper.countColors(img); return img; } return null; } private static Set getDims(final File file) throws IOException { Set dims = new HashSet<>(); if(file == null || !file.exists()) { return dims; } BufferedImage bimg = ImageIO.read(file); dims.add(bimg.getHeight()); dims.add(bimg.getWidth()); return dims; } private static String getChecksum(final MessageDigest digest, final File file) throws IOException { // Get file input stream for reading the file content FileInputStream fis = new FileInputStream(file); // Create byte array to read data in chunks byte[] byteArray = new byte[1024]; int bytesCount = 0; // Read file data and update in message digest while ((bytesCount = fis.read(byteArray)) != -1) { digest.update(byteArray, 0, bytesCount); } // close the stream; We don't need it now. fis.close(); // Get the hash's bytes byte[] bytes = digest.digest(); // This bytes[] has bytes in decimal format; // Convert it to hexadecimal format StringBuilder sb = new StringBuilder(); for (int i = 0; i < bytes.length; i++) { sb.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1)); } // return complete hash return sb.toString(); } private static void checkFolders() { final String[] folders = { FILE_DIRECTORY, THUMBS_DIRECTORY, COLORS_DIRECTORY, REFS_DIRECTORY, SOBEL_DIRECTORY }; for (String folder : folders) { File f = new File(folder); if (!f.exists()) { f.mkdirs(); } } } }