Hi, this is pretty much my first post here.
I just started learning C++ about a week and a half ago and I started working on a program that could compare pixels on the screen to see which letters they form (kind of like OCR). I probably know what you're thinking, but I do have enough programming experience to know mostly what i'm getting myself into.
The main idea of how this program will work:
- Somebody creates a bitmap of the given characters (in order) in the font&size they want to create a profile of
- A (Font-Profile Creator) C++ program will analyze the picture of all characters pixel values and store each character's contents into their own matrix-style (2D) boolean-type (true/false) array, true if the coordinates return a white color, false otherwise. It then stores this information in a file, in such a way that it is easy to load this information at a later time.
- The next program (The Screen-Analyzer) program will load the font profile and read the text at a given area of the screen (x,y,width,height) by comparing blocks of pixels to the ones stored in the font profile arrays. It will return the results as a string value.
I couldn't make the program read a bitmap but it reads the template displayed on-screen and stores the pixel values for the characters in arrays. It compiles fine. The way it runs is a different story. It just runs, takes up processor power, then closes. If I add anything else to the end of the script it just runs until i close it.
I was wondering if anyone could help me fix up my code or come up with a better method of doing what I need? Thanks in advance...
#include <windows.h>
#include <tchar.h>
#include <iostream>
#include <sstream>
#include <string.h>
#include <stdlib.h>
using namespace std;
#pragma comment(lib, "user32.lib")
int GetScreenPixel(int *pixr, int *pixb, int *pixg, int pixx, int pixy)
{
HDC hDC;
hDC = CreateDC("DISPLAY",0,0,0);
COLORREF clr = GetPixel(hDC, pixx, pixy);
int ClrRefR = GetRValue(clr);
int ClrRefB = GetBValue(clr);
int ClrRefG = GetGValue(clr);
*pixr = ClrRefR;
*pixb = ClrRefB;
*pixg = ClrRefG;
}
void MyFunc(void) //(called by main)
{
// This is the window I want to extract the font's pixel data from.
HWND hWnd = FindWindow(NULL,"Font Template Displayer");
// It is just an HTML App designed only to display the bitmap
POINT pos;
RECT rMyRect;
GetClientRect(hWnd, (LPRECT)&rMyRect);
ClientToScreen(hWnd, (LPPOINT)&rMyRect.left);
ClientToScreen(hWnd, (LPPOINT)&rMyRect.right);
char bufferthing[200];
// Information about font display window (displaying the bitmap)
// it is the same size as the bitmap itself
int winwidth = rMyRect.right - rMyRect.left;
int winheight = rMyRect.bottom - rMyRect.top;
int wintop = 0 + rMyRect.top; // Don't know why i put 0 here lol
int winleft = 0 + rMyRect.left;
SetForegroundWindow(hWnd);
int TmpPixR;
int TmpPixB;
int TmpPixG;
// These are the characters I want to be able to read (obviously)
char AllowedChars[] = "QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm1234567890$:";
// This array will store the width in pixels of each character
int AllowedCharLn[sizeof(AllowedChars)];
int CharOn = 0;
// These are the starting screen coordinates to read from
int StartPosX = 0; // They actually probably should be set to winleft, and wintop
int StartPosY = 0;
int whitesig = 255*3; // Is the same value as the RGB value of white added up
int tempsig; // Will breifly contain each pixel's color values (RGB added up)
// goodarr will contain each character's signature
int goodarr[sizeof(AllowedChars)][winheight][15];
// 15 is my estimate of the max width in pixels I will be working with for the characters.
// winheight is the same as the height of the characters
int tempcoord[winheight]; // I am using these arrays to stack my information together
int temparr[15][winheight]; // I'm new to C++ but I know this is a bad way of doing it
bool lastspace = true;
int temparrat = 0;
// Cycle through each pixel in window
for(int x=0;x<winwidth;x++)
{
bool blanked = true;
for(int y=0;y<winheight;y++)
{
// Get the pixel's data
GetScreenPixel(&TmpPixR,&TmpPixB,&TmpPixG,StartPosX+x,StartPosY+y);
// Put info into easy to read variable
tempsig = TmpPixR+TmpPixB+TmpPixG;
if(tempsig == whitesig) // If it is white, value is 1
{ blanked = false; lastspace = false;
tempcoord[y] = 1;
}
else // If it is not, it is irrelivant
{
tempcoord[y] = 0;
}
// if pixel is white, blanked is false
}
for(int i=0;i<sizeof(tempcoord);i++)
{
temparr[temparrat][i] = tempcoord[i]; // Put vertical line data into temporary horizontal array
}
temparrat = temparrat+1; // Horizontal array counter up by 1
// If blanked is true by this point, whole vertical line column was not white.
// This means that the next character scan can begin
if(blanked == true && lastspace == false)
{
for(int ix=0;ix<winheight;ix++)
{
for(int xi=0;xi<temparrat-1;xi++)
{
goodarr[CharOn][ix][xi] = temparr[xi][ix];
AllowedCharLn[CharOn] = temparrat-1;
}
}
CharOn+=1; temparrat = 0; lastspace = true;
// Resets horizontal array counter, gets ready for next letter and makes
// sure these commands aren't called again until next space is detected
}
}
// MessageBox(NULL, "Yayyyy", "Msg Box", MB_OK);
// Message box will cause program to run an endless loop (stall)
}
int main() {
MyFunc();
return 0;
}
Here is the code for my HTML App that displays the font template bitmap. I load this before I run the c++ program.
<HTA:APPLICATION
border="none"
/>
<HTML>
<HEAD>
<TITLE>Font Template Displayer</TITLE>
</HEAD>
<script>
window.moveTo(0,0);
window.resizeTo(0,0);
</script>
<body onLoad="doLoad()" bgcolor="#C0C0C0" Style="border:none;" scroll="no">
<!-- The purpose of this program is to display characters on-screen
in a specified font and size. Then the program written in C++
can read the pure-white pixels of each letter and make an
array-type matrix containing basically a signature for each letter.
When the program completes it will store the data in a file that
can be called upon for comparing against other screen pixels
(basically reading them).
-->
<img Style="position:absolute; top:0; left:0;" ID="imgsrc" src="arialbold9template.bmp">
<script>
function doLoad() { window.moveTo(0,0); window.resizeTo(document.all.imgsrc.width+1,document.all.imgsrc.height+1); }
</script>
</body>
</HTML>