Skip to content
View in the app

A better way to browse. Learn more.

Tip.It Forum

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

C# - Odd bug

Featured Replies

EDIT: Fixed

 

(sorry for the bad post formatting and generally bad code, was just a quick test to see if it worked, will refactor once I actually get it working)

 

I'm working on a little personal project, which is an OCR-driven drop log for Runescape (This never actually interacts with the Runescape client in any way, no input)

 

It's supposed to work by taking a screenshot of the Runescape client, finding any item text (which is done by itterating through each pixel and checking if it matches the item text colour, then converting the result to a pattern) and using OCR to turn this into a string (not the best method for this, but again, to test).

To do this, I'm using patterns of each character in the Runescape font stored with the format:

(Pattern being a boolean representation of each pixel in the image used to generate the pattern, non-white: true, white: false)

ptnformat.png

And itterating over each pixel in the input image and looking for sequences that match the first part of a pattern, then repeating this for the pixels below the matched sequence until there is a part which does not match, or until the pattern is fully matched (yes, I know this is horribly inefficient and I have briefly looked at other OCR libraries, most of the ones which have the features I need have memory leak issues though).

 

Currently, its only a test to make sure I can actually read text.

 

One part of the code which searches for a matching sequence is giving an odd bug which I can't find the source of anywhere...

 

GetCharacters:

private char[] GetCharacters(bool[] value, SearchPattern[] patterns)
{
List<char> characters = new List<char>();

// Itterate over each pixel in the input image sequence.
for (int i = 0; i < value.Length; i++)
{
   	foreach (SearchPattern p in patterns)
   	{
       	// Check if there is a match for the first line of the search pattern.
       	if (p.IsMatch(0, value.Skip(i).Take(p.Lines[0].Length).ToArray())) // <-- Line where it fails.
       	{
           	// Check each line of the pattern for a match.
           	for (int l = 1; l < p.Height; l++)
           	{
               	int offset = 0;
               	bool isMatch = p.IsMatch(l, value.Skip(i + offset + (loadedImage.Width - p.Width)).Take(p.Lines[l].Length).ToArray()); // <-- May fail
               	if (isMatch && l == p.Height - 1)
               	{
                   	characters.Add(p.Character);
                   	break;
               	}
               	else if (isMatch)
               	{
                   	offset += (loadedImage.Width - p.Width);
               	}
               	else
               	{
                   	break;
               	}
           	}
       	}
   	}
}

return characters.ToArray();
}

The call

p.IsMatch(0, value.Skip(i).Take(p.Lines[0].Length).ToArray())

always fails because of the bug in

SearchPattern.IsMatch

 

loadedImage being a Bitmap object representing the input image.

Skip and Take provided by LINQ.

 

SearchPattern.cs

using System.IO;
using System;

namespace RunescapeOcr
{
public class SearchPattern
{
	public SearchPattern(string path)
	{
		using (BinaryReader reader = new BinaryReader(File.OpenRead(path)))
		{
			this.Character = reader.ReadChar();
			this.Width = reader.ReadInt32();
			this.Height = reader.ReadInt32();

			int sequenceLength = (int)reader.BaseStream.Length - (int)reader.BaseStream.Position;
			this.Sequence = new bool[sequenceLength];

			for (int i = 0; i < sequenceLength; i++)
			{
				this.Sequence[i] = reader.ReadBoolean();
			}

			this.Lines = GetLines(Width, Height, Sequence);
		}
	}

	public bool IsMatch(int line, bool[] sequence)
	{
		// BUG: This check always fails no matter what I change.
		// For the test, this.Lines[line].Length is 5 (only characters used are both 5 pixels wide)
		// However, even though this.Lines[line].Length is used to select characters in GetCharacters,
		// it always ends up being with sequence.Length being 4 (for this test).
		// if I add 1 to this to get them to match, sequence.Length becomes 5, so the result ends up being 6 instead.
		// I've tried several other things (different operators (e.g. <, >, <=, >=, ==  etc.))
		// but this condition will always change so that it throws an exception.
		if (this.Lines[line].Length != sequence.Length)
			throw new Exception("Sequence lengths do not match");

		for (int i = 0; i < this.Lines[line].Length; i++)
		{
			if (this.Lines[line][i] != sequence[i])
				return false;
		}
		return true;
	}

	protected bool[][] GetLines(int width, int height, bool[] sequence)
	{
		if ((sequence.Length / width) != height)
			throw new Exception("Corrupted Search Pattern.");

		bool[][] lines = new bool[height][];

		for (int h = 0; h < height; h++)
		{
			lines[h] = new bool[width];
			for (int w = 0; w < width; w++)
			{
				lines[h][w] = sequence[(h * width) + w];
			}
		}

		return lines;
	}

	public char Character { get; private set; }

	public int Width { get; private set; }

	public int Height { get; private set; }

	public bool[] Sequence { get; private set; }

	public bool[][] Lines { get; private set; }
}
}

 

I really can't see what is causing this bug... it always happens and seems to change dynamically to any adjustments I make.

Create an account or sign in to comment

Important Information

By using this site, you agree to our Terms of Use.

Account

Navigation

Search

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.