/** * Zooms out by making the source rectangle (srcRect) larger and centering it on (x,y). If we * can't make it larger, then make the window smaller. */ public void zoomOut(int x, int y) { if (magnification <= 0.03125) return; double oldMag = magnification; double newMag = getLowerZoomLevel(magnification); double srcRatio = (double) srcRect.width / srcRect.height; double imageRatio = (double) imageWidth / imageHeight; double initialMag = imp.getWindow().getInitialMagnification(); if (Math.abs(srcRatio - imageRatio) > 0.05) { double scale = oldMag / newMag; int newSrcWidth = (int) Math.round(srcRect.width * scale); int newSrcHeight = (int) Math.round(srcRect.height * scale); if (newSrcWidth > imageWidth) newSrcWidth = imageWidth; if (newSrcHeight > imageHeight) newSrcHeight = imageHeight; int newSrcX = srcRect.x - (newSrcWidth - srcRect.width) / 2; int newSrcY = srcRect.y - (newSrcHeight - srcRect.height) / 2; if (newSrcX < 0) newSrcX = 0; if (newSrcY < 0) newSrcY = 0; srcRect = new Rectangle(newSrcX, newSrcY, newSrcWidth, newSrcHeight); // IJ.log(newMag+" "+srcRect+" "+dstWidth+" "+dstHeight); int newDstWidth = (int) (srcRect.width * newMag); int newDstHeight = (int) (srcRect.height * newMag); setMagnification(newMag); setMaxBounds(); // IJ.log(newDstWidth+" "+dstWidth+" "+newDstHeight+" "+dstHeight); if (newDstWidth < dstWidth || newDstHeight < dstHeight) { // IJ.log("pack"); setDrawingSize(newDstWidth, newDstHeight); imp.getWindow().pack(); } else repaint(); return; } if (imageWidth * newMag > dstWidth) { int w = (int) Math.round(dstWidth / newMag); if (w * newMag < dstWidth) w++; int h = (int) Math.round(dstHeight / newMag); if (h * newMag < dstHeight) h++; x = offScreenX(x); y = offScreenY(y); Rectangle r = new Rectangle(x - w / 2, y - h / 2, w, h); if (r.x < 0) r.x = 0; if (r.y < 0) r.y = 0; if (r.x + w > imageWidth) r.x = imageWidth - w; if (r.y + h > imageHeight) r.y = imageHeight - h; srcRect = r; } else { srcRect = new Rectangle(0, 0, imageWidth, imageHeight); setDrawingSize((int) (imageWidth * newMag), (int) (imageHeight * newMag)); // setDrawingSize(dstWidth/2, dstHeight/2); imp.getWindow().pack(); } // IJ.write(newMag + " " + srcRect.x+" "+srcRect.y+" "+srcRect.width+" "+srcRect.height+" // "+dstWidth + " " + dstHeight); setMagnification(newMag); // IJ.write(srcRect.x + " " + srcRect.width + " " + dstWidth); setMaxBounds(); repaint(); }
private void drawScreenFrame(Graphics2D g2d, int scrId) { g2d.setColor(screenFrameColor); g2d.setStroke(strokeScreenFrame); if (screenFrame == null) { screenFrame = Screen.getBounds(scrId); Rectangle ubound = scrOCP.getBounds(); screenFrame.x -= ubound.x; screenFrame.y -= ubound.y; int sw = (int) (strokeScreenFrame.getLineWidth() / 2); screenFrame.x += sw; screenFrame.y += sw; screenFrame.width -= sw * 2; screenFrame.height -= sw * 2; } g2d.draw(screenFrame); }
private void drawSelection(Graphics2D g2d) { if (srcx != destx || srcy != desty) { int x1 = (srcx < destx) ? srcx : destx; int y1 = (srcy < desty) ? srcy : desty; int x2 = (srcx > destx) ? srcx : destx; int y2 = (srcy > desty) ? srcy : desty; rectSelection.x = x1; rectSelection.y = y1; rectSelection.width = (x2 - x1) + 1; rectSelection.height = (y2 - y1) + 1; if (rectSelection.width > 0 && rectSelection.height > 0) { g2d.drawImage(scr_img.getSubimage(x1, y1, x2 - x1 + 1, y2 - y1 + 1), null, x1, y1); } g2d.setColor(selFrameColor); g2d.setStroke(bs); g2d.draw(rectSelection); int cx = (x1 + x2) / 2; int cy = (y1 + y2) / 2; g2d.setColor(selCrossColor); g2d.setStroke(_StrokeCross); g2d.drawLine(cx, y1, cx, y2); g2d.drawLine(x1, cy, x2, cy); if (Screen.getNumberScreens() > 1) { drawScreenFrame(g2d, srcScreenId); } } }
/** Enlarge the canvas if the user enlarges the window. */ void resizeCanvas(int width, int height) { ImageWindow win = imp.getWindow(); // IJ.log("resizeCanvas: "+srcRect+" "+imageWidth+" "+imageHeight+" "+width+" "+height+" // "+dstWidth+" "+dstHeight+" "+win.maxBounds); if (!maxBoundsReset && (width > dstWidth || height > dstHeight) && win != null && win.maxBounds != null && width != win.maxBounds.width - 10) { if (resetMaxBoundsCount != 0) resetMaxBounds(); // Works around problem that prevented window from being larger than // maximized size resetMaxBoundsCount++; } if (IJ.altKeyDown()) { fitToWindow(); return; } if (srcRect.width < imageWidth || srcRect.height < imageHeight) { if (width > imageWidth * magnification) width = (int) (imageWidth * magnification); if (height > imageHeight * magnification) height = (int) (imageHeight * magnification); setDrawingSize(width, height); srcRect.width = (int) (dstWidth / magnification); srcRect.height = (int) (dstHeight / magnification); if ((srcRect.x + srcRect.width) > imageWidth) srcRect.x = imageWidth - srcRect.width; if ((srcRect.y + srcRect.height) > imageHeight) srcRect.y = imageHeight - srcRect.height; repaint(); } // IJ.log("resizeCanvas2: "+srcRect+" "+dstWidth+" "+dstHeight+" "+width+" "+height); }
public void zoomIn() { Dimension asz = this.getSize(); int maxzf = 3; int coef = 1; int r; cmdline = "/bin/sh get.sh " + j2kfilename + " " + iw + " " + ih + " " + rect.x + " " + rect.y + " " + rect.width + " " + rect.height; Exec.execPrint(cmdline); rect.x = rect.y = rect.width = rect.height = 0; img = pgm.open("out.pgm"); iw = img.getWidth(this); ih = img.getHeight(this); bi = new BufferedImage(iw, ih, BufferedImage.TYPE_INT_RGB); big = bi.createGraphics(); selected = 0; fullRefresh = true; repaint(); }
void adjustSourceRect(double newMag, int x, int y) { // IJ.log("adjustSourceRect1: "+newMag+" "+dstWidth+" "+dstHeight); int w = (int) Math.round(dstWidth / newMag); if (w * newMag < dstWidth) w++; int h = (int) Math.round(dstHeight / newMag); if (h * newMag < dstHeight) h++; x = offScreenX(x); y = offScreenY(y); Rectangle r = new Rectangle(x - w / 2, y - h / 2, w, h); if (r.x < 0) r.x = 0; if (r.y < 0) r.y = 0; if (r.x + w > imageWidth) r.x = imageWidth - w; if (r.y + h > imageHeight) r.y = imageHeight - h; srcRect = r; setMagnification(newMag); // IJ.log("adjustSourceRect2: "+srcRect+" "+dstWidth+" "+dstHeight); }
/* * Create a BufferedImage for AWT components. * * @param component AWT component to create image from * @param fileName name of file to be created or null * @return image the image for the given region * @exception AWTException see Robot class constructors * @exception IOException if an error occurs during writing */ public static BufferedImage createImage(Component component, String fileName) throws AWTException, IOException { Point p = new Point(0, 0); SwingUtilities.convertPointToScreen(p, component); Rectangle region = component.getBounds(); region.x = p.x; region.y = p.y; return ScreenCapture.createImage(region, fileName); }
public ScreenImage getSelection() { if (canceled) { return null; } BufferedImage cropImg = cropSelection(); if (cropImg == null) { return null; } rectSelection.x += scrOCP.getX(); rectSelection.y += scrOCP.getY(); ScreenImage ret = new ScreenImage(rectSelection, cropImg); return ret; }
/** [Internal] */ public void paintComponent(Graphics g) { boolean opq = true; if (theOpaque != null) opq = theOpaque; super.setOpaque(opq); // if(theBackground!=null)super.setBackground(theBackground); super.paintComponent(g); Graphics2D g2 = (Graphics2D) g; Rectangle rt = getBounds(); rt.x = 0; rt.y = 0; doBuffer(g2, opq, rt); chkFPS(); }
protected void scroll(int sx, int sy) { int ox = xSrcStart + (int) (sx / magnification); // convert to offscreen coordinates int oy = ySrcStart + (int) (sy / magnification); // IJ.log("scroll: "+ox+" "+oy+" "+xMouseStart+" "+yMouseStart); int newx = xSrcStart + (xMouseStart - ox); int newy = ySrcStart + (yMouseStart - oy); if (newx < 0) newx = 0; if (newy < 0) newy = 0; if ((newx + srcRect.width) > imageWidth) newx = imageWidth - srcRect.width; if ((newy + srcRect.height) > imageHeight) newy = imageHeight - srcRect.height; srcRect.x = newx; srcRect.y = newy; // IJ.log(sx+" "+sy+" "+newx+" "+newy+" "+srcRect); imp.draw(); Thread.yield(); }
/** Processes the data and renders it to a component */ public synchronized int process(Buffer buffer) { if (component == null) return BUFFER_PROCESSED_FAILED; Format inf = buffer.getFormat(); if (inf == null) return BUFFER_PROCESSED_FAILED; if (inf != inputFormat || !buffer.getFormat().equals(inputFormat)) { if (setInputFormat(inf) != null) return BUFFER_PROCESSED_FAILED; } Object data = buffer.getData(); if (!(data instanceof int[])) return BUFFER_PROCESSED_FAILED; if (lastBuffer != buffer) { lastBuffer = buffer; newImage(buffer); } sourceImage.newPixels(0, 0, inWidth, inHeight); Graphics g = component.getGraphics(); if (g != null) { if (reqBounds == null) { bounds = component.getBounds(); bounds.x = 0; bounds.y = 0; } else bounds = reqBounds; g.drawImage( destImage, bounds.x, bounds.y, bounds.width, bounds.height, 0, 0, inWidth, inHeight, component); } return BUFFER_PROCESSED_OK; }
@Override public ScreenImage capture(Rectangle rect) { Debug.log(5, "capture: " + rect); BufferedImage ret = new BufferedImage(rect.width, rect.height, BufferedImage.TYPE_INT_RGB); Graphics2D g2d = ret.createGraphics(); for (int i = 0; i < Screen.getNumberScreens(); i++) { Rectangle scrBound = Screen.getBounds(i); if (scrBound.intersects(rect)) { Rectangle inter = scrBound.intersection(rect); Debug.log(5, "scrBound: " + scrBound + ", inter: " + inter); int ix = inter.x, iy = inter.y; inter.x -= scrBound.x; inter.y -= scrBound.y; ScreenImage img = robots[i].captureScreen(inter); g2d.drawImage(img.getImage(), ix - rect.x, iy - rect.y, null); } } g2d.dispose(); return new ScreenImage(rect, ret); }
/** * Gets the template location at which the best match occurs in a rectangle and along a line. May * return null. * * @param target the image to search * @param searchRect the rectangle to search within the target image * @param x0 the x-component of a point on the line * @param y0 the y-component of a point on the line * @param slope the slope of the line * @param spread the spread of the line (line width = 1+2*spread) * @return the optimized template location of the best match, if any */ public TPoint getMatchLocation( BufferedImage target, Rectangle searchRect, double x0, double y0, double theta, int spread) { wTarget = target.getWidth(); hTarget = target.getHeight(); // determine insets needed to accommodate template int left = wTemplate / 2, right = left; if (wTemplate % 2 > 0) right++; int top = hTemplate / 2, bottom = top; if (hTemplate % 2 > 0) bottom++; // trim search rectangle if necessary searchRect.x = Math.max(left, Math.min(wTarget - right, searchRect.x)); searchRect.y = Math.max(top, Math.min(hTarget - bottom, searchRect.y)); searchRect.width = Math.min(wTarget - searchRect.x - right, searchRect.width); searchRect.height = Math.min(hTarget - searchRect.y - bottom, searchRect.height); if (searchRect.width <= 0 || searchRect.height <= 0) { peakHeight = Double.NaN; peakWidth = Double.NaN; return null; } // set up test pixels to search (rectangle plus template) int xMin = Math.max(0, searchRect.x - left); int xMax = Math.min(wTarget, searchRect.x + searchRect.width + right); int yMin = Math.max(0, searchRect.y - top); int yMax = Math.min(hTarget, searchRect.y + searchRect.height + bottom); wTest = xMax - xMin; hTest = yMax - yMin; if (target.getType() != BufferedImage.TYPE_INT_RGB) { BufferedImage image = new BufferedImage(wTarget, hTarget, BufferedImage.TYPE_INT_RGB); image.createGraphics().drawImage(target, 0, 0, null); target = image; } targetPixels = new int[wTest * hTest]; target.getRaster().getDataElements(xMin, yMin, wTest, hTest, targetPixels); // get the points to search along the line ArrayList<Point2D> searchPts = getSearchPoints(searchRect, x0, y0, theta); if (searchPts == null) { peakHeight = Double.NaN; peakWidth = Double.NaN; return null; } // collect differences in a map as they are measured HashMap<Point2D, Double> diffs = new HashMap<Point2D, Double>(); // find the point with the minimum difference from template double matchDiff = largeNumber; // larger than typical differences int xMatch = 0, yMatch = 0; double avgDiff = 0; Point2D matchPt = null; for (Point2D pt : searchPts) { int x = (int) pt.getX(); int y = (int) pt.getY(); double diff = getDifferenceAtTestPoint(x, y); diffs.put(pt, diff); avgDiff += diff; if (diff < matchDiff) { matchDiff = diff; xMatch = x; yMatch = y; matchPt = pt; } } avgDiff /= searchPts.size(); peakHeight = avgDiff / matchDiff - 1; peakWidth = Double.NaN; double dl = 0; int matchIndex = searchPts.indexOf(matchPt); // if match is not exact, fit a Gaussian and find peak if (!Double.isInfinite(peakHeight) && matchIndex > 0 && matchIndex < searchPts.size() - 1) { // fill data arrays Point2D pt = searchPts.get(matchIndex - 1); double diff = diffs.get(pt); xValues[0] = -pt.distance(matchPt); yValues[0] = avgDiff / diff - 1; xValues[1] = 0; yValues[1] = peakHeight; pt = searchPts.get(matchIndex + 1); diff = diffs.get(pt); xValues[2] = pt.distance(matchPt); yValues[2] = avgDiff / diff - 1; // determine approximate offset (dl) and width (w) values double pull = -xValues[0] / (yValues[1] - yValues[0]); double push = xValues[2] / (yValues[1] - yValues[2]); if (Double.isNaN(pull)) pull = LARGE_NUMBER; if (Double.isNaN(push)) push = LARGE_NUMBER; dl = 0.3 * (xValues[2] - xValues[0]) * (push - pull) / (push + pull); double ratio = dl > 0 ? peakHeight / yValues[0] : peakHeight / yValues[2]; double w = dl > 0 ? dl - xValues[0] : dl - xValues[2]; w = w * w / Math.log(ratio); // set parameters and fit to x data dataset.clear(); dataset.append(xValues, yValues); double rmsDev = 1; for (int k = 0; k < 3; k++) { double c = k == 0 ? w : k == 1 ? w / 3 : w * 3; f.setParameterValue(0, peakHeight); f.setParameterValue(1, dl); f.setParameterValue(2, c); rmsDev = fitter.fit(f); if (rmsDev < 0.01) { // fitter succeeded (3-point fit should be exact) dl = f.getParameterValue(1); peakWidth = f.getParameterValue(2); break; } } } double dx = dl * Math.cos(theta); double dy = dl * Math.sin(theta); double xImage = xMatch + searchRect.x - left - trimLeft + dx; double yImage = yMatch + searchRect.y - top - trimTop + dy; return new TPoint(xImage, yImage); }
/** * Gets the template location at which the best match occurs in a rectangle. May return null. * * @param target the image to search * @param searchRect the rectangle to search within the target image * @return the optimized template location at which the best match, if any, is found */ public TPoint getMatchLocation(BufferedImage target, Rectangle searchRect) { wTarget = target.getWidth(); hTarget = target.getHeight(); // determine insets needed to accommodate template int left = wTemplate / 2, right = left; if (wTemplate % 2 > 0) right++; int top = hTemplate / 2, bottom = top; if (hTemplate % 2 > 0) bottom++; // trim search rectangle if necessary searchRect.x = Math.max(left, Math.min(wTarget - right, searchRect.x)); searchRect.y = Math.max(top, Math.min(hTarget - bottom, searchRect.y)); searchRect.width = Math.min(wTarget - searchRect.x - right, searchRect.width); searchRect.height = Math.min(hTarget - searchRect.y - bottom, searchRect.height); if (searchRect.width <= 0 || searchRect.height <= 0) { peakHeight = Double.NaN; peakWidth = Double.NaN; return null; } // set up test pixels to search (rectangle plus template) int xMin = Math.max(0, searchRect.x - left); int xMax = Math.min(wTarget, searchRect.x + searchRect.width + right); int yMin = Math.max(0, searchRect.y - top); int yMax = Math.min(hTarget, searchRect.y + searchRect.height + bottom); wTest = xMax - xMin; hTest = yMax - yMin; if (target.getType() != BufferedImage.TYPE_INT_RGB) { BufferedImage image = new BufferedImage(wTarget, hTarget, BufferedImage.TYPE_INT_RGB); image.createGraphics().drawImage(target, 0, 0, null); target = image; } targetPixels = new int[wTest * hTest]; target.getRaster().getDataElements(xMin, yMin, wTest, hTest, targetPixels); // find the rectangle point with the minimum difference double matchDiff = largeNumber; // larger than typical differences int xMatch = 0, yMatch = 0; double avgDiff = 0; for (int x = 0; x <= searchRect.width; x++) { for (int y = 0; y <= searchRect.height; y++) { double diff = getDifferenceAtTestPoint(x, y); avgDiff += diff; if (diff < matchDiff) { matchDiff = diff; xMatch = x; yMatch = y; } } } avgDiff /= (searchRect.width * searchRect.height); peakHeight = avgDiff / matchDiff - 1; peakWidth = Double.NaN; double dx = 0, dy = 0; // if match is not exact, fit a Gaussian and find peak if (!Double.isInfinite(peakHeight)) { // fill data arrays xValues[1] = yValues[1] = peakHeight; for (int i = -1; i < 2; i++) { if (i == 0) continue; double diff = getDifferenceAtTestPoint(xMatch + i, yMatch); xValues[i + 1] = avgDiff / diff - 1; diff = getDifferenceAtTestPoint(xMatch, yMatch + i); yValues[i + 1] = avgDiff / diff - 1; } // estimate peakHeight = peak of gaussian // estimate offset dx of gaussian double pull = 1 / (xValues[1] - xValues[0]); double push = 1 / (xValues[1] - xValues[2]); if (Double.isNaN(pull)) pull = LARGE_NUMBER; if (Double.isNaN(push)) push = LARGE_NUMBER; dx = 0.6 * (push - pull) / (push + pull); // estimate width wx of gaussian double ratio = dx > 0 ? peakHeight / xValues[0] : peakHeight / xValues[2]; double wx = dx > 0 ? dx + 1 : dx - 1; wx = wx * wx / Math.log(ratio); // estimate offset dy of gaussian pull = 1 / (yValues[1] - yValues[0]); push = 1 / (yValues[1] - yValues[2]); if (Double.isNaN(pull)) pull = LARGE_NUMBER; if (Double.isNaN(push)) push = LARGE_NUMBER; dy = 0.6 * (push - pull) / (push + pull); // estimate width wy of gaussian ratio = dy > 0 ? peakHeight / yValues[0] : peakHeight / yValues[2]; double wy = dy > 0 ? dy + 1 : dy - 1; wy = wy * wy / Math.log(ratio); // set x parameters and fit to x data dataset.clear(); dataset.append(pixelOffsets, xValues); double rmsDev = 1; for (int k = 0; k < 3; k++) { double c = k == 0 ? wx : k == 1 ? wx / 3 : wx * 3; f.setParameterValue(0, peakHeight); f.setParameterValue(1, dx); f.setParameterValue(2, c); rmsDev = fitter.fit(f); if (rmsDev < 0.01) { // fitter succeeded (3-point fit should be exact) dx = f.getParameterValue(1); peakWidth = f.getParameterValue(2); break; } } if (!Double.isNaN(peakWidth)) { // set y parameters and fit to y data dataset.clear(); dataset.append(pixelOffsets, yValues); for (int k = 0; k < 3; k++) { double c = k == 0 ? wy : k == 1 ? wy / 3 : wy * 3; f.setParameterValue(0, peakHeight); f.setParameterValue(1, dx); f.setParameterValue(2, c); rmsDev = fitter.fit(f); if (rmsDev < 0.01) { // fitter succeeded (3-point fit should be exact) dy = f.getParameterValue(1); peakWidth = (peakWidth + f.getParameterValue(2)) / 2; break; } } if (rmsDev > 0.01) peakWidth = Double.NaN; } } double xImage = xMatch + searchRect.x - left - trimLeft + dx; double yImage = yMatch + searchRect.y - top - trimTop + dy; return new TPoint(xImage, yImage); }
public void setRGeom(int x1, int y1, int x2, int y2) { rect.x = Math.min(x1, x2) - offset.x; rect.y = Math.min(y1, y2) - offset.y; rect.width = Math.abs(x2 - x1); rect.height = Math.abs(y2 - y1); }