/**
  * 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;
 }
Exemple #9
0
 /** [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;
  }
Exemple #12
0
  @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);
 }