/** * Given a bufferedImage with a legend near the bottom (entire width of image), this replaces the * legend with white. * * @param bufferedImage * @return a bufferedImage without the legend. If trouble, this returns the original image. */ public static BufferedImage removeLegend(BufferedImage bufferedImage) { try { int lh[] = findLegendLH(bufferedImage); if (lh[0] == 0 && lh[1] == 0) return bufferedImage; Graphics g = bufferedImage.getGraphics(); g.setColor(Color.white); // white g.fillRect(0, lh[0], bufferedImage.getWidth(), lh[1] - lh[0] + 1); } catch (Throwable t) { String2.log(MustBe.throwableToString(t)); } return bufferedImage; }
/** * This returns a message indicating if graphics operations on bufferedImages are hardware * accelerated. */ public static String isBufferedImageAccelerated() { if (isBufferedImageAccelerated == null) { try { BufferedImage bi = getBufferedImage(10, 10); ImageCapabilities imCap = bi.getCapabilities(null); isBufferedImageAccelerated = "bufferedImage isAccelerated=" + (imCap == null ? "[unknown]" : imCap.isAccelerated()); } catch (Throwable t) { String2.log(MustBe.throwableToString(t)); isBufferedImageAccelerated = "bufferedImage isAccelerated=[unknown]"; } } return isBufferedImageAccelerated; }
/** Bob Simons added this to avoid memory leak problems. */ public void releaseResources() throws Exception { try { xloc_ = null; yloc_ = null; tloc_ = null; keyTitle_ = null; xMetaData_ = null; yMetaData_ = null; associatedData_ = null; xRange_ = null; yRange_ = null; changes_ = null; if (JPane.debug) String2.log("sgt.dm.SimpleLine.releaseResources() finished"); } catch (Throwable t) { String2.log(MustBe.throwableToString(t)); if (JPane.debug) String2.pressEnterToContinue(); } }
/** * Given a bufferedImage, this removes any whitespace more than 10 lines at the bottom. * * @param bufferedImage * @param borderWidth in pixels * @return a trimmed bufferedImage. If trouble, this returns the original image. */ public static BufferedImage trimBottom(BufferedImage bufferedImage, int borderWidth) { try { if (borderWidth < 0) borderWidth = 0; if (borderWidth > 1000) return bufferedImage; // find the first non-white pixel above bottom edge int width = bufferedImage.getWidth(); int height = bufferedImage.getHeight(); int y; Y_LOOP: for (y = height - 1; y >= 0; y--) { for (int x = 0; x < width; x++) { if (bufferedImage.getRGB(x, y) != 0xFFFFFFFF) break Y_LOOP; } } // if (verbose) String2.log("trimBottom y=" + y + " height=" + height); int newHeight = y + borderWidth + 1; if (y < 0 || newHeight >= height) return bufferedImage; BufferedImage newBI = getBufferedImage(width, newHeight); Graphics g = newBI.getGraphics(); g.drawImage( bufferedImage, 0, 0, width, newHeight, // dest params are exclusive 0, 0, width, newHeight, // source null); // documentation differs, but I think it blocks till finished if no observer return newBI; } catch (Throwable t) { String2.log(MustBe.throwableToString(t)); } return bufferedImage; }
/** * This is used when called from within a program. If args is null or args.length is 0, this * loops; otherwise it returns when done. * * @param args if args has values, they are used to answer the questions. * @returns the contents of outFileName (will be "" if trouble) */ public String doIt(String args[], boolean loop) throws Throwable { File2.safeRename(logFileName, logFileName + ".previous"); if (File2.isFile(outFileName)) { try { File2.rename(outFileName, outFileName + ".previous"); } catch (Throwable t) { File2.delete(outFileName); } } String2.setupLog( true, false, // toSystemOut, toSystemErr logFileName, false, // logToStringBuffer true, 20000000); // append String2.log( "*** Starting DasDds " + Calendar2.getCurrentISODateTimeStringLocal() + "\n" + "logFile=" + String2.logFileName() + "\n" + String2.standardHelpAboutMessage()); outFile = new FileWriter(outFileName); // default charset // delete the old log files (pre 1.48 names) File2.delete(EDStatic.fullLogsDirectory + "DasDdsLog.txt"); File2.delete(EDStatic.fullLogsDirectory + "DasDdsLog.txt.previous"); String datasetID = ""; if (args == null) args = new String[0]; // look for -verbose (and remove it) boolean verbose = false; // actually controls reallyVerbose int vi = String2.indexOf(args, "-verbose"); if (vi >= 0) { String2.log("verbose=true"); verbose = true; StringArray sa = new StringArray(args); sa.remove(vi); args = sa.toArray(); } do { // get the EDD type // EDD.reallyVerbose = false; //sometimes while testing datasetID = get( args, 0, "\n*** DasDds ***\n" + "This generates the DAS and DDS for a dataset and puts it in\n" + outFileName + "\n" + "Press ^D or ^C to exit at any time.\n\n" + "Which datasetID", datasetID); if (datasetID == null) { String2.flushLog(); outFile.flush(); outFile.close(); return String2.readFromFile(outFileName)[1]; } // delete the datasetInfo files for this datasetID (in case incorrect info) try { String dir = EDD.datasetDir(datasetID); String2.log( "dataset dir=" + dir + "\n" + "dataset n files not deleted = " + RegexFilenameFilter.regexDelete(dir, ".*", false)); } catch (Throwable t) { String2.log( "\n*** An error occurred while deleting the old info for " + datasetID + ":\n" + MustBe.throwableToString(t)); } try { printToBoth(EDD.testDasDds(datasetID, verbose)); } catch (Throwable t) { String2.log( "\n*** An error occurred while trying to load " + datasetID + ":\n" + MustBe.throwableToString(t)); } String2.flushLog(); } while (loop && args.length == 0); outFile.flush(); outFile.close(); String ret = String2.readFromFile(outFileName)[1]; String2.returnLoggingToSystemOut(); return ret; }
/** * Given a bufferedImage with a rectangular graph/map at the top, this returns the left, right, * bottom, top of the graph (from human perspective). Since y=0 at top of image, the returned top * value will be a lower value than bottom. * * @param bufferedImage * @return int[4] with left, right, bottom, top of the graph. If trouble, this returns null. */ public static int[] findGraph(BufferedImage bufferedImage) { // rely on this try/catch to catch errors try { int width = bufferedImage.getWidth(); int height = bufferedImage.getHeight(); int centerX = width / 2; // starting at top center, go down to first back pixel int top = 0; while (bufferedImage.getRGB(centerX, top) != 0xff000000 || // look at main pixel bufferedImage.getRGB(centerX - 1, top) != 0xff000000 || // and to left bufferedImage.getRGB(centerX + 1, top) != 0xff000000) { // and to right top++; // String2.log("top=" + top + " 0x" + Integer.toHexString(bufferedImage.getRGB(centerX, // top))); } // go left to left (may be fooled by tic mark) int left = centerX - 1; while (bufferedImage.getRGB(left - 1, top) == 0xff000000) { left--; // String2.log("left=" + left + " 0x" + Integer.toHexString(bufferedImage.getRGB(left-1, // top))); } // backtrack left if it was tic mark while (bufferedImage.getRGB(left, top + 1) != 0xff000000) { left++; // String2.log("backtrack left=" + left + " 0x" + // Integer.toHexString(bufferedImage.getRGB(left, top-1))); } // go right to right int right = centerX + 1; while (bufferedImage.getRGB(right + 1, top) == 0xff000000) { right++; // String2.log("right=" + right + " 0x" + Integer.toHexString(bufferedImage.getRGB(right+1, // top))); } // go down to bottom (may be fooled by tick mark) int bottom = top; while (bufferedImage.getRGB(left, bottom + 1) == 0xff000000 && bufferedImage.getRGB(right, bottom + 1) == 0xff000000) { bottom++; // String2.log("bottom=" + bottom + " 0x" + Integer.toHexString(bufferedImage.getRGB(left, // bottom-1))); } // backtrack bottom if it was tick mark while (bufferedImage.getRGB(left + 1, bottom) != 0xff000000 || bufferedImage.getRGB(right - 1, bottom) != 0xff000000) { bottom--; // String2.log("backtrack bottom=" + bottom + " 0x" + // Integer.toHexString(bufferedImage.getRGB(left+1, bottom))); } // don't bother to check integrity of bottom edge // String2.log("success " + left + " " + right + " " + bottom + " " + top); return new int[] {left, right, bottom, top}; } catch (Throwable t) { String2.log("SgtUtil.findGraph failed.\n" + MustBe.throwableToString(t)); return null; } }