package eu.europeana.creative.dataset.pt.classification; import it.cnr.isti.vir.features.mpeg7.imageanalysis.ScalableColorPlusImpl; import java.awt.image.BufferedImage; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.Observable; import java.util.Observer; import javax.imageio.ImageIO; import org.apache.log4j.Logger; import eu.europeana.api.client.exception.TechnicalRuntimeException; import eu.europeana.api.client.thumbnails.ThumbnailsAccessor; import eu.europeana.api.client.thumbnails.processing.LargeThumbnailsetProcessing; public class GrayScaleSepiaDetector implements Observer { Logger log = Logger.getLogger(this.getClass()); File outputFile; File imageBaseFolder; int thresholdDominantColorShare, thresholdDominantColorCount; Map<String, String> thumbnailCategoryMap; //Set<String> reportedCategories; public GrayScaleSepiaDetector(File imageBaseFolder, int thresholdDominantColorShare, int thresholdDominantColorCount){ super(); this.imageBaseFolder = imageBaseFolder; this.thresholdDominantColorShare = thresholdDominantColorShare; this.thresholdDominantColorCount = thresholdDominantColorCount; } @Override public void update(Observable o, Object arg) { if(! (arg instanceof Map)) throw new TechnicalRuntimeException("Wrong argument type. Expected map but invoked with " + arg.getClass()); @SuppressWarnings("unchecked") Map<String, String> thumbnailMap = (Map<String, String>) arg; if(thumbnailCategoryMap == null){ thumbnailCategoryMap = new HashMap<String, String>(thumbnailMap.size()); }else{ thumbnailCategoryMap.clear(); } int failureCount = 0; File imageFile; String imageCategorization; BufferedImage image; ScalableColorPlusImpl featureExtractor; for (Map.Entry<String, String> thumbnail : thumbnailMap.entrySet()) { imageFile = getImageFile(thumbnail.getKey()); if(!imageFile.exists()){ imageCategorization = "not_available"; }else{ try{ featureExtractor = newFeatureExtractor(); image = ImageIO.read(imageFile); featureExtractor.extract(image); imageCategorization = featureExtractor.getCategory().toString(); }catch(Exception e){ imageCategorization = "error"; log.info( "Error: " + e.getMessage() + " for file: " + imageFile.getAbsolutePath()); log.debug(e); failureCount++; } } //all categories or selected categories //if(getReportedCategories() == null || getReportedCategories().contains(imageCategorization)) thumbnailCategoryMap.put(thumbnail.getKey(), imageCategorization); } writeCategoriesToFile(thumbnailMap); ((LargeThumbnailsetProcessing) o).increaseFailureCount(failureCount); } private void writeCategoriesToFile(Map<String, String> thumbnailMap) { if(!outputFile.exists()) outputFile.getParentFile().mkdirs(); BufferedWriter writer = null; try{ writer= new BufferedWriter(new FileWriter(outputFile, true)); for (Map.Entry<String, String> thumbnail : thumbnailMap.entrySet()) { writer.write(thumbnail.getKey()); writer.write(";"); writer.write(thumbnail.getValue()); writer.write(";"); writer.write(thumbnailCategoryMap.get(thumbnail.getKey())); writer.write("\n"); } writer.flush(); }catch(Exception e){ log.info("Failed to write thumbnail category to file", e); }finally{ try { if(writer != null) writer.close(); } catch (IOException e) { log.warn("cannot close file writer:", e); } } } private ScalableColorPlusImpl newFeatureExtractor() { ScalableColorPlusImpl featureExtractor = new ScalableColorPlusImpl(); featureExtractor.setThresholdDominantColorsShare(thresholdDominantColorShare); featureExtractor.setThresholdDominantColorsCount(thresholdDominantColorCount); return featureExtractor; } /** * this is duplication of {@link ThumbnailsAccessor#getImageFile(File, String)} * @param dir * @param id * @return */ public File getImageFile(String id) { String fileName = id + ".jpg"; File imageFile = new File(getImageBaseFolder(), fileName); return imageFile; } public File getImageBaseFolder() { return imageBaseFolder; } public Map<String, String> getThumbnailCategoryMap() { return thumbnailCategoryMap; } public File getOutputFile() { return outputFile; } public void setOutputFile(File outputFile) { this.outputFile = outputFile; } }