Exemplo n.º 1
0
    public BufferedImage getGridImage() {
      if (rendered) return gridImage;

      if (!loaded) throw new Loading();

      gridImage = TexI.mkbuf(cmaps);

      BufferedImage[] texes = new BufferedImage[256];

      Coord c = new Coord();
      for (c.y = 0; c.y < cmaps.y; c.y++) {
        for (c.x = 0; c.x < cmaps.x; c.x++) {
          int t = gettile(c);
          BufferedImage tex = tileimg(t, texes);
          if (tex != null)
            gridImage.setRGB(
                c.x,
                c.y,
                tex.getRGB(
                    Utils.floormod(c.x, tex.getWidth()), Utils.floormod(c.y, tex.getHeight())));
        }
      }
      for (c.y = 1; c.y < cmaps.y - 1; c.y++) {
        for (c.x = 1; c.x < cmaps.x - 1; c.x++) {
          int t = gettile(c);
          if ((gettile(c.add(-1, 0)) > t)
              || (gettile(c.add(1, 0)) > t)
              || (gettile(c.add(0, -1)) > t)
              || (gettile(c.add(0, 1)) > t)) gridImage.setRGB(c.x, c.y, Color.BLACK.getRGB());
        }
      }
      rendered = true;
      return gridImage;
    }
Exemplo n.º 2
0
 private void clearPlane() {
   int black = Color.BLACK.getRGB();
   synchronized (LOCKER) {
     for (int i = 0; i < pixels.length; i++) {
       pixels[i] = black;
     }
   }
 }
Exemplo n.º 3
0
 // Bildfarben invertieren
 public void invert() {
   for (int y = 0; y < this.h; y++) {
     for (int x = 0; x < this.w; x++) {
       if (isActive(x, y)) this.setRGB(x, y, Color.WHITE.getRGB());
       else this.setRGB(x, y, Color.BLACK.getRGB());
     }
   }
 }
Exemplo n.º 4
0
 @Override
 public void setBackground(Color c) {
   if (txt_box == null)
     return; // WORKAROUND.OSX: OSX LookAndFeel calls setBackground during ctor of Mem_html;
   // DATE:2015-05-11
   if (c.getRGB() == Color.BLACK.getRGB()) txt_box.setCaretColor(Color.WHITE);
   else if (c.getRGB() == Color.WHITE.getRGB()) txt_box.setCaretColor(Color.BLACK);
   super.setBackground(c);
 }
Exemplo n.º 5
0
 /* Color.toString() is not great so we need a way to convert a
  * Color to some easily readable format, since we only
  * support black, white, blue, green, red, & yellow we can
  * easily check these by looking at the RGB values of the
  * color found by calling Color.getRGB().
  */
 public String colorToString(Color color) {
   if (color.getRGB() == Color.BLACK.getRGB()) {
     return "Black";
   } else if (color.getRGB() == Color.BLUE.getRGB()) {
     return "Blue";
   } else if (color.getRGB() == Color.GREEN.getRGB()) {
     return "Green";
   } else if (color.getRGB() == Color.RED.getRGB()) {
     return "Red";
   } else if (color.getRGB() == Color.YELLOW.getRGB()) {
     return "Yellow";
   } else {
     return "No Color Information";
   }
 }
Exemplo n.º 6
0
 public BufferedImage drawmap(Coord ul, Coord sz) {
   BufferedImage[] texes = new BufferedImage[256];
   MCache m = ui.sess.glob.map;
   BufferedImage buf = TexI.mkbuf(sz);
   Coord c = new Coord();
   for (c.y = 0; c.y < sz.y; c.y++) {
     for (c.x = 0; c.x < sz.x; c.x++) {
       int t = m.gettile(ul.add(c));
       BufferedImage tex = tileimg(t, texes);
       int rgb = 0;
       if (tex != null)
         rgb =
             tex.getRGB(
                 Utils.floormod(c.x + ul.x, tex.getWidth()),
                 Utils.floormod(c.y + ul.y, tex.getHeight()));
       buf.setRGB(c.x, c.y, rgb);
     }
   }
   for (c.y = 1; c.y < sz.y - 1; c.y++) {
     for (c.x = 1; c.x < sz.x - 1; c.x++) {
       int t = m.gettile(ul.add(c));
       Tiler tl = m.tiler(t);
       if (tl instanceof Ridges.RidgeTile) {
         if (Ridges.brokenp(m, ul.add(c))) {
           for (int y = c.y - 1; y <= c.y + 1; y++) {
             for (int x = c.x - 1; x <= c.x + 1; x++) {
               Color cc = new Color(buf.getRGB(x, y));
               buf.setRGB(
                   x,
                   y,
                   Utils.blendcol(cc, Color.BLACK, ((x == c.x) && (y == c.y)) ? 1 : 0.1).getRGB());
             }
           }
         }
       }
     }
   }
   for (c.y = 0; c.y < sz.y; c.y++) {
     for (c.x = 0; c.x < sz.x; c.x++) {
       int t = m.gettile(ul.add(c));
       if ((m.gettile(ul.add(c).add(-1, 0)) > t)
           || (m.gettile(ul.add(c).add(1, 0)) > t)
           || (m.gettile(ul.add(c).add(0, -1)) > t)
           || (m.gettile(ul.add(c).add(0, 1)) > t)) buf.setRGB(c.x, c.y, Color.BLACK.getRGB());
     }
   }
   return (buf);
 }
Exemplo n.º 7
0
 public Component getTableCellRendererComponent(
     JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
   Component comp =
       super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
   if (value != null && highlight(table, value, isSelected, hasFocus, row, column)) {
     if (isSelected) {
       comp.setBackground(new Color((HIGHLIGHT_COLOR.getRGB() ^ comp.getBackground().getRGB())));
       comp.setForeground(new Color(Color.BLACK.getRGB() ^ comp.getForeground().getRGB()));
     } else {
       comp.setBackground(HIGHLIGHT_COLOR);
       comp.setForeground(Color.BLACK);
     }
   } else {
     if (!isSelected) {
       comp.setBackground(Color.WHITE);
       comp.setForeground(Color.BLACK);
     }
   }
   return comp;
 }
  private int[][] seeBMPImage(File file) throws IOException {
    BufferedImage image = ImageIO.read(file);

    int[][] array2D = new int[image.getHeight()][image.getWidth()];

    for (int xPixel = 0; xPixel < image.getWidth(); xPixel++) {
      for (int yPixel = 0; yPixel < image.getHeight(); yPixel++) {
        int color = image.getRGB(xPixel, yPixel);
        if (color == Color.BLACK.getRGB()) {
          //                    array2D[xPixel][yPixel] = 1;
          array2D[yPixel][xPixel] = 1;
        } else {
          //                    array2D[xPixel][yPixel] = 0; // ?
          array2D[yPixel][xPixel] = 0;
        }
      }
    }

    return array2D;
  }
Exemplo n.º 9
0
  public void encode(String str, String path, int width, int height) {
    try {
      Map hints = new HashMap();
      hints.put(EncodeHintType.MARGIN, 0);
      // hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
      hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
      hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
      BitMatrix byteMatrix =
          new MultiFormatWriter().encode(str, BarcodeFormat.QR_CODE, width, height, hints);

      /** tianboalei 2015-1-22 去掉生成二维码时周围的白圈 */
      // 1
      int[] rec = byteMatrix.getEnclosingRectangle();
      int resWidth = rec[2] + 1;
      int resHeight = rec[3] + 1;
      BitMatrix resMatrix = new BitMatrix(resWidth, resHeight);
      resMatrix.clear();
      for (int i = 0; i < resWidth; i++) {
        for (int j = 0; j < resHeight; j++) {
          if (byteMatrix.get(i + rec[0], j + rec[1])) {
            resMatrix.set(i, j);
          }
        }
      }
      // 2
      int widthT = resMatrix.getWidth();
      int heightT = resMatrix.getHeight();
      BufferedImage image = new BufferedImage(widthT, heightT, BufferedImage.TYPE_INT_ARGB);
      for (int x = 0; x < widthT; x++) {
        for (int y = 0; y < heightT; y++) {
          image.setRGB(
              x, y, resMatrix.get(x, y) == true ? Color.BLACK.getRGB() : Color.WHITE.getRGB());
        }
      }
      /** 去掉二维码周围白圈结束 */
      File file = new File(path);
      writeToFile(resMatrix, "png", file);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
Exemplo n.º 10
0
  /**
   * Returns a list of nine-patch data intervals from the specified image.
   *
   * @param image nin-patch image to process
   * @param intervalType intervals type
   * @return list of nine-patch data intervals from the specified image
   */
  public static List<NinePatchInterval> parseIntervals(
      final BufferedImage image, final NinePatchIntervalType intervalType) {
    final boolean hv =
        intervalType.equals(NinePatchIntervalType.horizontalStretch)
            || intervalType.equals(NinePatchIntervalType.verticalStretch);
    final int l =
        (intervalType.equals(NinePatchIntervalType.horizontalStretch)
                    || intervalType.equals(NinePatchIntervalType.horizontalContent)
                ? image.getWidth()
                : image.getHeight())
            - 1;

    final List<NinePatchInterval> intervals = new ArrayList<NinePatchInterval>();
    NinePatchInterval interval = null;
    boolean pixelPart;
    for (int i = 1; i < l; i++) {
      final int rgb;
      switch (intervalType) {
        case horizontalStretch:
          rgb = image.getRGB(i, 0);
          break;
        case verticalStretch:
          rgb = image.getRGB(0, i);
          break;
        case horizontalContent:
          rgb = image.getRGB(i, image.getHeight() - 1);
          break;
        case verticalContent:
          rgb = image.getRGB(image.getWidth() - 1, i);
          break;
        default:
          rgb = 0;
          break;
      }

      pixelPart = rgb != Color.BLACK.getRGB();
      if (interval == null) {
        // Initial interval
        interval = new NinePatchInterval(i - 1, i - 1, pixelPart);
      } else if (pixelPart == interval.isPixel()) {
        // Enlarge interval
        interval.setEnd(i - 1);
      } else if (pixelPart != interval.isPixel()) {
        // Add pixel interval only for stretch types and nonpixel for
        // any type
        if (hv || !interval.isPixel()) {
          intervals.add(interval);
        }
        // New interval starts
        interval = new NinePatchInterval(i - 1, i - 1, pixelPart);
      }
    }
    if (interval != null) {
      // Add pixel interval only for stretch types and nonpixel for any
      // type
      if (hv || !interval.isPixel()) {
        intervals.add(interval);
      }
    }
    return intervals;
  }
/** Created by Xiaxing SHI on 21/11/15. */
public class BasicPainter implements Painter, DrawingSource {
  private String name = "My Painting";
  private ColorRBG color = new ColorRBG(Color.BLACK.getRGB());
  private Pencil pencil = new Pencil(1, color);
  private Canvas canvas = new Canvas(1024, 1024);
  private boolean isAWT = true, isSVG = true;

  private ArrayList<Shape> shapes = new ArrayList<Shape>();

  @Override
  public void setName(String name) {
    if (name != null) this.name = name;
  }

  @Override
  public void setCanvasSize(int width, int height) {
    this.canvas.setWidth(width);
    this.canvas.setHeight(height);
  }

  @Override
  public void setShowInWindow(boolean isWindow) {
    this.isAWT = isWindow;
  }

  @Override
  public void setSaveAsSVG(boolean isSvg) {
    this.isSVG = isSvg;
  }

  @Override
  public void stroke(int width, Color color) {
    this.pencil = new Pencil(width, new ColorRBG((color.getRGB())));
  }

  @Override
  public void fill(Color color) {
    this.color = new ColorRBG(color.getRGB());
  }

  @Override
  public void circle(int x, int y, int r) {
    Circle c = new Circle(x, y, r);
    addToShapes(c);
  }

  @Override
  public void ellipse(int x, int y, int rx, int ry) {
    Ellipse e = new Ellipse(x, y, rx, ry);
    addToShapes(e);
  }

  @Override
  public void line(int x1, int y1, int x2, int y2) {
    Line l = new Line(x1, y1, x2, y2);
    addToShapes(l);
  }

  @Override
  public void path(LineType type, Point... points) {
    if (points.length == 0) {
      return;
    }

    Point start = points[0];
    ArrayList<PathPart> parts = new ArrayList<PathPart>();
    ArrayList<Point> pts = new ArrayList<Point>(Arrays.asList(points));
    pts.remove(0); // Remove the start point

    parts.add(new PathPart(pts, type));
    Path p = new Path(start, parts);
    addToShapes(p);
  }

  @Override
  public void path(Point start, LineType[] types, Point[][] points) {
    if (types.length != points.length) {
      return;
    }

    Path p = new Path();
    p.setStart(start);

    ArrayList<PathPart> parts = new ArrayList<PathPart>();
    for (int i = 0; i < types.length; ++i) {
      parts.add(new PathPart(types[i], points[i]));
    }
    p.setParts(parts);

    addToShapes(p);
  }

  @Override
  public void polygon(Point... points) {
    ArrayList<Point> pts = new ArrayList<Point>(Arrays.asList(points));

    Polygon p = new Polygon(pts);
    addToShapes(p);
  }

  @Override
  public void polyline(Point... points) {
    ArrayList<Point> pts = new ArrayList<Point>(Arrays.asList(points));

    Polyline p = new Polyline(pts);
    addToShapes(p);
  }

  @Override
  public void rectangle(int x, int y, int width, int height) {
    Rectangle r = new Rectangle(x, y, height, width);
    addToShapes(r);
  }

  @Override
  public void text(int x, int y, String text) {
    Text t = new Text(x, y, text);
    addToShapes(t);
  }

  @Override
  public String getName() {
    return this.name;
  }

  @Override
  public Canvas getCanvas() {
    return this.canvas;
  }

  @Override
  public ArrayList<Shape> getShapes() {
    return this.shapes;
  }

  @Override
  public boolean isShowInWindow() {
    return this.isAWT;
  }

  @Override
  public boolean isSaveAsSVG() {
    return this.isSVG;
  }

  private void addToShapes(Shape shape) {
    shape.setColor(color);
    shape.setPencil(pencil);
    shapes.add(shape);
  }
}
Exemplo n.º 12
0
/**
 * A font in an Image Markup document that originates from a born-digital source, e.g. a
 * born-digital PDF document.
 *
 * @author sautter
 */
public class ImFont implements ImObject {

  /** the name of the attribute holding the font name */
  public static final String NAME_ATTRIBUTE = "name";

  /** the name of the attribute holding the font style */
  public static final String STYLE_ATTRIBUTE = "style";

  /** the name of the attribute holding character IDs */
  public static final String CHARACTER_ID_ATTRIBUTE = "charId";

  /** the name of the attribute holding character strings */
  public static final String CHARACTER_STRING_ATTRIBUTE = "charString";

  /** the name of the attribute holding character images */
  public static final String CHARACTER_IMAGE_ATTRIBUTE = "charImage";

  /** the name of the attribute indicating if the font is serif or sans-serif */
  public static final String SERIF_ATTRIBUTE = "serif";

  /**
   * the name of the attribute to a word storing the font specific char codes the word was composed
   * from
   */
  public static final String CHARACTER_CODE_STRING_ATTRIBUTE = "fontCharCodes";

  private ImDocument doc;

  /** the name of the font */
  public final String name;

  private boolean bold;
  private boolean italics;
  private boolean serif;

  private TreeMap characters = new TreeMap();

  /**
   * Constructor
   *
   * @param doc the Image Markup document the font belongs to
   * @param name the font name
   */
  public ImFont(ImDocument doc, String name) {
    this(doc, name, false, false, true);
  }

  /**
   * Constructor
   *
   * @param doc the Image Markup document the font belongs to
   * @param name the font name
   * @param bold is the font bold?
   * @param italics is the font in italics?
   * @param serif is the font serif or sans-serif?
   */
  public ImFont(ImDocument doc, String name, boolean bold, boolean italics, boolean serif) {
    this.doc = doc;
    this.name = name;
    this.bold = bold;
    this.italics = italics;
    this.serif = serif;
  }

  /* (non-Javadoc)
   * @see de.uka.ipd.idaho.gamta.Attributed#setAttribute(java.lang.String)
   */
  public void setAttribute(String name) {
    if (BOLD_ATTRIBUTE.equals(name)) this.setBold(true);
    else if (ITALICS_ATTRIBUTE.equals(name)) this.setItalics(true);
    else if (SERIF_ATTRIBUTE.equals(name)) this.setSerif(true);
  }

  /* (non-Javadoc)
   * @see de.uka.ipd.idaho.gamta.Attributed#setAttribute(java.lang.String, java.lang.Object)
   */
  public Object setAttribute(String name, Object value) {
    if (BOLD_ATTRIBUTE.equals(name)) {
      boolean wasBold = this.isBold();
      this.setBold(value != null);
      return new Boolean(wasBold);
    } else if (ITALICS_ATTRIBUTE.equals(name)) {
      boolean wasItalics = this.isItalics();
      this.setItalics(value != null);
      return new Boolean(wasItalics);
    } else if (SERIF_ATTRIBUTE.equals(name)) {
      boolean wasSerif = this.isSerif();
      this.setSerif(value != null);
      return new Boolean(wasSerif);
    } else if (name.startsWith(CHARACTER_STRING_ATTRIBUTE + "-") && (value instanceof String)) {
      int charId = Integer.parseInt(name.substring((CHARACTER_STRING_ATTRIBUTE + "-").length()));
      String oCharStr = this.getString(charId);
      this.addCharacter(charId, ((String) value), ((BufferedImage) null));
      return oCharStr;
    } else if (name.startsWith(CHARACTER_IMAGE_ATTRIBUTE + "-")
        && (value instanceof BufferedImage)) {
      int charId = Integer.parseInt(name.substring((CHARACTER_IMAGE_ATTRIBUTE + "-").length()));
      BufferedImage oCharImage = this.getImage(charId);
      this.addCharacter(charId, null, ((BufferedImage) value));
      return oCharImage;
    } else return null;
  }

  /* (non-Javadoc)
   * @see de.uka.ipd.idaho.gamta.Attributed#copyAttributes(de.uka.ipd.idaho.gamta.Attributed)
   */
  public void copyAttributes(Attributed source) {
    /* we're not doing this here, as attributes are only to allow for generic undo management */
  }

  /* (non-Javadoc)
   * @see de.uka.ipd.idaho.gamta.Attributed#getAttribute(java.lang.String)
   */
  public Object getAttribute(String name) {
    return this.getAttribute(name, null);
  }

  /* (non-Javadoc)
   * @see de.uka.ipd.idaho.gamta.Attributed#getAttribute(java.lang.String, java.lang.Object)
   */
  public Object getAttribute(String name, Object def) {
    if (BOLD_ATTRIBUTE.equals(name)) return new Boolean(this.isBold());
    else if (ITALICS_ATTRIBUTE.equals(name)) return new Boolean(this.isItalics());
    else if (SERIF_ATTRIBUTE.equals(name)) return new Boolean(this.isSerif());
    else if (name.startsWith(CHARACTER_STRING_ATTRIBUTE + "-")) {
      int charId = Integer.parseInt(name.substring((CHARACTER_STRING_ATTRIBUTE + "-").length()));
      return this.getString(charId);
    } else if (name.startsWith(CHARACTER_IMAGE_ATTRIBUTE + "-")) {
      int charId = Integer.parseInt(name.substring((CHARACTER_IMAGE_ATTRIBUTE + "-").length()));
      return this.getImage(charId);
    } else return def;
  }

  /* (non-Javadoc)
   * @see de.uka.ipd.idaho.gamta.Attributed#hasAttribute(java.lang.String)
   */
  public boolean hasAttribute(String name) {
    return (BOLD_ATTRIBUTE.equals(name)
        || ITALICS_ATTRIBUTE.equals(name)
        || SERIF_ATTRIBUTE.equals(name));
  }

  /* (non-Javadoc)
   * @see de.uka.ipd.idaho.gamta.Attributed#getAttributeNames()
   */
  public String[] getAttributeNames() {
    String[] ans = {BOLD_ATTRIBUTE, ITALICS_ATTRIBUTE, SERIF_ATTRIBUTE};
    return ans;
  }

  /* (non-Javadoc)
   * @see de.uka.ipd.idaho.gamta.Attributed#removeAttribute(java.lang.String)
   */
  public Object removeAttribute(String name) {
    if (BOLD_ATTRIBUTE.equals(name)) {
      boolean wasBold = this.isBold();
      this.setBold(false);
      return new Boolean(wasBold);
    } else if (ITALICS_ATTRIBUTE.equals(name)) {
      boolean wasItalics = this.isItalics();
      this.setItalics(false);
      return new Boolean(wasItalics);
    } else if (SERIF_ATTRIBUTE.equals(name)) {
      boolean wasSerif = this.isSerif();
      this.setSerif(false);
      return new Boolean(wasSerif);
    } else return null;
  }

  /* (non-Javadoc)
   * @see de.uka.ipd.idaho.gamta.Attributed#clearAttributes()
   */
  public void clearAttributes() {
    /* we're not doing this here, as attributes are only to allow for generic undo management */
  }

  /* (non-Javadoc)
   * @see de.uka.ipd.idaho.im.ImObject#getType()
   */
  public String getType() {
    return "font";
  }

  /* (non-Javadoc)
   * @see de.uka.ipd.idaho.im.ImObject#setType(java.lang.String)
   */
  public void setType(String type) {}

  /* (non-Javadoc)
   * @see de.uka.ipd.idaho.im.ImObject#getDocument()
   */
  public ImDocument getDocument() {
    return this.doc;
  }

  /* (non-Javadoc)
   * @see de.uka.ipd.idaho.im.ImObject#getDocumentProperty(java.lang.String)
   */
  public String getDocumentProperty(String propertyName) {
    return this.doc.getDocumentProperty(propertyName);
  }

  /* (non-Javadoc)
   * @see de.uka.ipd.idaho.im.ImObject#getDocumentProperty(java.lang.String, java.lang.String)
   */
  public String getDocumentProperty(String propertyName, String defaultValue) {
    return this.doc.getDocumentProperty(propertyName, defaultValue);
  }

  /* (non-Javadoc)
   * @see de.uka.ipd.idaho.im.ImObject#getDocumentPropertyNames()
   */
  public String[] getDocumentPropertyNames() {
    return this.doc.getDocumentPropertyNames();
  }

  /**
   * Test whether or not the font is bold.
   *
   * @return true if the font is bold, false otherwise
   */
  public boolean isBold() {
    return this.bold;
  }

  /**
   * Mark the font as bold or non-bold.
   *
   * @param bold is the font bold?
   */
  public void setBold(boolean bold) {
    if (this.bold == bold) return;
    this.bold = bold;
    this.doc.notifyAttributeChanged(this, BOLD_ATTRIBUTE, (this.bold ? null : "true"));
  }

  /**
   * Test whether or not the font is in italics.
   *
   * @return true if the font is in italics, false otherwise
   */
  public boolean isItalics() {
    return this.italics;
  }

  /**
   * Mark the font as italics or non-italics.
   *
   * @param italics is the font in italics?
   */
  public void setItalics(boolean italics) {
    if (this.italics == italics) return;
    this.italics = italics;
    this.doc.notifyAttributeChanged(this, ITALICS_ATTRIBUTE, (this.italics ? null : "true"));
  }

  /**
   * Test whether the font is serif or sans-serif.
   *
   * @return true if the font is serif, false otherwise
   */
  public boolean isSerif() {
    return this.serif;
  }

  /**
   * Mark the font as serif or sans-serif.
   *
   * @param serif is the font serif?
   */
  public void setSerif(boolean serif) {
    if (this.serif == serif) return;
    this.serif = serif;
    this.doc.notifyAttributeChanged(this, SERIF_ATTRIBUTE, (this.serif ? null : "true"));
  }

  /**
   * Retrieve the number of characters in the font.
   *
   * @return the number of characters
   */
  public int getCharacterCount() {
    return this.characters.size();
  }

  /**
   * Add a character to the font. The character string is supposed to hold a Unicode representation
   * of the character, preferably one consisting of individual letters, digits, symbols, or
   * punctuation marks, rather than ligature characters or the like. The returned boolean indicates
   * if the font was modified, i.e., if a character was added or modified as a result of the call to
   * this method.
   *
   * @param charId the font-local ID of the character
   * @param charStr the Unicode representation of the character
   * @return true if the font was modified, false otherwise
   */
  public boolean addCharacter(int charId, String charStr) {
    return this.addCharacter(charId, charStr, ((BufferedImage) null));
  }

  /**
   * Add a character to the font. The character string is supposed to hold a Unicode representation
   * of the character, preferably one consisting of individual letters, digits, symbols, or
   * punctuation marks, rather than ligature characters or the like. The argument character image is
   * the glyph corresponding to the character in the source document, if any is explicitly given
   * there; it allows for users to double-check and modify the transcription of glyphs to Unicode
   * characters. The character image string is parsed as a hex encoding of a 32 pixel high
   * black-and-white bitmap. The returned boolean indicates if the font was modified, i.e., if a
   * character was added or modified as a result of the call to this method.
   *
   * @param charId the font-local ID of the character
   * @param charStr the Unicode representation of the character
   * @param charImageHex the character image as extracted from the source
   * @return true if the font was modified, false otherwise
   */
  public boolean addCharacter(int charId, String charStr, String charImageHex) {
    return this.addCharacter(charId, charStr, decodeCharacterImage(charImageHex));
  }

  /**
   * Add a character to the font. The character string is supposed to hold a Unicode representation
   * of the character, preferably one consisting of individual letters, digits, symbols, or
   * punctuation marks, rather than ligature characters or the like. The argument character image is
   * the glyph corresponding to the character in the source document, if any is explicitly given
   * there; it allows for users to double-check and modify the transcription of glyphs to Unicode
   * characters. The character image should be a black-and-white bitmap, 32 pixels high, with width
   * allowed to adjust proportionally in accordance to the glyph dimensions. The returned boolean
   * indicates if the font was modified, i.e., if a character was added or modified as a result of
   * the call to this method.
   *
   * @param charId the font-local ID of the character
   * @param charStr the Unicode representation of the character
   * @param charImage the character image as extracted from the source
   * @return true if the font was modified, false otherwise
   */
  public boolean addCharacter(int charId, String charStr, BufferedImage charImage) {
    ImCharacter chr = ((ImCharacter) this.characters.get(new Integer(charId)));
    if (chr == null) {
      chr = new ImCharacter(charId, charStr, charImage);
      this.characters.put(new Integer(chr.id), chr);
      return true;
    }
    boolean modified = false;
    if ((charStr != null) && !charStr.equals(chr.str)) {
      modified = true;
      String oCharStr = chr.str;
      chr.str = charStr;
      this.doc.notifyAttributeChanged(this, (CHARACTER_STRING_ATTRIBUTE + "-" + charId), oCharStr);
    }
    if ((charImage != null) && !characterImagesEqual(charImage, chr.image)) {
      modified = true;
      BufferedImage oCharImage = chr.image;
      chr.image = charImage;
      this.doc.notifyAttributeChanged(this, (CHARACTER_IMAGE_ATTRIBUTE + "-" + charId), oCharImage);
    }
    return modified;
  }

  /**
   * Retrieve the Unicode string representing a character.
   *
   * @param charId the font-local ID of the character
   * @return the Unicode string of the character with the argument ID
   */
  public String getString(int charId) {
    ImCharacter chr = ((ImCharacter) this.characters.get(new Integer(charId)));
    return ((chr == null) ? null : chr.str);
  }

  /**
   * Retrieve the glyph image for a character.
   *
   * @param charId the font-local ID of the character
   * @return the glyph image of the character with the argument ID
   */
  public BufferedImage getImage(int charId) {
    ImCharacter chr = ((ImCharacter) this.characters.get(new Integer(charId)));
    return ((chr == null) ? null : chr.image);
  }

  /**
   * Retrieve the hex representation of the glyph image for a character.
   *
   * @param charId the font-local ID of the character
   * @return the hex representation glyph image of the character with the argument ID
   */
  public String getImageHex(int charId) {
    ImCharacter chr = ((ImCharacter) this.characters.get(new Integer(charId)));
    return ((chr == null) ? null : encodeCharacterImage(chr.image));
  }

  /**
   * Retrieve the IDs of all characters belonging to the font.
   *
   * @return an array holding the character IDs
   */
  public int[] getCharacterIDs() {
    int[] charIDs = new int[this.characters.size()];
    int charIdIndex = 0;
    for (Iterator cidit = this.characters.keySet().iterator(); cidit.hasNext(); )
      charIDs[charIdIndex++] = ((Integer) cidit.next()).intValue();
    return charIDs;
  }

  private static class ImCharacter {
    int id;
    String str;
    BufferedImage image;

    ImCharacter(int id, String str, BufferedImage image) {
      this.id = id;
      this.str = str;
      this.image = image;
    }
  }

  private static final int whiteRgb = Color.WHITE.getRGB();
  private static final int blackRgb = Color.BLACK.getRGB();

  private static BufferedImage decodeCharacterImage(String charImageHex) {
    if (charImageHex == null) return null;
    int charImageWidth = (charImageHex.length() / 8);
    if (charImageWidth == 0) return null;

    BufferedImage charImage = new BufferedImage(charImageWidth, 32, BufferedImage.TYPE_BYTE_BINARY);
    int x = 0;
    int y = 0;
    int hex;
    int hexMask;
    for (int h = 0; h < charImageHex.length(); h++) {
      hex = Integer.parseInt(charImageHex.substring(h, (h + 1)), 16);
      hexMask = 8;
      while (hexMask != 0) {
        charImage.setRGB(x++, y, (((hex & hexMask) == 0) ? whiteRgb : blackRgb));
        hexMask >>= 1;
        if (x == charImageWidth) {
          x = 0;
          y++;
        }
      }
    }

    return charImage;
  }

  private static String encodeCharacterImage(BufferedImage charImage) {
    if (charImage == null) return null;

    int hex = 0;
    int hexBits = 0;
    StringBuffer charImageHex = new StringBuffer();
    for (int y = 0; y < charImage.getHeight(); y++)
      for (int x = 0; x < charImage.getWidth(); x++) {
        if (charImage.getRGB(x, y) != whiteRgb) hex += 1;
        if (hexBits == 3) {
          charImageHex.append(Integer.toString(hex, 16).toUpperCase());
          hex = 0;
          hexBits = 0;
        } else {
          hex <<= 1;
          hexBits++;
        }
      }

    return charImageHex.toString();
  }

  private static boolean characterImagesEqual(BufferedImage ci1, BufferedImage ci2) {
    if (ci1 == ci2) return true;
    if ((ci1 == null) || (ci2 == null)) return false;
    if ((ci1.getWidth() != ci2.getWidth()) || (ci1.getHeight() != ci2.getHeight())) return false;
    for (int x = 0; x < ci1.getWidth(); x++)
      for (int y = 0; y < ci1.getHeight(); y++) {
        if (ci1.getRGB(x, y) != ci2.getRGB(x, y)) return false;
      }
    return true;
  }

  /**
   * Scale a character image to 32 pixels high and proportional width. If the argument image already
   * is 32 pixels in height, it is simply returned. In any case, the type of the returned image is
   * the same as that of the argument image.
   *
   * @param charImage the character image to scale
   * @return the scaled character image
   */
  public static BufferedImage scaleCharImage(BufferedImage charImage) {
    if ((charImage == null) || (charImage.getHeight() == 32)) return charImage;
    BufferedImage sCharImage =
        new BufferedImage(
            Math.max(1, ((charImage.getWidth() * 32) / charImage.getHeight())),
            32,
            charImage.getType());
    Graphics2D sCiGr = sCharImage.createGraphics();
    sCiGr.setColor(Color.WHITE);
    sCiGr.fillRect(0, 0, sCharImage.getWidth(), sCharImage.getHeight());
    sCiGr.scale((32.0 / charImage.getHeight()), (32.0 / charImage.getHeight()));
    sCiGr.drawImage(charImage, 0, 0, null);
    sCiGr.dispose();
    //		JOptionPane.showMessageDialog(null, new JLabel(new ImageIcon(charImage)), ("Scaled " +
    // charImage.getWidth() + "x" + charImage.getHeight() + " to " + sCharImage.getWidth() + "x" +
    // sCharImage.getHeight()), JOptionPane.PLAIN_MESSAGE, new ImageIcon(sCharImage));
    return sCharImage;
  }
}
Exemplo n.º 13
0
  /**
   * Overrides the Runnable run method. Checks an image to see if it contains a Sign Language letter
   * and identifies the letter if true.
   */
  @Override
  public void run() {
    Random r = new Random();
    int currentResult = this.result;

    while (true) {

      /*
       * This is the normal sleep that relaxes the CPU a bit and
       * lets other threads run fluently.
       */
      try {
        Thread.sleep(100);
      } catch (InterruptedException ex) {
        ex.printStackTrace();
      }

      while (this.algorithmRunning) {

        if (this.capturedImageChanged) {
          synchronized (this.lockObject) {
            this.capturedImageChanged = false;
          }

          /*
           * This is where the Algorithm method will be called (possibly other classes involded).
           * For now, instead a simple sleep will be called as simulation.
           *
           *   try {
           *       Thread.sleep(5000);
           *   } catch (InterruptedException ex) {
           *       ex.printStackTrace();
           *   }
           */

          /*
           * Let's see.
           * Processing and information aquiring part.
           */
          if (this.siblingEye == null) {
            continue;
          }
          BufferedImage capturedIm = this.siblingEye.getImage();
          // System.out.format("Brain: capIm's with is %d and height is %d\n",
          // capturedIm.getWidth(), capturedIm.getHeight());
          if (capturedIm == null) {
            continue;
          }
          double ar =
              (double) (EyeWebcam.HAND_CUT_X2 - EyeWebcam.HAND_CUT_X1)
                  / (EyeWebcam.HAND_CUT_Y2 - EyeWebcam.HAND_CUT_Y1);
          // System.out.format("Brain: aspect ratio = %.2f\n", ar);
          int camImWidth, camImHeight;
          int cutX1 = EyeWebcam.HAND_CUT_X1;
          int cutX2 = EyeWebcam.HAND_CUT_X2;
          int cutY1 = EyeWebcam.HAND_CUT_Y1;
          int cutY2 = EyeWebcam.HAND_CUT_Y2;
          if (ar < DBImage.DB_IMAGE_ASPECT_RATIO) {
            camImWidth = (int) Math.round(DBImage.DB_IMAGE_HEIGHT * ar);
            camImHeight = DBImage.DB_IMAGE_HEIGHT;
            double cutHeight =
                (EyeWebcam.HAND_CUT_Y2
                        - EyeWebcam.HAND_CUT_Y1
                        - (EyeWebcam.HAND_CUT_X2 - EyeWebcam.HAND_CUT_X1)
                            / DBImage.DB_IMAGE_ASPECT_RATIO)
                    / 2;
            cutY1 = (int) (EyeWebcam.HAND_CUT_Y1 + cutHeight);
            cutY2 = (int) (EyeWebcam.HAND_CUT_Y2 - cutHeight);
          } else {
            camImWidth = DBImage.DB_IMAGE_WIDTH;
            camImHeight = (int) Math.round(DBImage.DB_IMAGE_WIDTH / ar);
            double cutWidth =
                (EyeWebcam.HAND_CUT_X2
                        - EyeWebcam.HAND_CUT_X1
                        - (EyeWebcam.HAND_CUT_Y2 - EyeWebcam.HAND_CUT_Y1)
                            * DBImage.DB_IMAGE_ASPECT_RATIO)
                    / 2;
            cutX1 = (int) (EyeWebcam.HAND_CUT_X1 + cutWidth);
            cutX2 = (int) (EyeWebcam.HAND_CUT_X2 - cutWidth);
          }
          // System.out.format("Brain: camImWidth = %d, camImHeight = %d\n", camImWidth,
          // camImHeight);
          // System.out.format("Brain: cutX2 = %d, cutX1 = %d, cutY2 = %d, cutY1 = %d\n", cutX2,
          // cutX1, cutY2, cutY1);
          // System.out.format("Brain: cutX2 - cutX1 / cutY2 - cutY1 = %.3f\n", (double) (cutX2 -
          // cutX1) / (cutY2 - cutY1));
          int[][] cutResizedGrayIntIm =
              ImageAlgorithms.buffIm2CutGrayResizedIntIm(
                  capturedIm,
                  cutX1,
                  cutY1,
                  cutX2,
                  cutY2,
                  DBImage.DB_IMAGE_WIDTH,
                  DBImage.DB_IMAGE_HEIGHT);
          if (cutResizedGrayIntIm == null) {
            continue;
          }
          GrayImageAndHistogram contourIntImAndHistogram =
              ImageAlgorithms.grayIntIm2ContourImAndHistogram(
                  cutResizedGrayIntIm, DBImage.CONTOUR_POWER);
          int[][] contourIntIm = contourIntImAndHistogram.getGrayImage();
          int[] histogram = contourIntImAndHistogram.getHistogram();
          int threshold =
              ImageAlgorithms.computeNecessaryThreshold(
                  DBImage.WHITE_PROPORTION, histogram, camImWidth * camImHeight);
          // System.out.format("Brain: threshold = %d\n", threshold);
          boolean[][] camBoolIm = ImageAlgorithms.grayIntIm2BoolIm(contourIntIm, threshold);
          this.processedImage =
              ImageAlgorithms.boolIm2BuffIm(camBoolIm, Color.BLACK.getRGB(), Color.WHITE.getRGB());
          Shape greatestShape = ImageAlgorithms.findGreatestShape(camBoolIm);
          // System.out.format("Brain: greatestShape's area is %d\n", greatestShape.getArea());

          Point2D leftMostPoint = greatestShape.getLeftMostPoint();
          Point2D rightMostPoint = greatestShape.getRightMostPoint();
          Point2D bottomMostPoint = greatestShape.getBottomMostPoint();
          Point2D topMostPoint = greatestShape.getTopMostPoint();

          Shape leftShape =
              ImageAlgorithms.reduceShapeHVAreaLimit(
                  greatestShape, leftMostPoint, DBImage.HV_THINNESS, true, DBImage.HV_AREA_LIMIT);
          Shape rightShape =
              ImageAlgorithms.reduceShapeHVAreaLimit(
                  greatestShape, rightMostPoint, DBImage.HV_THINNESS, true, DBImage.HV_AREA_LIMIT);
          Shape topShape =
              ImageAlgorithms.reduceShapeHVAreaLimit(
                  greatestShape, topMostPoint, DBImage.HV_THINNESS, false, DBImage.HV_AREA_LIMIT);
          Shape bottomShape =
              ImageAlgorithms.reduceShapeHVAreaLimit(
                  greatestShape,
                  bottomMostPoint,
                  DBImage.HV_THINNESS,
                  false,
                  DBImage.HV_AREA_LIMIT);

          int camLeftShapeCenter = leftShape.getCenter().getX();
          int camTopShapeCenter = topShape.getCenter().getY();
          int camShapeWidth = rightShape.getCenter().getX() - camLeftShapeCenter;
          int camShapeHeight = bottomShape.getCenter().getY() - camTopShapeCenter;
          // System.out.format("Brain: camLeftShapeCenter = %d, camTopShapeCenter = %d,
          // camShapeWidth = %d, camShapeHeight = %d\n", camLeftShapeCenter, camTopShapeCenter,
          // camShapeWidth, camShapeHeight);

          /* Comparison part.
           * Similar to that sucky algorithm Iulia showed me.
           * (The algorithm is sucky not Iulia)
           * BTW talkin'bout Iulia M., not Iulia P. cause Iulia P. _is_ forsure.
           */
          Vector<Letter> letters = this.parentModel.getLetters();
          if (letters == null) {
            continue;
          }
          // System.out.format("Brain: got %d letters.\n", letters.size());
          Iterator<Letter> itlt = letters.iterator();
          int letterIndex = 0;
          double maxMatchedDouble = 0.0;
          int maxMatchedIndex = 0;
          while (itlt.hasNext()) {
            Letter letter = itlt.next();
            Vector<DBImage> dbIms = letter.getDBImages();
            // System.out.format("Brain: got %d images for letter %d.\n", dbIms.size(),
            // letterIndex);
            if (dbIms == null) {
              continue;
            }
            Iterator<DBImage> itim = dbIms.iterator();
            int imIndex = 0;
            int nMatched = 0;
            while (itim.hasNext()) {
              DBImage dbIm = itim.next();

              boolean[][] dbBoolIm = dbIm.getRaster();
              // System.out.format("dbBoolIm's width and heigth is %d and %d\n", dbBoolIm[0].length,
              // dbBoolIm.length);
              int dbLeftShapeCenter = dbIm.getLeftShapeCenter();
              int dbTopShapeCenter = dbIm.getTopShapeCenter();
              int dbShapeWidth = dbIm.getShapeWidth();
              int dbShapeHeight = dbIm.getShapeHeight();
              // System.out.format("Brain: dbLeftShapeCenter = %d, dbTopShapeCenter = %d,
              // dbShapeWidth = %d, dbShapeHeight = %d\n", dbLeftShapeCenter, dbTopShapeCenter,
              // dbShapeWidth, dbShapeHeight);
              boolean[][] transZoomedBoolIm =
                  ImageAlgorithms.transZoomBoolIm(
                      camBoolIm,
                      dbLeftShapeCenter - camLeftShapeCenter,
                      dbTopShapeCenter - camTopShapeCenter,
                      (double) dbShapeWidth / camShapeWidth,
                      (double) dbShapeHeight / camShapeHeight,
                      camLeftShapeCenter,
                      camTopShapeCenter);
              // this.processedImage = ImageAlgorithms.boolIm2BuffIm(transZoomedBoolIm,
              // Color.BLACK.getRGB(), Color.BLUE.brighter().getRGB());
              // System.out.format("transZoomedBoolIm's width and heigth is %d and %d\n",
              // transZoomedBoolIm[0].length, transZoomedBoolIm.length);

              double match = ImageAlgorithms.compareTwoBoolIms(camBoolIm, dbBoolIm);
              // double match = ImageAlgorithms.compareTwoBoolIms(transZoomedBoolIm, dbBoolIm);
              // System.out.format("matching with letter %d, %d. image gives %.3f\n", letterIndex,
              // imIndex, match);
              if (match >= Brain.MINIMUM_RATE_NEEDED_TO_MATCH) {
                nMatched++;
              }

              imIndex++;
            }
            double nMatchedDouble = (double) nMatched / dbIms.size();
            if (nMatchedDouble > maxMatchedDouble) {
              maxMatchedDouble = nMatchedDouble;
              maxMatchedIndex = letterIndex + 1;
            }

            letterIndex++;
          }
          System.out.format(
              "Brain: compared with %d letters, maxMatchedDouble = %.3f, maxMatchedIndex = %d.\n",
              letterIndex, maxMatchedDouble, maxMatchedIndex);

          /* Evaluating the comparison.
           */
          if (maxMatchedDouble > Brain.MINIMUM_PROPORTION_OF_IMAGES_NEEDED_TO_MATCH) {
            currentResult = maxMatchedIndex;
          } else {
            currentResult = -1;
          }

          /* For testing: */
          // currentResult = 1 + r.nextInt(4);

        }

        if (currentResult != this.result) {
          this.result = currentResult;
          System.out.format("Brain: new result = %d\n", result);
          this.parentModel.setBrainResultChanged();
        }
      }
    }
  }
Exemplo n.º 14
0
 // Zeichent ein Schwarzes Punkt
 public void activate(int x, int y) {
   this.setRGB(x, y, Color.BLACK.getRGB());
 }
Exemplo n.º 15
0
  /*
   * (non-Javadoc)
   *
   * @see pt.up.fe.dceg.neptus.renderer2d.Renderer2DPainter#paint(java.awt.Graphics2D,
   * pt.up.fe.dceg.neptus.renderer2d.StateRenderer2D)
   */
  @Override
  public void paint(Graphics2D g2, StateRenderer2D renderer) {
    // if (!showInRender)
    // return;
    double alfaPercentage = 1;
    int dt = 3;
    long deltaTimeMillis = System.currentTimeMillis() - lastCalcPosTimeMillis;
    if (deltaTimeMillis > secondsToDisplayRanges * 1000.0) {
      // alfaPercentage = 0.5;
      dt = 0;
    } else if (deltaTimeMillis > secondsToDisplayRanges * 1000.0 / 2.0) {
      // alfaPercentage = 0.5;
      dt = 1;
    } else if (deltaTimeMillis > secondsToDisplayRanges * 1000.0 / 4.0) {
      // alfaPercentage = 0.7;
      dt = 2;
    }
    double rotationAngle = renderer.getRotation();
    Point2D centerPos = renderer.getScreenPosition(new LocationType(location));

    Color color = orangeNINFO;
    // Paint system loc
    Graphics2D g = (Graphics2D) g2.create();
    g.setStroke(new BasicStroke(2));

    {
      double diameter = Math.max(length, width);
      if (diameter > 0) {
        Graphics2D gt = (Graphics2D) g.create();

        double scaleX = (renderer.getZoom() / 10) * width;
        double scaleY = (renderer.getZoom() / 10) * length;

        diameter = diameter * renderer.getZoom();
        Color colorCircle =
            new Color(
                color.getRed(), color.getGreen(), color.getBlue(), (int) (150 * alfaPercentage));
        gt.setColor(colorCircle);
        gt.draw(
            new Ellipse2D.Double(
                centerPos.getX() - diameter / 2,
                centerPos.getY() - diameter / 2,
                diameter,
                diameter));

        gt.translate(centerPos.getX(), centerPos.getY());
        gt.rotate(Math.PI + Math.toRadians(headingDegrees) - renderer.getRotation());
        if (useSystemToDeriveHeadingOf != null && useSystemToDeriveHeadingOf.length() != 0) {
          gt.rotate(
              Math.toRadians(
                  -(-useHeadingAngleToDerivedHeading * 0 + useHeadingOffsetFromDerivedHeading)));
        }

        gt.scale(scaleX, scaleY);
        gt.fill(myShape);

        gt.dispose();
      }
    }

    if (dt > 0) {
      g.setColor(new Color(0, 0, 0, (int) (255 * alfaPercentage)));
      // g.draw(new Ellipse2D.Double(centerPos.getX()-10,centerPos.getY()-10,20,20));
      g.draw(
          new Arc2D.Double(
              centerPos.getX() - 12, centerPos.getY() - 12, 24, 24, -30, 60, Arc2D.OPEN));
      g.draw(
          new Arc2D.Double(
              centerPos.getX() - 12, centerPos.getY() - 12, 24, 24, -30 + 180, 60, Arc2D.OPEN));
      // g.setColor(new Color(255, 200, 0, (int) (255 * alfaPercentage)));
      color = orangeNINFO; // new Color(255, 255, 0).brighter();
      g.setColor(
          new Color(
              color.getRed(), color.getGreen(), color.getBlue(), (int) (255 * alfaPercentage)));
      // g.draw(new Ellipse2D.Double(centerPos.getX()-12,centerPos.getY()-12,24,24));
      g.draw(
          new Arc2D.Double(
              centerPos.getX() - 14, centerPos.getY() - 14, 28, 28, -30, 60, Arc2D.OPEN));
      g.draw(
          new Arc2D.Double(
              centerPos.getX() - 14, centerPos.getY() - 14, 28, 28, -30 + 180, 60, Arc2D.OPEN));
    }
    if (dt > 1) {
      g.setColor(new Color(0, 0, 0, (int) (255 * alfaPercentage)));
      // g.draw(new Ellipse2D.Double(centerPos.getX()-14,centerPos.getY()-14,28,28));
      g.draw(
          new Arc2D.Double(
              centerPos.getX() - 16, centerPos.getY() - 16, 32, 32, -30, 60, Arc2D.OPEN));
      g.draw(
          new Arc2D.Double(
              centerPos.getX() - 16, centerPos.getY() - 16, 32, 32, -30 + 180, 60, Arc2D.OPEN));
      color = orangeNINFO; // new Color(255, 255, 0).brighter();
      g.setColor(
          new Color(
              color.getRed(), color.getGreen(), color.getBlue(), (int) (255 * alfaPercentage)));
      g.draw(
          new Arc2D.Double(
              centerPos.getX() - 18, centerPos.getY() - 18, 36, 36, -30, 60, Arc2D.OPEN));
      g.draw(
          new Arc2D.Double(
              centerPos.getX() - 18, centerPos.getY() - 18, 36, 36, -30 + 180, 60, Arc2D.OPEN));
    }

    g.translate(centerPos.getX(), centerPos.getY());
    color = orangeNINFO; // new Color(255, 255, 0).darker();
    color =
        new Color(color.getRed(), color.getGreen(), color.getBlue(), (int) (255 * alfaPercentage));
    g.setColor(color);
    g.fill(new Ellipse2D.Double(-9, -9, 18, 18));
    // g.setColor(new Color(255, 255, 0, (int) (150 * alfaPercentage)).brighter());
    color = orangeNINFO.brighter(); // new Color(255, 255, 0).brighter();
    color =
        new Color(color.getRed(), color.getGreen(), color.getBlue(), (int) (255 * alfaPercentage));
    g.setColor(color);
    g.setStroke(new BasicStroke(2));
    g.draw(new Ellipse2D.Double(-9, -9, 18, 18));
    g.setColor(new Color(0, 0, 0, (int) (140 * alfaPercentage)));
    g.fill(new Ellipse2D.Double(-2, -2, 4, 4));
    g.setColor(Color.BLACK);

    if (true) {
      double newYaw = Math.toRadians(headingDegrees);
      Shape shape = getArrow();
      g.rotate(-rotationAngle);
      g.rotate(newYaw + Math.PI);
      color = Color.BLACK; // orangeNINFO.brighter();//new Color(255, 255, 0).brighter();
      g.setColor(
          new Color(
              color.getRed(), color.getGreen(), color.getBlue(), (int) (150 * alfaPercentage)));
      g.setStroke(new BasicStroke(2));
      g.fill(shape);
      color = Color.BLACK.darker(); // orangeNINFO.brighter();//new Color(255, 255, 0).brighter();
      g.setColor(
          new Color(
              color.getRed(), color.getGreen(), color.getBlue(), (int) (150 * alfaPercentage)));
      g.draw(shape);
      g.setColor(Color.BLACK);
      g.rotate(-(newYaw + Math.PI));
      g.rotate(rotationAngle);
    }

    // g.drawString("Me"
    // + (followingPositionOf != null && followingPositionOf.length() != 0 ? " [using " +
    // followingPositionOf + "]"
    // : "")
    // + (useSystemToDeriveHeadingOf != null && useSystemToDeriveHeadingOf.length() != 0 ? "
    // [heading from "
    // + useSystemToDeriveHeadingOf + " (@" +
    // + useHeadingAngleToDerivedHeading + CoordinateUtil.CHAR_DEGREE + "#"
    // + useHeadingOffsetFromDerivedHeading + CoordinateUtil.CHAR_DEGREE
    // + ")]" : ""), 18, 14);
    g.drawString(
        I18n.text("Me")
            + (followingPositionOf != null && followingPositionOf.length() != 0
                ? " " + I18n.text("Pos. external")
                : "")
            + (useSystemToDeriveHeadingOf != null && useSystemToDeriveHeadingOf.length() != 0
                ? " "
                    + I18n.textc(
                        "Heading external",
                        "indication that the heading comes from external source")
                : ""),
        18,
        14);
    g.translate(-centerPos.getX(), -centerPos.getY());

    g.dispose();
  }