This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I have designed a forms app which could have been better designed for unit testing by using business logic etc but at this stage I do not want to alter my code. It is an app which performs steganography whereby a message is embedded in an image using an LSB algorithm. I am currently trying to write a unit test for the button2 click event. When button2 is pressed; it will take text from two other textboxes and an image from a picturebox and run the LSB algorithm. Below is the test function. I create test values for the textboxes concerned. When I run the test I get: System.NullReferenceException: Object reference not set to an instance of an object. Does this refer to the object sender = null; EventArgs e = null;. Or is what I am doing even possible? Do I have to resort to NUnitForms? I have added button2_click after the test function:
public void button2_ClickTest()
{
StegApp_Accessor target = new StegApp_Accessor();
// TODO: Initialize to an appropriate value
object sender = null; // TODO: Initialize to an appropriate value
EventArgs e = null; // TODO: Initialize to an appropriate value
target.textBox4.Text = "123456";
target.textBox5.Text = "test message";
target.button2_Click(sender, e);
//Assert.Inconclusive("A method that does not return a value cannot
// be verified.");
//target.textBox4.Text = "123456";
//target.textBox5.Text = "test message";
/*
if (target.textBox4.Text.Length > 6 || target.textBox4.Text.Length < 0)
{
Assert.Fail("Key is out of range");
}*/
//Assert.IsInstanceOfType(target.b1,typeof(byte[]));
if(target.b1.Length != target.temp4.Length)
{
Assert.Fail("B1 array does not have the correct lenght");
}
Assert.IsInstanceOfType(target.image1,typeof(Bitmap));
Assert.IsInstanceOfType(target.sb,typeof(StringBuilder));
if(target.sb.Length != target.tmp3.Length)
{
Assert.Fail("Issue with Stringbuilder sb. Lenght not equal to 'tmp3'!");
}
Assert.Equals(target.z,target.StringLenght);
Assert.Equals(target.c, target.textBox5.Text.Length);
}
`private void button2_Click(object sender, EventArgs e)
{
//int x1, y1, z = 0;
try
{
// Convert String Into Byte Array
//byte[] sourceData = System.Text.ASCIIEncoding.ASCII.GetBytes(a);
// Convert Each Byte Into A Binary String
//foreach (byte thisByte in sourceData)
// binaryString.Append(Convert.ToString(thisByte, 2));
while (!key)
{
if (textBox4.Text == "")
{
//b1 = ASCIIEncoding.ASCII.GetBytes(textBox5.Text);
key = false;
MessageBox.Show("Error, enter your six digit key!");
return;
}
else if (textBox4.Text.Length > 6)
{
MessageBox.Show("Error, Key too long, try again!");
return;
}
else
{
//temp4 = textBox4.Text[0] + textBox4.Text[1] + textBox4.Text[2] + textBox4.Text[3] + textBox4.Text[4] + textBox4.Text[5] + textBox5.Text;
c = textBox5.Text.Length;
temp5 = c.ToString();
if (c <= 9)
{
temp5 = "000" + temp5;
}
else if (c <= 99)
{
temp5 = "00" + temp5;
}
else if (c <= 999)
{
temp5 = "0" + temp5;
}
else if (c <= 9999)
{
}
else
{
MessageBox.Show("Message too long for this tool,try again");
return;
}
temp4 = textBox4.Text + temp5 + textBox5.Text;
b1 = ASCIIEncoding.ASCII.GetBytes(temp4);
key = true;
}
}
//byte[] b1 = ASCIIEncoding.ASCII.GetBytes(textBox5.Text);
//b1 = Encoding.Unicode.GetBytes(a);
//Create the array to be returned.
tmp2 = new string[b1.Length];
//Interate through each byte
for (int i = 0; i < b1.Length; i++)
{
int x = b1[i];
tmp = "";
while (true)
{
if ((x % 2) == 1)
{
tmp = "1" + tmp;
}
else
{
tmp = "0" + tmp;
}
x /= 2;
if (x < 1) break;
}
//Make sure the value is 8 chars long.
tmp2[i] = tmp.PadLeft(8, '0');
}
//string a="";
for (int i = 0; i < b1.Length; i++)
{
//a = tmp2[i];
tmp3 = tmp3 + tmp2[i];
}
if (key)
{
tmp3 = "00" + tmp3;
}
else
{
tmp3 = "10" + tmp3;
}
sb.Append(tmp3);
//temp5 = c.ToString();
//z= c+1;
StringLenght = sb.Length;
byte Mask0 = 254;
byte Mask1 = 1;
byte NewRed = 0, NewGreen = 0, NewBlue = 0;
// Loop through the images pixels to reset color.
for (x1 = 0, y1 = 0; x1 < image1.Width && z < StringLenght; x1++)
{
for (y1 = 0; y1 < image1.Height && z < StringLenght; y1++)
{
Color pixelColor = image1.GetPixel(x1, y1);
//byte NewRed, NewGreen, NewBlue;
if (sb[z] == '0')
{
NewRed = Convert.ToByte(pixelColor.R & Mask0);
Color newColor = Color.FromArgb(NewRed, pixelColor.G, pixelColor.B);
image1.SetPixel(x1, y1, newColor);
pixelColor = image1.GetPixel(x1, y1);
z++;
if (z == StringLenght)
{
break;
}
}
else
{
NewRed = Convert.ToByte(pixelColor.R | Mask1);
Color newColor = Color.FromArgb(NewRed, pixelColor.G, pixelColor.B);
image1.SetPixel(x1, y1, newColor);
pixelColor = image1.GetPixel(x1, y1);
z++;
if (z == StringLenght)
{
break;
}
}
if (sb[z] == '0')
{
NewGreen = Convert.ToByte(pixelColor.G & Mask0);
Color newColor = Color.FromArgb(pixelColor.R, NewGreen, pixelColor.B);
image1.SetPixel(x1, y1, newColor);
pixelColor = image1.GetPixel(x1, y1);
z++;
if (z == StringLenght)
{
break;
}
}
else
{
NewGreen = Convert.ToByte(pixelColor.G | Mask1);
Color newColor = Color.FromArgb(pixelColor.R, NewGreen, pixelColor.B);
image1.SetPixel(x1, y1, newColor);
pixelColor = image1.GetPixel(x1, y1);
z++;
if (z == StringLenght)
{
break;
}
}
if (sb[z] == '0')
{
NewBlue = Convert.ToByte(pixelColor.B & Mask0);
Color newColor = Color.FromArgb(pixelColor.R, pixelColor.G, NewBlue);
image1.SetPixel(x1, y1, newColor);
pixelColor = image1.GetPixel(x1, y1);
z++;
if (z == StringLenght)
{
break;
}
}
else
{
NewBlue = Convert.ToByte(pixelColor.B | Mask1);
Color newColor = Color.FromArgb(pixelColor.R, pixelColor.G, NewBlue);
image1.SetPixel(x1, y1, newColor);
pixelColor = image1.GetPixel(x1, y1);
z++;
if (z == StringLenght)
{
break;
}
}
//string binary1 = Convert.ToString(pixelColor.R, 2);
//char last1 = binary1[binary1.Length - 1];
}
}
MessageBox.Show("Message embedded");
//Color newColor = Color.FromArgb(NewRed, NewGreen, NewBlue);
//image1.SetPixel(x, y, newColor);
// Set the PictureBox to display the image.
//pictureBox1.Image = image1;
// Display the pixel format in Label1.
//label1.Text = "Pixel format: " + image1.PixelFormat.ToString();
}
catch (ArgumentException)
{
MessageBox.Show("There was an error." +
"Check the path to the image file.");
}
//pictureBox2.Image = image1;
//Byte[] buf = Encoding.Unicode.GetBytes(RetreivedMessage.ToString());
//Byte[] buf = Encoding.Unicode.GetBytes(RetreivedMessage.ToString());
//string result = System.Text.Encoding.Unicode.GetString(buf);
//String result = Encoding.Unicode.GetString(buf);
//StringBuilder r2 = new StringBuilder();
//foreach (Byte b in Encoding.Unicode.GetBytes(FinalRetreivedMessage))
//{
// r2.Append(Convert.ToString(b));
// }
//int v = 0;
//for (int i = 0; i < FinalRetreivedMessage.Length; i++)
// {
// v = v * 2 + (FinalRetreivedMessage[i] == '0' ? 0 : 1);
// }
//string result = v.ToString();
// copy the string as UTF-8 bytes.
// byte[] utf8Bytes = new byte[FinalRetreivedMessage.Length];
// for (int i = 0; i < FinalRetreivedMessage.Length; ++i)
// {
//Debug.Assert( 0 <= utf8String[i] && utf8String[i] <= 255, "the char must be in byte's range");
// utf8Bytes[i] = (byte)FinalRetreivedMessage[i];
// }
//Encoding.UTF8.GetString(utf8Bytes, 0, utf8Bytes.Length);
// utf8Bytes = new byte[]{1,1,1,0,1,0,0,0};
// string result1 = Encoding.UTF8.GetString(utf8Bytes, 0, utf8Bytes.Length);
//string result1 = Encoding.UTF8.GetString(utf8Bytes);
// UTF8Encoding enc = new UTF8Encoding();
// string str = enc.GetString(utf8Bytes);
// Byte[] encodedBytes = enc.GetBytes(FinalRetreivedMessage);
// string message = encodedBytes.ToString();
// int count = FinalRetreivedMessage.Length / 8;
// var bollox = new byte[count];
// for (int i = 0; i < count; i++)
// bollox[i] = Convert.ToByte(FinalRetreivedMessage.Substring(i * 8, 8), 2);
// var bollox1 = new byte[count];
//for (int i = 0; i < count; i++)
//bollox1[i] = Encoding.Unicode.GetBytes(FinalRetreivedMessage.Substring(i * 8, 8));
// string result2 = bollox.ToString();
// string result3 = enc.GetString(bollox);
// string result4 = System.Convert.ToString(bollox);
// string StringIWant = BitConverter.ToString(bollox);
// string result5 = BitConverter.ToString(encodedBytes);
// string result6 = BitConverter.ToString(utf8Bytes);
// string result7 = BitConverter.ToString(Encoding.Unicode.GetBytes(FinalRetreivedMessage));
// string result8 = System.Convert.ToString(Encoding.Unicode.GetBytes(FinalRetreivedMessage));
// string result9 = Encoding.Unicode.GetString(Encoding.Unicode.GetBytes(FinalRetreivedMessage));
// string result10 = Encoding.Default.GetString(Encoding.Unicode.GetBytes(FinalRetreivedMessage));
}`
private void button2_Click(object sender, EventArgs e)
{
Embed();
}
public void Embed(string Embedkey, string EmbedMessage,Bitmap image3)
{
// embed message in image
}
public void EmbedTest()
{
StegApp target = new StegApp(); // TODO: Initialize to an appropriate value
string Embedkey = "123456"; // TODO: Initialize to an appropriate value
string EmbedMessage = "test2"; // TODO: Initialize to an appropriate value
Bitmap image3 = null; // TODO: Initialize to an appropriate value
image3 = new Bitmap(#"C:\Users\Admin\Documents\dt265\Project\Sky\sky-and-cloud.bmp",true);
string a="123456",b="test2";
target.Embed(Embedkey, EmbedMessage, image3);
//Assert.Inconclusive("A method that does not return a value cannot be verified.");
if (Embedkey.Length > 6 || Embedkey.Length < 0)
{
Assert.Fail("Key is out of range");
}
//Assert.IsInstanceOfType(target.b1,typeof(byte[]));
if(target.b1.Length != target.temp4.Length)
{
Assert.Fail("B1 array does not have the correct lenght");
}
Assert.IsInstanceOfType(target.image1,typeof(Bitmap));
Assert.IsInstanceOfType(target.sb,typeof(StringBuilder));
if(target.sb.Length != target.tmp3.Length)
{
Assert.Fail("Issue with Stringbuilder sb. Lenght not equal to 'tmp3'!");
}
if(target.z != target.StringLenght)
{
Assert.Fail("z != StringLenght");
}
if (target.c != EmbedMessage.Length)
{
Assert.Fail("c is not the lenght of the Message!");
}
}
Related
I am trying to find a way to determine the Index of the first character in a specific Line in RichEditBox (UWP)
in Richtextbox was easy
int indx1stlinchr = myRichTextBox.GetFirstCharIndexFromLine(i);
is there a way to do that or a workaround method ?
a part from my coloring method in Winforms Richtextbox
public void colorTheText(string rohtext)
{
myRichTextBox.SelectionLength = 0;
int def = network.SubSop_Deff;
var line = Regex.Split(rohtext, "\n|\r|\n\n");
int ipclassRange = CColor.KlassebitsRange(network.Network_Class, network.Netmask_length);
int k = 1;
int l = 1;
for (int i = 0; i < line.Length; i++)
{
int indx1stlinchr = myRichTextBox.GetFirstCharIndexFromLine(i);
int indexlinedge = line[i].LastIndexOf(" ");
if (line[i].StartsWith(">Network") == true)
{
myRichTextBox.SelectionLength = 0;
myRichTextBox.Select(indx1stlinchr, 12);
myRichTextBox.SelectionColor = Color.Black;
myRichTextBox.Select((indx1stlinchr + 13), 19);
myRichTextBox.SelectionColor = Color.Blue;
if (network.Reserved_IP != null)
{
myRichTextBox.SelectionLength = 0;
myRichTextBox.Select((indx1stlinchr + 76), 13);
myRichTextBox.SelectionColor = Color.Green;
}
if (ipclassRange > 0)
{
myRichTextBox.Select(indx1stlinchr + 39, ipclassRange);
myRichTextBox.SelectionColor = Color.Green;
}
myRichTextBox.SelectionLength = 0;
}
if (line[i].StartsWith("Netmask") == true)
{
myRichTextBox.SelectionLength = 0;
myRichTextBox.Select(indx1stlinchr, 19);
myRichTextBox.SelectionColor = Color.Black;
myRichTextBox.Select((indx1stlinchr + 13), 19);
myRichTextBox.SelectionColor = Color.Blue;
myRichTextBox.Select((indx1stlinchr + 38), 38);
myRichTextBox.SelectionColor = Color.Red;
myRichTextBox.SelectionLength = 0;
if (super == false)
{
indxlinstrt = myRichTextBox.GetFirstCharIndexOfCurrentLine();
if (k == 1)
{
myRichTextBox.Select(indxlinstrt + indexlinedge, (def + 4) * -1);
subrange = CColor.FindeSubRange(Regex.Split(myRichTextBox.SelectedText, ""), network.Netmask_length, def);
k = 0;
}
myRichTextBox.Select(indxlinstrt + indexlinedge, subrange);
myRichTextBox.SelectionColor = Color.DarkViolet;
myRichTextBox.SelectionLength = 0;
}
}//.........etc
}
super = false;
k = 1;
}
Try this snippet:
private int GetFirstCharIndexOfLine(ITextDocument document, int line)
{
string value;
document.GetText(TextGetOptions.None, out value);
int size = 0;
while (value.Length > size)
{
ITextRange range = document.GetRange(size, size + 1);
size += range.Expand(TextRangeUnit.Line);
var lineIndex = range.GetIndex(TextRangeUnit.Line);
if (line == lineIndex)
{
//start of range is first line character index
return range.StartPosition;
}
size += 1;
}
return -1;
}
I am having issues in calculation of cosine similarity between 2 strings.
I calculate the binary vector format of each string using a function. It gives out binary vectors which are in the form of, say, (1,1,1,1,1,0,0,0,0).
public static Tuple<int[],int[]> sentence_to_vector(String[] word_array1, String[] word_array2)
{
String[] unique_word_array1 = word_array1.Distinct().ToArray();
String[] unique_word_array2 = word_array2.Distinct().ToArray();
String[] list_all_words = unique_word_array1.Concat(unique_word_array2).ToArray();
String[] list_all_words_unique = list_all_words.Distinct().ToArray();
int count_all_unique_words = list_all_words_unique.Length;
int[] sentence1_vector = new int[count_all_unique_words];
int[] sentence2_vector = new int[count_all_unique_words];
for (int i = 0; i < count_all_unique_words; i++)
{
if (Array.IndexOf(unique_word_array1, list_all_words_unique[i]) >= 0)
{
sentence1_vector[i] = 1;
}
else
{
sentence1_vector[i] = 0;
}
}
for (int i = 0; i < count_all_unique_words; i++)
{
if (Array.IndexOf(word_array2, list_all_words_unique[i]) >= 0)
{
sentence2_vector[i] = 1;
}
else
{
sentence2_vector[i] = 0;
}
}
return Tuple.Create(sentence1_vector, sentence2_vector);;
}
After I calculate the vector representation, I go for cosine similarity calculation.
The code is attached herewith:
public static float get_cosine_similarity(int[] sentence1_vector, int[] sentence2_vector)
{
int vector_length = sentence1_vector.Length;
int i = 0;
float numerator = 0, denominator = 0;
int temp1 = 0, temp2 = 0;
double square_root1 = 0, square_root2 = 0;
for (i = 0; i < vector_length; i++)
{
numerator += sentence1_vector[i] * sentence2_vector[i];
temp1 += sentence1_vector[i] * sentence1_vector[i];
temp2 += sentence2_vector[i] * sentence2_vector[i];
}
//TextWriter tw = new StreamWriter("E://testpdf/date2.txt");
square_root1 = Math.Sqrt(temp1);
square_root2 = Math.Sqrt(temp2);
denominator = (float)(square_root1 * square_root2);
if (denominator != 0){
return (float)(numerator / denominator);
//return (float)(numerator);
}
else{
return 0;
}
}
I checked out a site where in I can specify 2 strings and find the cosine similarity between them. The site is attached herewith:
http://cs.uef.fi/~zhao/Link/Similarity_strings.html
function implementationCosin(){
var string1 = document.DPAform.str1.value;
var s1 = stringBlankCheck(string1);
var string2 = document.DPAform.str2.value;
var s2 = stringBlankCheck(string2);
if (s1.length < 1) {
alert("Please input the string1.");
return;
}
if (s2.length < 1) {
alert("Please input the string2.");
return;
}
document.DPAform.displayArea2.value = "";
var sDT = new Date();
// var begin = new Date().getTime();
var cosin_similarity_value = consinSimilarity(s1, s2);
document.DPAform.displayArea2.value += 'Cosin_Similarity(' + s1 + ',' + s2 + ')=' + cosin_similarity_value + '%\n';
var eDT = new Date();
var timediff = sDT.dateDiff("ms", eDT);
// var timediff = (new Date().getTime() - begin);
document.DPAform.displayArea2.value += "The total escaped time is: " + timediff + " (ms).\n";
}
Even if 2 sentences are 0% similar, my codes says that there is some amount of similarity between them.
I've tried open source projects such as this one however it doesn't seem to work at all for me. I then attempted to write my own algorithm like so (tolerance isn't being used yet).
public static Rectangle ImageSearch(Bitmap ToSearch, Bitmap ToFind, int Tolerance, double MinPercent) {
Rectangle ReturnValue = Rectangle.Empty;
BitmapData ToSearchData = ToSearch.LockBits(new Rectangle(0, 0, ToSearch.Width, ToSearch.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
BitmapData ToFindData = ToFind.LockBits(new Rectangle(0, 0, ToFind.Width, ToFind.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
IntPtr ToSearchScan0 = ToSearchData.Scan0;
IntPtr ToFindScan0 = ToFindData.Scan0;
int PixelWidth = 3; // 3 since 24 bits per pixel format
int ToSearchStride = ToSearchData.Stride;
int ToSearchPadding = ToSearchStride - (ToSearch.Width * PixelWidth);
int ToFindStride = ToFindData.Stride;
int ToFindPadding = ToFindStride - (ToFind.Width * PixelWidth);
unsafe {
byte *ToSearchPixelArray = (byte*)(void*)ToSearchData.Scan0;
byte *ToFindPixelArray = (byte*)(void*)ToFindData.Scan0;
byte sB, sG, sR, fB, fG, fR;
fB = ToFindPixelArray[0];
fG = ToFindPixelArray[1];
fR = ToFindPixelArray[2];
for (int sY = 0; sY < ToSearch.Height; sY++) {
for (int sX = 0; sX < ToSearch.Width * PixelWidth; sX += PixelWidth) {
sB = ToSearchPixelArray[0];
sG = ToSearchPixelArray[1];
sR = ToSearchPixelArray[2];
if (sB == fB && sG == fG && sR == fR) {
Console.WriteLine("found possible match");
byte *ToSearchBackup = ToSearchPixelArray;
byte *ToFindBackup = ToFindPixelArray;
int MatchedPixels = 0;
for (int fY = 0; fY < ToFind.Height; fY++) {
for (int fX = 0; fX < ToFind.Width * PixelWidth; fX += PixelWidth) {
fB = ToFindPixelArray[0];
fG = ToFindPixelArray[1];
fR = ToFindPixelArray[2];
sB = ToSearchPixelArray[0];
sG = ToSearchPixelArray[1];
sR = ToSearchPixelArray[2];
if (sB == fB && sG == fG && sR == fR) {
++MatchedPixels;
} else {
ToSearchPixelArray = ToSearchBackup;
ToFindPixelArray = ToFindBackup;
// this is the best way to break a nested loop in C#
fX = int.MaxValue;
fY = int.MaxValue;
}
}
ToSearchPixelArray += ToSearchStride - sX;
ToFindPixelArray += ToFindPadding;
}
if (MatchedPixels / (ToFind.Width * ToFind.Height) >= MinPercent) {
ReturnValue.X = (int)(sX / 3);
ReturnValue.Y = sY;
ReturnValue.Width = ToFind.Width;
ReturnValue.Height = ToFind.Height;
// this is the best way to break a nested loop in C#
sX = int.MaxValue;
sY = int.MaxValue;
}
}
}
ToSearchPixelArray += ToSearchPadding;
}
}
ToSearch.UnlockBits(ToSearchData);
ToFind.UnlockBits(ToFindData);
return ReturnValue;
}
But not even this will detect a screenshot I take of the exact image I'm searching through. Please do not suggest things such as Emgu, I'm using this in a commercial application and cannot afford to purchase a license from any GNU licensed projects (I'm not open sourcing the project either).
Serching many entries "serchingBitmap" in "sourceBitmap".
In this one I don't using unsafe code.
public static List<Point> FindBitmapsEntry(Bitmap sourceBitmap, Bitmap serchingBitmap)
{
#region Arguments check
if (sourceBitmap == null || serchingBitmap == null)
throw new ArgumentNullException();
if (sourceBitmap.PixelFormat != serchingBitmap.PixelFormat)
throw new ArgumentException("Pixel formats arn't equal");
if (sourceBitmap.Width < serchingBitmap.Width || sourceBitmap.Height < serchingBitmap.Height)
throw new ArgumentException("Size of serchingBitmap bigger then sourceBitmap");
#endregion
var pixelFormatSize = Image.GetPixelFormatSize(sourceBitmap.PixelFormat)/8;
// Copy sourceBitmap to byte array
var sourceBitmapData = sourceBitmap.LockBits(new Rectangle(0, 0, sourceBitmap.Width, sourceBitmap.Height),
ImageLockMode.ReadOnly, sourceBitmap.PixelFormat);
var sourceBitmapBytesLength = sourceBitmapData.Stride * sourceBitmap.Height;
var sourceBytes = new byte[sourceBitmapBytesLength];
Marshal.Copy(sourceBitmapData.Scan0, sourceBytes, 0, sourceBitmapBytesLength);
sourceBitmap.UnlockBits(sourceBitmapData);
// Copy serchingBitmap to byte array
var serchingBitmapData =
serchingBitmap.LockBits(new Rectangle(0, 0, serchingBitmap.Width, serchingBitmap.Height),
ImageLockMode.ReadOnly, serchingBitmap.PixelFormat);
var serchingBitmapBytesLength = serchingBitmapData.Stride * serchingBitmap.Height;
var serchingBytes = new byte[serchingBitmapBytesLength];
Marshal.Copy(serchingBitmapData.Scan0, serchingBytes, 0, serchingBitmapBytesLength);
serchingBitmap.UnlockBits(serchingBitmapData);
var pointsList = new List<Point>();
// Serching entries
// minimazing serching zone
// sourceBitmap.Height - serchingBitmap.Height + 1
for (var mainY = 0; mainY < sourceBitmap.Height - serchingBitmap.Height + 1; mainY++)
{
var sourceY = mainY * sourceBitmapData.Stride;
for (var mainX = 0; mainX < sourceBitmap.Width - serchingBitmap.Width + 1; mainX++)
{// mainY & mainX - pixel coordinates of sourceBitmap
// sourceY + sourceX = pointer in array sourceBitmap bytes
var sourceX = mainX*pixelFormatSize;
var isEqual = true;
for (var c = 0; c < pixelFormatSize; c++)
{// through the bytes in pixel
if (sourceBytes[sourceX + sourceY + c] == serchingBytes[c])
continue;
isEqual = false;
break;
}
if (!isEqual) continue;
var isStop = false;
// find fist equalation and now we go deeper)
for (var secY = 0; secY < serchingBitmap.Height; secY++)
{
var serchY = secY * serchingBitmapData.Stride;
var sourceSecY = (mainY + secY)*sourceBitmapData.Stride;
for (var secX = 0; secX < serchingBitmap.Width; secX++)
{// secX & secY - coordinates of serchingBitmap
// serchX + serchY = pointer in array serchingBitmap bytes
var serchX = secX*pixelFormatSize;
var sourceSecX = (mainX + secX)*pixelFormatSize;
for (var c = 0; c < pixelFormatSize; c++)
{// through the bytes in pixel
if (sourceBytes[sourceSecX + sourceSecY + c] == serchingBytes[serchX + serchY + c]) continue;
// not equal - abort iteration
isStop = true;
break;
}
if (isStop) break;
}
if (isStop) break;
}
if (!isStop)
{// serching bitmap is founded!!
pointsList.Add(new Point(mainX, mainY));
}
}
}
return pointsList;
}
It doesn't work accurately for me but it does give me an idea. I think the problem with this soludion is that it is looking for an exact pixel-for-pixel instance. Basically I am doing what you are doing, trying to find 1 or more occurrences of a bitmap in another but the properties may vary like brightness, contrast, size, etc. I have tired several things including Aforge.Net and Accord.Net but I can't seem to get an acceptable accuracy > 50%. Thanks for posting.
i've been trying to modify the program so that it could accept more than one data for a single alphabet character for example letter "A". there were some sort of ContainsKey function that allow only one key from keyboard to hold only one data. how to make it possible to hold more than one data?
I'm gonna make it very clear, this is an online OCR program using unsupervised neural network. when a user draw a character in the drawing space, they will have the option to add the character into the learning data to be train later. when they add a character, they have to define what character they just entered using the key on the keyboard. for example, they draw letter 'A' and a popup window will show up asking the user to enter the key from the keyboard for that letter.
the problem here, when there is already a letter 'A' in the learning data, i cannot add another letter 'A' bcause the key A is already hold the previous 'A'. i wanted to make the key A is able to hold more than one letter 'A'.
im gonna post the whole code for the program here and i hope u guys bear with me. this isnt my program, it is from Heaton Research and i just intend to modify it. thank in advance.
public partial class Form1 : Form
{
/**
* The downsample width for the application.
*/
const int DOWNSAMPLE_WIDTH = 10;
/**
* The down sample height for the application.
*/
const int DOWNSAMPLE_HEIGHT = 12;
private Bitmap entryImage;
private Graphics entryGraphics;
private int entryLastX;
private int entryLastY;
private Pen blackPen;
private bool[] downsampled;
private Dictionary<char, List<bool[]>> letterData = new Dictionary<Char, List<bool[]>>();
private double[][] trainingSet;
private SelfOrganizingMap network;
public Form1()
{
InitializeComponent();
blackPen = new Pen(Color.Black);
entryImage = new Bitmap(entry.Width, entry.Height);
entryGraphics = Graphics.FromImage(entryImage);
downsampled = new bool[Form1.DOWNSAMPLE_HEIGHT * Form1.DOWNSAMPLE_WIDTH];
ClearEntry();
}
private void entry_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
g.DrawImage(entryImage, 0, 0);
Pen blackPen = new Pen(Color.Black);
g.DrawRectangle(blackPen, 0, 0, entry.Width - 1, entry.Height - 1);
}
private void btnDelete_Click(object sender, EventArgs e)
{
string str = (string)this.letters.Items[this.letters.SelectedIndex];
char ch = str[0];
this.letterData.Remove(ch);
this.letters.Items.Remove(str);
ClearEntry();
}
private void btnLoad_Click(object sender, EventArgs e)
{
try
{
OpenFileDialog openFileDialog1 = new OpenFileDialog();
openFileDialog1.Filter = "Data File (*.dat)|*.dat";
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
TextReader f = new StreamReader(openFileDialog1.FileName);
String line;
this.letterData.Clear();
this.letters.Items.Clear();
while ((line = f.ReadLine()) != null)
{
int sampleSize = Form1.DOWNSAMPLE_HEIGHT * Form1.DOWNSAMPLE_WIDTH;
char ch = char.ToUpper(line[0]);
bool[] sample = new bool[sampleSize];
int idx = 2;
for (int i = 0; i < sampleSize; i++)
{
if (line[idx++] == '1')
sample[i] = true;
else
sample[i] = false;
}
this.letterData.Add(ch, sample);
this.letters.Items.Add("" + ch);
}
f.Close();
}
MessageBox.Show(this, "File Loaded");
}
catch (Exception ex)
{
MessageBox.Show("Error: " + ex.Message);
}
}
private void btnSave_Click(object sender, EventArgs e)
{
try
{
SaveFileDialog saveFileDialog1 = new SaveFileDialog();
saveFileDialog1.Filter = "Data File (*.dat)|*.dat";
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
TextWriter f = new StreamWriter(saveFileDialog1.FileName);
int size = Form1.DOWNSAMPLE_HEIGHT * Form1.DOWNSAMPLE_WIDTH;
for (int i = 0; i < this.letters.Items.Count; i++)
{
char ch = ((string)this.letters.Items[i])[0];
bool[] data = this.letterData[ch];
f.Write(ch + ":");
for (int j = 0; j < size; j++)
{
f.Write(data[j] ? "1" : "0");
}
f.WriteLine("");
}
f.Close();
MessageBox.Show("File Saved");
}
}
catch (Exception e2)
{
MessageBox.Show("Error: " + e2.Message, "Training");
}
}
private void btnBeginTraining_Click(object sender, EventArgs e)
{
int inputCount = Form1.DOWNSAMPLE_HEIGHT * Form1.DOWNSAMPLE_WIDTH;
int letterCount = this.letters.Items.Count;
this.trainingSet = new double[letterCount][];
int index = 0;
foreach (char ch in this.letterData.Keys)
{
this.trainingSet[index] = new double[inputCount];
bool[] data = this.letterData[ch];
for (int i = 0; i < inputCount; i++)
{
this.trainingSet[index][i] = data[i] ? 0.5 : -0.5;
}
index++;
}
network = new SelfOrganizingMap(inputCount, letterCount, NormalizationType.Z_AXIS);
this.ThreadProc();
}
private void btnAdd_Click(object sender, EventArgs e)
{
DownSample ds = new DownSample(this.entryImage);
this.downsampled = ds.downSample(Form1.DOWNSAMPLE_WIDTH, Form1.DOWNSAMPLE_HEIGHT);
this.sample.Invalidate();
String Prompt = "Enter the letter you just draw (from the keyboard)";
String Title = "Letter definition Required";
String Default = " ";
Int32 XPos = ((SystemInformation.WorkingArea.Width / 2) - 200);
Int32 YPos = ((SystemInformation.WorkingArea.Height / 2) - 100);
bool valid = false;
for (int i = 0; i < this.downsampled.Length; i++)
{
if (this.downsampled[i])
{
valid = true;
}
}
if (!valid)
{
MessageBox.Show("Please draw a letter before adding it.");
return;
}
String Result = Microsoft.VisualBasic.Interaction.InputBox(Prompt, Title, Default, XPos, YPos);
if (Result != null)
{
Result = Result.ToUpper();
if (Result.Length == 0)
{
MessageBox.Show("Please enter a character.");
}
else if (Result.Length < 1)
{
MessageBox.Show("Please enter only a single character.");
}
//else if (this.letterData.ContainsKey(Result[0]))
//{
// MessageBox.Show("That letter is already defined, please delete first.");
//}
else
{
if (this.letterData.ContainsKey(Result[0]))
{
this.letterData[Result[0]].Add(this.downsampled);
}
else
{
this.letterData.Add(Result[0], new List<bool[]>() {this.downsampled});
}
this.letters.Items.Add(Result);
//this.letterData.Add(Result[0], this.downsampled);
this.ClearEntry();
}
}
}
private void btnRecognize_Click(object sender, EventArgs e)
{
DownSample ds = new DownSample(this.entryImage);
this.downsampled = ds.downSample(Form1.DOWNSAMPLE_WIDTH, Form1.DOWNSAMPLE_HEIGHT);
this.sample.Invalidate();
if (this.network == null)
{
MessageBox.Show("The program needs to be trained first");
return;
}
int sampleSize = Form1.DOWNSAMPLE_HEIGHT * Form1.DOWNSAMPLE_WIDTH;
double[] input = new double[sampleSize];
for (int i = 0; i < sampleSize; i++)
{
input[i] = this.downsampled[i] ? 0.5 : -0.5;
}
int best = this.network.Winner(input);
char[] map = mapNeurons();
this.result.Text = " " + map[best];
MessageBox.Show(" " + map[best] + " (Neuron #"
+ best + " fired)", "That Letter You Enter Is");
//ClearEntry();
}
private void btnClear_Click(object sender, EventArgs e)
{
ClearEntry();
}
private void btnSample_Click(object sender, EventArgs e)
{
DownSample ds = new DownSample(this.entryImage);
this.downsampled = ds.downSample(Form1.DOWNSAMPLE_WIDTH, Form1.DOWNSAMPLE_HEIGHT);
this.sample.Invalidate();
}
public void ClearEntry()
{
Brush whiteBrush = new SolidBrush(Color.White);
entryGraphics.FillRectangle(whiteBrush, 0, 0, entry.Width, entry.Height);
entry.Invalidate();
DownSample ds = new DownSample(this.entryImage);
this.downsampled = ds.downSample(Form1.DOWNSAMPLE_WIDTH, Form1.DOWNSAMPLE_HEIGHT);
this.sample.Invalidate();
}
private void entry_MouseDown(object sender, MouseEventArgs e)
{
entry.Capture = true;
entryLastX = e.X;
entryLastY = e.Y;
}
private void entry_MouseUp(object sender, MouseEventArgs e)
{
entryGraphics.DrawLine(blackPen, entryLastX, entryLastY, e.X, e.Y);
entry.Invalidate();
entry.Capture = false;
}
private void entry_MouseMove(object sender, MouseEventArgs e)
{
if (entry.Capture == true)
{
entryGraphics.DrawLine(blackPen, entryLastX, entryLastY, e.X, e.Y);
entry.Invalidate();
entryLastX = e.X;
entryLastY = e.Y;
}
}
private void sample_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
int x, y;
int vcell = sample.Height / Form1.DOWNSAMPLE_HEIGHT;
int hcell = sample.Width / Form1.DOWNSAMPLE_WIDTH;
Brush whiteBrush = new SolidBrush(Color.White);
Brush blackBrush = new SolidBrush(Color.Black);
Pen blackPen = new Pen(Color.Black);
g.FillRectangle(whiteBrush, 0, 0, sample.Width, sample.Height);
for (y = 0; y < Form1.DOWNSAMPLE_HEIGHT; y++)
{
g.DrawLine(blackPen, 0, y * vcell, sample.Width, y * vcell);
}
for (x = 0; x < Form1.DOWNSAMPLE_WIDTH; x++)
{
g.DrawLine(blackPen, x * hcell, 0, x * hcell, sample.Height);
}
int index = 0;
for (y = 0; y < Form1.DOWNSAMPLE_HEIGHT; y++)
{
for (x = 0; x < Form1.DOWNSAMPLE_WIDTH; x++)
{
if (this.downsampled[index++])
{
g.FillRectangle(blackBrush, x * hcell, y * vcell, hcell, vcell);
}
}
}
g.DrawRectangle(blackPen, 0, 0, sample.Width - 1, sample.Height - 1);
}
private void letters_SelectedIndexChanged(object sender, EventArgs e)
{
if (this.letters.SelectedIndex >= 0)
{
string str = (string)this.letters.Items[this.letters.SelectedIndex];
char ch = str[0];
this.downsampled = this.letterData[ch];
this.sample.Invalidate();
}
}
public void ThreadProc()
{
TrainSelfOrganizingMap train = new TrainSelfOrganizingMap(
this.network, this.trainingSet, TrainSelfOrganizingMap.LearningMethod.SUBTRACTIVE, 0.5);
int tries = 1;
do
{
train.Iteration();
this.txtTries.Text = "" + tries;
this.txtBestError.Text = "" + train.BestError;
this.txtLastError.Text = "" + train.TotalError;
tries++;
Application.DoEvents();
} while (train.TotalError > 0.01 && (tries <= 100));
MessageBox.Show("Training complete.");
}
/**
* Used to map neurons to actual letters.
*
* #return The current mapping between neurons and letters as an array.
*/
public char[] mapNeurons()
{
char[] map = new char[this.letters.Items.Count];
for (int i = 0; i < map.Length; i++)
{
map[i] = '?';
}
for (int i = 0; i < this.letters.Items.Count; i++)
{
double[] input = new double[Form1.DOWNSAMPLE_HEIGHT * Form1.DOWNSAMPLE_WIDTH];
char ch = ((string)(this.letters.Items[i]))[0];
bool[] data = this.letterData[ch];
for (int j = 0; j < input.Length; j++)
{
input[j] = data[j] ? 0.5 : -0.5;
}
int best = this.network.Winner(input);
map[best] = ch;
}
return map;
}
}
Dictionary<> is created in a such way that you can access Key Value pair in most efficient way. Now in Dictionary<> you can not have two pairs with same key. To do so,
what you can do, you create a dictionary like Dictionary<char, List<bool[]>>, now in this dictionary you can store one key with more than one value.
Update
If you change the dictionary to Dictionary<char, List<bool[]>> then to store one key with more than one value you will have to as follows
private bool[] downsampled;
private Dictionary<char, List<bool[]>> letterData = new Dictionary<Char, List<bool[]>>();
//
// Your Code
//
if (Result != null)
{
Result = Result.ToUpper();
if (Result.Length == 0)
{
MessageBox.Show("Please enter a character.");
}
else if (Result.Length < 1)
{
MessageBox.Show("Please enter only a single character.");
}
else
{
if (this.letterData.ContainsKey(Result[0]))
{
this.letterData[Result[0]].Add(this.downsampled);
}
else
{
this.letterData.Add(Result[0], new List<bool[]>() { this.downsampled });
}
this.letters.Items.Add(Result);
this.ClearEntry();
}
}
If you want to string as key, instead of char, use Dictionary<string, List<bool[]>>.
Hope this answers your question.
Take a look at the Lookup class in .Net. This lets you have the same "key" value multiple times.
i need help with parsing pdf
the pdf builded in illustrator and it have 4 layer and each layer have one graphic path object
what i wont to do is to get all the 4 graphic paths and draw them in another pdf file that have the same width and hight as this pdf and i want to draw them in the same positions.
this is the code i started to write:
public static List<PDFMask> GetMasksFromPage(PdfPage page)
{
List<PDFMask> masks = new List<PDFMask>();
PdfDictionary contents = page.Elements.GetDictionary("/Contents");
PdfDictionary.PdfStream contentsStream = contents.Stream;
PdfDictionary resources = page.Elements.GetDictionary("/Resources");
PdfDictionary properties = resources.Elements.GetDictionary("/Properties");
PdfName[] keys = properties.Elements.KeyNames;
int dataStartPointer = 0;
int dataEndPointer = Utils.Bytes.IndexOf(contentsStream.UnfilteredValue, Encoding.ASCII.GetBytes("EMC "), dataStartPointer);
int dataCount = dataEndPointer+4;
for (int i = 0; i < keys.Length; i++)
{
PdfDictionary mc = properties.Elements.GetDictionary(keys[i].Value);
PDFMask mask = new PDFMask();
mask.name = mc.Elements.GetString("/Title");
mask.key = keys[i].Value;
byte[] data = new byte[dataCount];
Array.Copy(contentsStream.UnfilteredValue, dataStartPointer, mask.data, 0, dataCount);
mask.parseData(data);
dataStartPointer += dataCount+1;
dataEndPointer = Utils.Bytes.IndexOf(contentsStream.UnfilteredValue, Encoding.ASCII.GetBytes("EMC "), dataStartPointer);
dataCount = dataEndPointer + 4 - dataStartPointer;
masks.Add(mask);
}
return masks;
}
now the code above used for get all the layers data and seporate them in to 4 objects
PdfDictionary.PdfStream contentsStream = contents.Stream;
this line give me the 4 layers grapichs binary data
now this is the PDFMask Class that repesent a 1 layer
public class PDFMask
{
public string name;
public string key;
public byte[] data;
public void parseData(byte[] data)
{
this.data = data; //how i parsing this data to some XGrapic Object?
}
}
now this is what the data source look like:
/Layer /MC0 BDC
0.75 0.68 0.67 0.902 k
/GS0 gs
q 1 0 0 1 396.4473 1835.6143 cm
0 0 m
76.497 -132.515 l
-17.184 -159.051 l
76.496 -185.607 l
-0.003 -318.119 l
-72.563 -252.047 l
-50.486 -349.178 l
-202.179 -349.182 l
-180.097 -252.046 l
-252.658 -318.116 l
-329.154 -185.603 l
-235.473 -159.048 l
-329.154 -132.511 l
-252.654 0.002 l
-180.094 -66.07 l
-202.175 31.087 l
-50.482 31.081 l
-72.563 -66.072 l
h
f
Q
EMC
i looking for some parser (i will prefer a pdfsharp parser)
that can parse this data to some graphic object that i colud use it on another pdf document
ok what i did to slove this is to buid my own parser for my own needs i will display here th code i am sure it will help someone someday...
public struct GD { public double x, y, a, b, c, d; public byte t; }
public struct Coordinate { public double locX, locY, oriX, oriY, xAxis, yAxis; }
public class PDFMask
{
private string _name;
public string fun;
public string name
{
get
{
return _name;
}
set
{
if (value.Contains("{"))
{
_name = value.Substring(0, value.IndexOf("{"));
fun = value.Substring(value.IndexOf("{"));
}
else
{
_name = value;
}
}
}
public string key;
public byte[] data;
public GD[] graphicsDirectives;
public Coordinate coordinate;
public void parseData(byte[] data)
{
this.data = data;
graphicsDirectives = new GD[100];
int gdCount = 0;
byte[] buffer = new byte[100];
int bufferCount = 0;
for (int i = 0; i < data.Length; i++)
{
switch (data[i])
{
case (byte)'\n':
if (bufferCount > 2 && buffer[bufferCount - 2] == ' ' && (buffer[bufferCount - 1] == 'c' || buffer[bufferCount - 1] == 'l' || buffer[bufferCount - 1] == 'm'))
graphicsDirectives[gdCount++] = parseDataWriteGD(buffer, bufferCount);
else if (bufferCount > 3 && buffer[0] == 'q' && buffer[bufferCount - 1] == 'm' && buffer[bufferCount - 2] == 'c')
coordinate = parseDataWriteCoordinate(buffer, bufferCount);
bufferCount = 0;
break;
default :
buffer[bufferCount++] = data[i];
break;
}
}
GD[] actualGraphicsDirectives = new GD[gdCount];
Array.Copy(graphicsDirectives, actualGraphicsDirectives, gdCount);
graphicsDirectives = actualGraphicsDirectives;
}
public Coordinate parseDataWriteCoordinate(byte[] bytes, int count)
{
byte[] actualBytes = new byte[count];
Array.Copy(bytes, actualBytes, count);
string[] values = Encoding.ASCII.GetString(actualBytes).Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
Coordinate c = new Coordinate();
c.locX = double.Parse(values[1]);
c.locY = double.Parse(values[2]);
c.oriX = double.Parse(values[3]);
c.oriY = double.Parse(values[4]);
c.xAxis = double.Parse(values[5]);
c.yAxis = double.Parse(values[6]);
return c;
}
public GD parseDataWriteGD(byte[] bytes, int count)
{
byte[] actualBytes = new byte[count];
Array.Copy(bytes, actualBytes, count);
string[] values = Encoding.ASCII.GetString(actualBytes).Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
GD gd = new GD();
gd.t = (byte)values[values.Length - 1][0];
if (gd.t == 'c')
{
gd.a = double.Parse(values[0]);
gd.b = double.Parse(values[1]);
gd.c = double.Parse(values[2]);
gd.d = double.Parse(values[3]);
gd.x = double.Parse(values[4]);
gd.y = double.Parse(values[5]);
}
else
{
gd.x = double.Parse(values[0]);
gd.y = double.Parse(values[1]);
}
return gd;
}
}