Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.awt.Color;
- import java.awt.Point;
- import java.awt.Rectangle;
- import java.awt.image.BufferedImage;
- import java.io.File;
- import java.io.IOException;
- import java.util.ArrayList;
- import javax.imageio.ImageIO;
- import org.runedream.api.methods.Environment;
- import org.runedream.api.methods.Game;
- import org.runedream.api.util.Log;
- /**
- * Optical Character Recognition (OCR) methods.
- *
- * @author battlegaurd
- */
- public class OCR {
- private static final Font[][] ALL_LETTERS = new Font[FontType.values().length][62];
- static {
- for (int i = 0; i < ALL_LETTERS.length; i++) {
- ALL_LETTERS[i] = grabFontSet(ALL_LETTERS[i], FontType.values()[i].getName());
- }
- }
- /**
- * NOTE THE MORE VARIABLES YOU DEFINE THE FASTER THIS WILL BE AND THE SMALLER THE RECTANGLE THE FASTER IT WILL BE
- * SO TRY NOT TO RUN THIS WITH NO FONT SPECIFIED AND NO COLOR OF THE TEXT SPECIFIED BECAUSE IT DRASTICALLY INCREASES THE AMOUNT
- * OF OPERATIONS IT MUST PERFORM. I AM WORKING ON A HELPER SCRIPT THAT WILL MAKE THIS A LOT EASIER
- */
- /**
- * Finds text within a rectangle of the specified font.
- * </br>
- * To optimize performance, minimize the bounds of the rectangle, define the color, and define the font.
- * @param fontC The color of the text inside of the rectangle; or null to search for any color.
- * @param rec The rectangle to search within.
- * @param curfont The font to find a string of.
- * @return The text found within the rectangle.
- */
- public static String findString(final Color fontC, final Rectangle rec, final FontType font) {
- return findString(rec, fontC, ALL_LETTERS[font.ordinal()], false);
- }
- /**
- * Finds text within a rectangle of any supported font.
- * </br>
- * To optimize performance, minimize the bounds of the rectangle and define the color.
- * @param rec The rectangle to search within.
- * @param fontC The color of the text inside of the rectangle; or null to search for any color.
- * @return The text found within the rectangle.
- */
- public static String findString(final Rectangle rec, final Color fontC) {
- return findString(rec, fontC, null, false);
- }
- /**
- * Finds text within a rectangle of the specified font.
- * </br>
- * To optimize performance, minimize the bounds of the rectangle, define the color, and define the font.
- * @param fontC The color of the text inside of the rectangle; or null to search for any color.
- * @param rec The rectangle to search within.
- * @param curfont The font to find a string of.
- * @param multiColorText <tt>true</tt> if the text should be detected in multiple colors; otherwise <tt>false</tt>.
- * @return The text found within the rectangle.
- */
- public static String findString(final Color fontC, final Rectangle rec, final FontType font, final boolean multiColorText) {
- return findString(rec, fontC, ALL_LETTERS[font.ordinal()], multiColorText);
- }
- /**
- * Finds text within a rectangle of any supported font.
- * </br>
- * To optimize performance, minimize the bounds of the rectangle and define the color.
- * @param rec The rectangle to search within.
- * @param fontC The color of the text inside of the rectangle; or null to search for any color.
- * @param multiColorText <tt>true</tt> if the text should be detected in multiple colors; otherwise <tt>false</tt>.
- * @return The text found within the rectangle.
- */
- public static String findString(final Rectangle rec, final Color fontC, final boolean multiColorText) {
- return findString(rec, fontC, null, multiColorText);
- }
- /**
- * Finds text within a rectangle.
- * </br>
- * To optimize performance, minimize the bounds of the rectangle, define the color, and define the font.
- * @param rec The rectangle to search within.
- * @param fontC The color of the text inside of the rectangle; or null to search for any color.
- * @param font The font type to search for; or null to search for all font types
- * @param multiColorText <tt>true</tt> if the text should be detected in multiple colors; otherwise <tt>false</tt>.
- * @return The text found within the rectangle.
- */
- private static String findString(final Rectangle rec, Color fontC, final Font[] font, final boolean multiColorText) {
- ArrayList<Letter> nums = new ArrayList<Letter>();
- Font[] foundFont = font;
- for (int y = rec.y; y < rec.y + rec.height; y++) {
- M1: for (int x = rec.x; x < rec.x + rec.width; x++) {
- Color c = Game.getColorAt(x, y);
- if (fontC != null && !fontC.equals(c)) {
- continue;
- }
- for (int i = 0; i < ALL_LETTERS.length; i++) {
- Font[] curFont = ALL_LETTERS[i];
- if (foundFont != null) {
- curFont = foundFont;
- }
- M2: for (int j = 0; j < curFont.length; j++) {
- final Rectangle loc = new Rectangle(x - curFont[j].goodPts[0].x,
- y - curFont[j].goodPts[0].y, curFont[j].letBox.width, curFont[j].letBox.height);
- if (!rec.contains(loc)) {
- continue;
- }
- for (int k = 0; k < curFont[j].goodPts.length; k++) {
- if (!checkColor(Game.getColorAt(loc.x + curFont[j].goodPts[k].x,
- loc.y + curFont[j].goodPts[k].y), c, 40)) {
- continue M2;
- }
- }
- for (int k = 0; k < curFont[j].badPts.length; k++) {
- if (checkColor(Game.getColorAt(loc.x + curFont[j].badPts[k].x,
- loc.y + curFont[j].badPts[k].y), c, 40)) {
- continue M2;
- }
- }
- nums.add(new Letter(curFont[j].letter, loc.x, loc.x + curFont[j].letBox.width));
- foundFont = curFont;
- if (!multiColorText) {
- fontC = c;
- }
- continue M1;
- }
- if (foundFont != null) {
- break;
- }
- }
- }
- }
- return sortLetters(nums);
- }
- private static class Letter {
- private int x0;
- private int x1;
- private char letter;
- public Letter(final char letter, final int x0, final int x1) {
- this.letter = letter;
- this.x0 = x0;
- this.x1 = x1;
- }
- }
- private static class Font {
- private Point[] goodPts;
- private Point[] badPts;
- private char letter;
- private Rectangle letBox;
- public Font(final ArrayList<Point> goodpoints, final ArrayList<Point> badpoints,
- final char letter, final Rectangle letBox) {
- goodPts = new Point[goodpoints.size()];
- goodPts = goodpoints.toArray(goodPts);
- badPts = new Point[badpoints.size()];
- badPts = badpoints.toArray(goodPts);
- this.letBox = letBox;
- this.letter = letter;
- }
- }
- /**
- * Enumeration of the fonts available to use.
- */
- public static enum FontType {
- BIG_CHARS("BigChars"),
- NPC_CHARS("NPCChars"),
- FRIEND_CHARS("FriendChars"),
- LOGIN_CHARS("LoginChars"),
- SMALL_CHARS("SmallChars"),
- STAT_CHARS("StatChars"),
- UP_CHARS("UpChars"),
- UP_CHARS_EX("UpCharsEx");
- private String name;
- private FontType(final String name) {
- this.name = name;
- }
- /**
- * Gets the name of this FontType.
- * @return The FontType's name.
- */
- public String getName() {
- return name;
- }
- }
- /**
- * Load all images for the current font and store the font information to the Font array
- * @param fontset : font array that information will be stored
- * @param fontname : name of the current font
- * @return : a filled array of font information
- */
- private static Font[] grabFontSet(final Font[] fontset, final String fontname) {
- int cnt = 0;
- final String base = Environment.getStorageDirectoryPath() + File.separator
- + "Fonts" + File.separator + fontname + File.separator;
- for (int i = 48; i < 123; i++) {
- try {
- if ((i >= 58 && i < 65) || (i >= 91 && i < 97)) {
- continue;
- }
- final BufferedImage img = ImageIO.read(new File(base + i + ".bmp"));
- fontset[cnt++] = parseBMP(img, (char) i);
- } catch (final IOException e) {
- Log.log("Failed to read bitmap " + i + " on font " + fontname);
- }
- }
- /*for (i = 48; i < 58; i++) {
- final BufferedImage img = ImageIO.read(new File(base + i + ".bmp"));
- fontset[cnt++] = parseBMP(img, (char) i);
- }
- for (i = 65; i < 91; i++) {
- final BufferedImage img = ImageIO.read(new File(base + i + ".bmp"));
- fontset[cnt++] = parseBMP(img, (char) i);
- }
- for (i = 97; i < 123; i++) {
- final BufferedImage img = ImageIO.read(new File(base + i + ".bmp"));
- fontset[cnt++] = parseBMP(img, (char) i);
- }*/
- return fontset;
- }
- /**
- * Parses a letter font from a bitmap image.
- * @param img The image to parse.
- * @param letter The character to parse.
- * @return The letter font.
- */
- private static Font parseBMP(final BufferedImage img, final char letter) {
- final ArrayList<Point> goodPts = new ArrayList<Point>();
- final ArrayList<Point> badPts = new ArrayList<Point>();
- for (int y = 0; y < img.getHeight(); y++) {
- for (int x = 0; x < img.getWidth(); x++) {
- final Color c2 = new Color(img.getRGB(x, y));
- if (c2.equals(Color.WHITE)) {
- goodPts.add(new Point(x, y));
- } else {
- badPts.add(new Point(x, y));
- }
- }
- }
- return new Font(goodPts, badPts, letter, new Rectangle(img.getWidth(), img.getHeight()));
- }
- private static boolean checkColor(final Color c, final Color c2, final int tol) {
- return checkColor(c.getRed(), c2.getRed()) + checkColor(c.getGreen(), c2.getGreen())
- + checkColor(c.getBlue(), c2.getBlue()) < tol;
- }
- private static int checkColor(final int rgb, final int val) {
- return Math.abs(rgb - val);
- }
- // WE COULD MAYBE REMOVE THIS IF WE ONLY SEARCH ALONG THE MIDDLE OF THE BOX FOR COLORS. THIS WOULD ALSO ALLOW US TO NOT HAVE TO DO ANYWHERE CLOSE
- // TO THE AMOUNT OF TRAVERSALS AND WOULD REMOVE A LOT OF EXTRA RUNTIME
- // THE ONLY DOWN SIDE WOULD BE THE PERSON MUST MAKE SURE HE HAS HIS BOX CENTERED IN A WAY THAT THE 1 Y LINE THEY SPECIFY HITS ALL THE LETTERS
- // THIS COULD ALSO BRING IN THE PROBLEM OF THE PERSON NOT KNOWING WHERE THE TEXT IS ON SCREEN AND WOULD MAKE HIS JOB A LOT MORE TROUBLESOME
- private static String sortLetters(final ArrayList<Letter> letters) {
- String text = "";
- Letter oldLetter = null;
- while (!letters.isEmpty()) {
- Letter curLetter = new Letter('X', 800, 800);
- for (int i = 0; i < letters.size(); i++) {
- if (letters.get(i).x0 < curLetter.x0) {
- curLetter = letters.get(i);
- }
- }
- if (oldLetter != null && curLetter.x0 - oldLetter.x1 > 1){
- text += " ";
- }
- oldLetter = curLetter;
- text += curLetter.letter;
- letters.remove(curLetter);
- }
- return text;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement