/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package omr.util; import java.awt.Rectangle; import java.io.File; import java.io.PrintWriter; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.Collection; import java.util.List; import java.util.Properties; import java.util.regex.*; import omr.CLI; import omr.Main; import omr.score.Score; import omr.score.entity.Measure; import omr.score.entity.Page; import omr.score.entity.PageNode; import omr.score.entity.ScorePart; import omr.score.entity.ScoreSystem; import omr.score.entity.SystemPart; import omr.score.ui.ScoreController; import omr.sheet.SystemInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Given the current page, creates an XML dump of the system, parts, and * measures providing their coordinates and dimensions based upon just as they * appear on the scanned image, not as they might appear in a rendering * of a Score. This is for create overlays on the scans themselves. * * @author jlpoole */ public class ExportCoordinates { private Score myScore; /** Usual logger utility. */ private static final Logger logger = LoggerFactory.getLogger(ExportCoordinates.class); private String indent = ""; private int defaultIndentSpace = 2; private Pattern p = Pattern.compile("^(.*)\\.(tiff?|png)$", Pattern.CASE_INSENSITIVE); SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss z"); // // Constructors // public ExportCoordinates() { myScore = ScoreController.getCurrentScore(); } public ExportCoordinates(Score s) { myScore = s; } // // Methods // public void export(){ export(false); } public void export(boolean debug){ String xmlFile = null; PrintWriter xmlWriter = null; Calendar calobj = Calendar.getInstance(); // // Create an output file with the same name, but ".xml" suffix // String imageFile = myScore.getImageFile().getName(); String imageDir = myScore.getImageFile().getParentFile().getAbsolutePath(); // // if the Command Line Interface ("CLI") specified "-option exportdir ..." // then we'll overide the directory // Properties cliProps = Main.getCliConstants(); String exportDir = cliProps.getProperty("exportdir"); if (exportDir != null){ // verify the directory path exists File dir = new File(exportDir); if (dir.exists()){ imageDir = exportDir; } else { logger.error ("Directory not found for option 'exportDir' " + "having a value of '" + exportDir + "' provided in command line," + " Aborting export of coordinates."); return; } } if (debug) logger.info("imageFile = " + imageFile); if (debug) logger.info("imageDir = " + imageDir); Matcher m = p.matcher(imageFile); boolean outToFile = m.find(); if (outToFile){ xmlFile = m.group(1); xmlFile = imageDir + File.separator + xmlFile; try { xmlWriter = new PrintWriter(xmlFile + ".xml", "UTF-8"); } catch (Exception e) { logger.info("Could not open output file: " + xmlFile); } } else { logger.info("Could not derive file from " + imageFile); } int systemId, partId, measureId = 0; String xmlOut = ""; if (debug) logger.info("myScore.getImagePath = {}",myScore.getImagePath()); // what is the current page ? // TODO: Danger need to identify current Page! Page currentPage = myScore.getFirstPage(); List currentSystems = currentPage.getSystems(); xmlOut += indent + "<page id=\"" + myScore.getImagePath() + "\" "; xmlOut += indent + "\nomrDate=\"" + sdf.format(calobj.getTime()) + "\" "; xmlOut += indent + "\nimageLastModified=\"" + sdf.format(myScore.getImageFile().lastModified()) + "\" "; // // TODO: add version of Libreveris, in case we want to rerun OMR // later on with a revised version. // TODO: extract form TIFF/PNG the resolution, time of creation? // xmlOut = closeElement(xmlOut); increaseIndent(); for (systemId = 0; systemId < currentSystems.size();systemId++) { ScoreSystem curSystem = (ScoreSystem) currentSystems.get(systemId); xmlOut += indent + "<system id=\"" + curSystem.getId() + "\""; Rectangle systemRect = curSystem.getBox(); xmlOut += getRectangleAttributes(systemRect); xmlOut = closeElement(xmlOut); List currentParts = curSystem.getParts(); increaseIndent(); for (partId = 0; partId < currentParts.size(); partId++){ SystemPart curPart = (SystemPart) currentParts.get(partId); xmlOut += indent + "<part id=\"" + curPart.getId() + "\""; Rectangle partRect = curPart.getBox(); xmlOut += getRectangleAttributes(partRect); xmlOut = closeElement(xmlOut); List myMeasures = curPart.getMeasures(); increaseIndent(); for (measureId = 0; measureId < myMeasures.size(); measureId++){ Measure curMeasure = (Measure) myMeasures.get(measureId); xmlOut += " <measure id=\"" + curMeasure.getIdValue() + "\""; if (debug) logger.info("id = {}",curMeasure.getIdValue()); Rectangle measureRect = curMeasure.getBox(); if (debug) logger.info(" rect.x = {}", measureRect.x); if (debug) logger.info(" rect.y = {}", measureRect.y); xmlOut += getRectangleAttributes(measureRect); xmlOut = closeElementSingle(xmlOut); } xmlOut += endElement("part"); } xmlOut += endElement("system"); } xmlOut += endElement("page"); if (debug) logger.info(xmlOut); if (outToFile){ xmlWriter.print(xmlOut); xmlWriter.close(); } } private String getRectangleAttributes (Rectangle r){ String attrs = ""; attrs+= " x=\"" + r.x + "\" y=\"" + r.y + "\"" + " width=\"" + r.width + "\" height=\"" + r.height + "\""; return attrs; } /** * For elements which will have closing tags afterwards * @param e Element name. * @return Element name + ">" and new line */ private String closeElement(String e){ return e + ">\n"; } /** * For elements which will have no children. * @param e Element name. * @return Element name + "/>" and new line */ private String closeElementSingle(String e){ return e + "/>\n"; } private String endElement (String e){ decreaseIndent(); String s = indent + "</" + e + ">\n"; return s; } private void increaseIndent(){ increaseIndent(defaultIndentSpace); } /** * * @param x Augment number of spaces desired for indentation. */ private void increaseIndent(int x){ if (indent.endsWith("")){ for (int i = 0; i < x; i++){ indent += " "; } } else { for (int i = 0; i < x; i++){ indent = indent.replaceFirst(".?$"," "); } } } private void decreaseIndent(){ decreaseIndent(defaultIndentSpace); } /** * * @param x Number of spaces to be removed from indentation string. */ private void decreaseIndent(int x){ for (int i = 0; i < x; i++){ indent = indent.replaceFirst(".?$",""); } } }