mirror of
https://github.com/moparisthebest/Simba
synced 2025-01-30 23:00:18 -05:00
Minor changes + added todo list.
This commit is contained in:
parent
72539efffd
commit
2141e1d016
@ -49,10 +49,12 @@ type
|
||||
TMFonts = class(TObject)
|
||||
private
|
||||
Fonts: TList;
|
||||
Path: String;
|
||||
FPath: String;
|
||||
Client : TObject;
|
||||
function GetFontIndex(const Name: String): Integer;
|
||||
function GetFontByIndex(Index : integer): TMfont;
|
||||
procedure SetPath(const aPath: String);
|
||||
function GetPath: String;
|
||||
public
|
||||
constructor Create(Owner : TObject);
|
||||
destructor Destroy; override;
|
||||
@ -60,10 +62,9 @@ type
|
||||
function FreeFont(const Name: String): Boolean;
|
||||
function LoadFont(const Name: String; Shadow: Boolean): boolean;
|
||||
function LoadSystemFont(const SysFont : TFont; const FontName : string) : boolean;
|
||||
procedure SetPath(const aPath: String);
|
||||
function GetPath: String;
|
||||
function Copy(Owner : TObject): TMFonts;
|
||||
function Count : integer;
|
||||
property Path : string read GetPath write SetPath;
|
||||
property Font[Index : integer]: TMfont read GetFontByIndex; default;
|
||||
end;
|
||||
|
||||
@ -155,12 +156,12 @@ end;
|
||||
|
||||
procedure TMFonts.SetPath(const aPath: String);
|
||||
begin
|
||||
Path := aPath;
|
||||
FPath := aPath;
|
||||
end;
|
||||
|
||||
function TMFonts.GetPath: String;
|
||||
begin
|
||||
Exit(Path);
|
||||
Exit(FPath);
|
||||
end;
|
||||
|
||||
function TMFonts.GetFontIndex(const Name: String): Integer;
|
||||
@ -201,9 +202,9 @@ function TMFonts.LoadFont(const Name: String; Shadow: Boolean): boolean;
|
||||
var
|
||||
f: TMFont;
|
||||
begin
|
||||
if not DirectoryExists(Path + Name) then
|
||||
if not DirectoryExists(FPath + Name) then
|
||||
begin
|
||||
raise Exception.Create('LoadFont: Directory ' + Path + Name + ' does not exists.');
|
||||
raise Exception.Create('LoadFont: Directory ' + FPath + Name + ' does not exists.');
|
||||
Exit(False);
|
||||
end;
|
||||
|
||||
@ -211,7 +212,7 @@ begin
|
||||
f.Name := Name;
|
||||
if Shadow then
|
||||
F.Name := F.Name + '_s';
|
||||
f.Data := InitOCR( LoadGlyphMasks(Path + Name + DS, Shadow));
|
||||
f.Data := InitOCR( LoadGlyphMasks(FPath + Name + DS, Shadow));
|
||||
Fonts.Add(f);
|
||||
{$IFDEF FONTDEBUG}
|
||||
TClient(Client).Writeln('Loaded Font ' + f.Name);
|
||||
@ -270,7 +271,7 @@ var
|
||||
i:integer;
|
||||
begin
|
||||
Result := TMFonts.Create(Owner);
|
||||
Result.Path := Self.GetPath();
|
||||
Result.Path := FPath;
|
||||
for i := 0 to Self.Fonts.Count -1 do
|
||||
Result.Fonts.Add(TMFont(Self.Fonts.Items[i]).Copy());
|
||||
end;
|
||||
|
@ -45,7 +45,7 @@ type
|
||||
debugbmp: TMufasaBitmap;
|
||||
{$ENDIF}
|
||||
function GetFonts:TMFonts;
|
||||
procedure SetFonts(NewFonts: TMFonts);
|
||||
procedure SetFonts(const NewFonts: TMFonts);
|
||||
public
|
||||
constructor Create(Owner: TObject);
|
||||
destructor Destroy; override;
|
||||
@ -139,7 +139,7 @@ var
|
||||
i: longint;
|
||||
begin
|
||||
// We're going to load all fonts now
|
||||
FFonts.SetPath(path);
|
||||
FFonts.Path := path;
|
||||
dirs := GetDirectories(path);
|
||||
Result := false;
|
||||
for i := 0 to high(dirs) do
|
||||
@ -158,7 +158,7 @@ begin
|
||||
end;
|
||||
|
||||
{ Set new Fonts. We set it to a Copy of NewFonts }
|
||||
procedure TMOCR.SetFonts(NewFonts: TMFonts);
|
||||
procedure TMOCR.SetFonts(const NewFonts: TMFonts);
|
||||
begin
|
||||
Self.FFonts := NewFonts.Copy(Self.Client);
|
||||
end;
|
||||
|
@ -8,54 +8,45 @@ uses
|
||||
Classes, SysUtils, MufasaTypes,bitmaps;
|
||||
|
||||
type
|
||||
TNormArray = array of integer;
|
||||
TocrGlyphMask = record
|
||||
ascii: char;
|
||||
width,height: integer;
|
||||
l,r,t,b: integer;
|
||||
mask: TNormArray;
|
||||
end;
|
||||
TocrGlyphMaskArray = array of TocrGlyphMask;
|
||||
TocrGlyphMetric = record
|
||||
xoff,yoff: integer;
|
||||
width,height: integer;
|
||||
index: integer; //stores the internal TocrData index for this char
|
||||
end;
|
||||
TocrData = record
|
||||
ascii: array[0..255] of TocrGlyphMetric;
|
||||
pos: array of array of integer;
|
||||
pos_adj: array of real;
|
||||
neg: array of array of integer;
|
||||
neg_adj: array of real;
|
||||
map: array of char;
|
||||
width,height, max_width, max_height: integer;
|
||||
inputs,outputs: integer;
|
||||
end;
|
||||
TNormArray = array of integer;
|
||||
TocrGlyphMask = record
|
||||
ascii: char;
|
||||
width,height: integer;
|
||||
l,r,t,b: integer;
|
||||
mask: TNormArray;
|
||||
end;
|
||||
TocrGlyphMaskArray = array of TocrGlyphMask;
|
||||
TocrGlyphMetric = record
|
||||
xoff,yoff: integer;
|
||||
width,height: integer;
|
||||
index: integer; //stores the internal TocrData index for this char
|
||||
end;
|
||||
TocrData = record
|
||||
ascii: array[0..255] of TocrGlyphMetric;
|
||||
pos: array of array of integer;
|
||||
pos_adj: array of real;
|
||||
neg: array of array of integer;
|
||||
neg_adj: array of real;
|
||||
map: array of char;
|
||||
width,height, max_width, max_height: integer;
|
||||
inputs,outputs: integer;
|
||||
end;
|
||||
|
||||
TocrDataArray = array of TocrData;
|
||||
TocrDataArray = array of TocrData;
|
||||
|
||||
{Begin To be removed}
|
||||
Tbmp = record
|
||||
data: array of TRGB32;
|
||||
width,height: integer;
|
||||
end;
|
||||
{End To be removed}
|
||||
tLab = record
|
||||
L,a,b: real;
|
||||
end;
|
||||
|
||||
|
||||
tLab = record
|
||||
L,a,b: real;
|
||||
end;
|
||||
|
||||
procedure findBounds(glyphs: TocrGlyphMaskArray; out width,height: integer);
|
||||
function LoadGlyphMask(const bmp : TMufasaBitmap; shadow: boolean; const ascii : char): TocrGlyphMask;
|
||||
function LoadGlyphMasks(const path: string; shadow: boolean): TocrGlyphMaskArray;
|
||||
function InitOCR(const Masks : TocrGlyphMaskArray): TocrData;
|
||||
function GuessGlyph(glyph: TNormArray; ocrdata: TocrData): char;
|
||||
function PointsToNorm(points: TpointArray; out w,h: integer): TNormArray;
|
||||
function ImageToNorm(src: TRGB32Array; w,h: integer): TNormArray;
|
||||
function ocrDetect(txt: TNormArray; w,h: integer; var ocrdata: TocrData): string;
|
||||
function ExtractText(colors: PRGB32;{colors: tRGBArray;} w,h: integer): TNormArray;
|
||||
function MakeTPAString(str: string): TpointArray;
|
||||
procedure findBounds(glyphs: TocrGlyphMaskArray; out width,height: integer);
|
||||
function LoadGlyphMask(const bmp : TMufasaBitmap; shadow: boolean; const ascii : char): TocrGlyphMask;
|
||||
function LoadGlyphMasks(const path: string; shadow: boolean): TocrGlyphMaskArray;
|
||||
function InitOCR(const Masks : TocrGlyphMaskArray): TocrData;
|
||||
function GuessGlyph(glyph: TNormArray; ocrdata: TocrData): char;
|
||||
function PointsToNorm(points: TpointArray; out w,h: integer): TNormArray;
|
||||
function ImageToNorm(src: TRGB32Array; w,h: integer): TNormArray;
|
||||
function ocrDetect(txt: TNormArray; w,h: integer; var ocrdata: TocrData): string;
|
||||
function ExtractText(colors: PRGB32;{colors: tRGBArray;} w,h: integer): TNormArray;
|
||||
|
||||
implementation
|
||||
uses
|
||||
@ -64,86 +55,63 @@ uses
|
||||
graphtype, intfgraphics,graphics;
|
||||
{End To-Remove unit}
|
||||
|
||||
|
||||
function ReadBMP(path: string): Tbmp;
|
||||
var
|
||||
LazIntf : TLazIntfImage;
|
||||
RawImageDesc : TRawImageDescription;
|
||||
begin
|
||||
if FileExists(path) then
|
||||
begin;
|
||||
LazIntf := TLazIntfImage.Create(0,0);
|
||||
RawImageDesc.Init_BPP32_B8G8R8_BIO_TTB(LazIntf.Width,LazIntf.Height);
|
||||
LazIntf.DataDescription := RawImageDesc;
|
||||
LazIntf.LoadFromFile(path);
|
||||
Result.width := LazIntf.Width;
|
||||
Result.height := LazIntf.Height;
|
||||
SetLength(result.data,LazIntf.Width*LazIntf.Height);
|
||||
Move(LazIntf.PixelData[0],result.data[0],LazIntf.Width*LazIntf.Height*sizeOf(TRGB32));
|
||||
LazIntf.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
|
||||
{initalizes the remaining fields from a TocrGlyphMask and finds the global bounds}
|
||||
procedure findBounds(glyphs: TocrGlyphMaskArray; out width,height: integer);
|
||||
var
|
||||
i,x,y,c,w,h: integer;
|
||||
l,r,t,b: integer;
|
||||
dat: TNormArray;
|
||||
i,x,y,c,w,h: integer;
|
||||
l,r,t,b: integer;
|
||||
dat: TNormArray;
|
||||
begin
|
||||
width:= 0;
|
||||
height:= 0;
|
||||
for c:= 0 to length(glyphs) - 1 do
|
||||
width:= 0;
|
||||
height:= 0;
|
||||
for c:= 0 to length(glyphs) - 1 do
|
||||
begin
|
||||
dat:= glyphs[c].mask;
|
||||
w:= glyphs[c].width;
|
||||
h:= glyphs[c].height;
|
||||
l:= w;
|
||||
r:= 0;
|
||||
t:= h;
|
||||
b:= 0;
|
||||
for i:= 0 to w*h-1 do
|
||||
begin
|
||||
dat:= glyphs[c].mask;
|
||||
w:= glyphs[c].width;
|
||||
h:= glyphs[c].height;
|
||||
l:= w;
|
||||
r:= 0;
|
||||
t:= h;
|
||||
b:= 0;
|
||||
for i:= 0 to w*h-1 do
|
||||
begin
|
||||
if dat[i] = 1 then
|
||||
begin
|
||||
x:= i mod w;
|
||||
y:= i div w;
|
||||
if x > r then r:= x;
|
||||
if x < l then l:= x;
|
||||
if y > b then b:= y;
|
||||
if y < t then t:= y;
|
||||
end;
|
||||
end;
|
||||
if l = w then l:= 0;
|
||||
if t = h then t:= 0;
|
||||
glyphs[c].r:= r;
|
||||
glyphs[c].l:= l;
|
||||
glyphs[c].b:= b;
|
||||
glyphs[c].t:= t;
|
||||
if (r - l + 1) > width then width:= r - l + 1;
|
||||
if (b - t + 1) > height then height:= b - t + 1;
|
||||
if dat[i] = 1 then
|
||||
begin
|
||||
x:= i mod w;
|
||||
y:= i div w;
|
||||
if x > r then r:= x;
|
||||
if x < l then l:= x;
|
||||
if y > b then b:= y;
|
||||
if y < t then t:= y;
|
||||
end;
|
||||
end;
|
||||
if l = w then l:= 0;
|
||||
if t = h then t:= 0;
|
||||
glyphs[c].r:= r;
|
||||
glyphs[c].l:= l;
|
||||
glyphs[c].b:= b;
|
||||
glyphs[c].t:= t;
|
||||
if (r - l + 1) > width then width:= r - l + 1;
|
||||
if (b - t + 1) > height then height:= b - t + 1;
|
||||
end;
|
||||
end;
|
||||
|
||||
{Use whatever you want if you don't like this}
|
||||
function GetFiles(Path, Ext: string): TstringArray;
|
||||
var
|
||||
SearchRec : TSearchRec;
|
||||
c : integer;
|
||||
SearchRec : TSearchRec;
|
||||
c : integer;
|
||||
begin
|
||||
c := 0;
|
||||
if FindFirst(Path + '*.' + ext, faAnyFile, SearchRec) = 0 then
|
||||
begin
|
||||
repeat
|
||||
inc(c);
|
||||
SetLength(Result,c);
|
||||
Result[c-1] := SearchRec.Name;
|
||||
until FindNext(SearchRec) <> 0;
|
||||
SysUtils.FindClose(SearchRec);
|
||||
end;
|
||||
c := 0;
|
||||
if FindFirst(Path + '*.' + ext, faAnyFile, SearchRec) = 0 then
|
||||
begin
|
||||
repeat
|
||||
inc(c);
|
||||
SetLength(Result,c);
|
||||
Result[c-1] := SearchRec.Name;
|
||||
until FindNext(SearchRec) <> 0;
|
||||
SysUtils.FindClose(SearchRec);
|
||||
end;
|
||||
end;
|
||||
|
||||
function LoadGlyphMask(const bmp: TMufasaBitmap; shadow: boolean; const ascii : char): TocrGlyphMask;
|
||||
@ -258,218 +226,215 @@ end;
|
||||
{guesses a glyph stored in glyph (which is an 1-0 image of the size specified by width and height in ocrdata}
|
||||
function GuessGlyph(glyph: TNormArray; ocrdata: TocrData): char;
|
||||
var
|
||||
i,c,inputs,outputs,val: integer;
|
||||
pos_weights: array of real;
|
||||
neg_weights: array of real;
|
||||
max, weight: real;
|
||||
i,c,inputs,outputs,val: integer;
|
||||
pos_weights: array of real;
|
||||
neg_weights: array of real;
|
||||
max, weight: real;
|
||||
begin
|
||||
SetLength(pos_weights,ocrdata.outputs);
|
||||
SetLength(neg_weights,ocrdata.outputs);
|
||||
inputs:= ocrdata.inputs - 1;
|
||||
outputs:= ocrdata.outputs - 1;
|
||||
for i:= 0 to inputs do
|
||||
SetLength(pos_weights,ocrdata.outputs);
|
||||
SetLength(neg_weights,ocrdata.outputs);
|
||||
inputs:= ocrdata.inputs - 1;
|
||||
outputs:= ocrdata.outputs - 1;
|
||||
for i:= 0 to inputs do
|
||||
begin
|
||||
val:= glyph[i];
|
||||
for c:= 0 to outputs do
|
||||
begin
|
||||
val:= glyph[i];
|
||||
for c:= 0 to outputs do
|
||||
begin
|
||||
pos_weights[c]:= pos_weights[c] + ocrdata.pos[c][i] * val;
|
||||
neg_weights[c]:= neg_weights[c] + ocrdata.neg[c][i] * val;
|
||||
end
|
||||
end;
|
||||
max:= 0;
|
||||
for i:= 0 to outputs do
|
||||
pos_weights[c]:= pos_weights[c] + ocrdata.pos[c][i] * val;
|
||||
neg_weights[c]:= neg_weights[c] + ocrdata.neg[c][i] * val;
|
||||
end
|
||||
end;
|
||||
max:= 0;
|
||||
for i:= 0 to outputs do
|
||||
begin
|
||||
weight:= pos_weights[i] * ocrdata.pos_adj[i] - neg_weights[i] * ocrdata.neg_adj[i];
|
||||
if (weight > max) then
|
||||
begin
|
||||
weight:= pos_weights[i] * ocrdata.pos_adj[i] - neg_weights[i] * ocrdata.neg_adj[i];
|
||||
if (weight > max) then
|
||||
begin
|
||||
max:= weight;
|
||||
result:= ocrdata.map[i];
|
||||
end;
|
||||
max:= weight;
|
||||
result:= ocrdata.map[i];
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
{converts a TPA into a 1-0 image of the smallest possible size}
|
||||
function PointsToNorm(points: TpointArray; out w,h: integer): TNormArray;
|
||||
var
|
||||
l,r,t,b: integer;
|
||||
i,len,size: integer;
|
||||
norm: TNormArray;
|
||||
l,r,t,b: integer;
|
||||
i,len,size: integer;
|
||||
norm: TNormArray;
|
||||
begin
|
||||
len:= length(points);
|
||||
l:= points[0].x;
|
||||
r:= points[0].x;
|
||||
t:= points[0].y;
|
||||
b:= points[0].y;
|
||||
for i:= 1 to len-1 do
|
||||
begin
|
||||
if points[i].x < l then l:= points[i].x;
|
||||
if points[i].x > r then r:= points[i].x;
|
||||
if points[i].y < t then t:= points[i].y;
|
||||
if points[i].y > b then b:= points[i].y;
|
||||
end;
|
||||
w:= r - l + 1;
|
||||
h:= b - t + 1;
|
||||
size:= w * h;
|
||||
SetLength(norm,size);
|
||||
for i:= 0 to len-1 do
|
||||
norm[(points[i].x - l) + (points[i].y - t) * w]:= 1;
|
||||
result:= norm;
|
||||
len:= length(points);
|
||||
l:= points[0].x;
|
||||
r:= points[0].x;
|
||||
t:= points[0].y;
|
||||
b:= points[0].y;
|
||||
for i:= 1 to len-1 do
|
||||
begin
|
||||
if points[i].x < l then l:= points[i].x;
|
||||
if points[i].x > r then r:= points[i].x;
|
||||
if points[i].y < t then t:= points[i].y;
|
||||
if points[i].y > b then b:= points[i].y;
|
||||
end;
|
||||
w:= r - l + 1;
|
||||
h:= b - t + 1;
|
||||
size:= w * h;
|
||||
SetLength(norm,size);
|
||||
for i:= 0 to len-1 do
|
||||
norm[(points[i].x - l) + (points[i].y - t) * w]:= 1;
|
||||
result:= norm;
|
||||
end;
|
||||
|
||||
function ImageToNorm(src: TRGB32Array; w,h: integer): TNormArray;
|
||||
var
|
||||
norm: TNormArray;
|
||||
i: integer;
|
||||
norm: TNormArray;
|
||||
i: integer;
|
||||
begin
|
||||
SetLength(norm,w*h);
|
||||
for i:= 0 to w*h-1 do
|
||||
if (src[i].r = 255) and (src[i].g = 255) and (src[i].b = 255) then
|
||||
norm[i]:= 1 else norm[i]:= 0;
|
||||
result:= norm;
|
||||
SetLength(norm,w*h);
|
||||
for i:= 0 to w*h-1 do
|
||||
if (src[i].r = 255) and (src[i].g = 255) and (src[i].b = 255) then
|
||||
norm[i]:= 1 else norm[i]:= 0;
|
||||
result:= norm;
|
||||
end;
|
||||
|
||||
{takes a mask of only one line of text, a TocrData, and returns the string in it}
|
||||
function ocrDetect(txt: TNormArray; w,h: integer; var ocrdata: TocrData): string;
|
||||
var
|
||||
l,r,t,b,x,y,xx,yy: integer;
|
||||
upper,left,last,spaces: integer;
|
||||
glyph: TNormArray;
|
||||
empty: boolean;
|
||||
ascii: char;
|
||||
l,r,t,b,x,y,xx,yy: integer;
|
||||
upper,left,last,spaces: integer;
|
||||
glyph: TNormArray;
|
||||
empty: boolean;
|
||||
ascii: char;
|
||||
begin
|
||||
result:= '';
|
||||
l:= -1;
|
||||
r:= -1;
|
||||
upper:= -9001; //large negative
|
||||
left:= -9001; //large negative
|
||||
x:= 0;
|
||||
while x < w do
|
||||
result:= '';
|
||||
l:= -1;
|
||||
r:= -1;
|
||||
upper:= -9001; //large negative
|
||||
left:= -9001; //large negative
|
||||
x:= 0;
|
||||
while x < w do
|
||||
begin
|
||||
empty:= true;
|
||||
for y:= 0 to h-1 do
|
||||
begin
|
||||
empty:= true;
|
||||
for y:= 0 to h-1 do
|
||||
begin
|
||||
if txt[x+y*w] = 1 then
|
||||
begin
|
||||
empty:= false;
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
if (l = -1) and (not empty) then
|
||||
begin
|
||||
l:= x
|
||||
end else if (l <> -1) then
|
||||
begin
|
||||
if empty then
|
||||
r:= x - 1
|
||||
else if x = w-1 then
|
||||
r:= x;
|
||||
end;
|
||||
if (r <> -1) and (l <> -1) then
|
||||
begin
|
||||
t:= -1;
|
||||
b:= -1;
|
||||
SetLength(glyph,0);
|
||||
SetLength(glyph,ocrdata.width*ocrdata.height);
|
||||
for yy:= 0 to h-1 do
|
||||
begin
|
||||
for xx:= l to r do
|
||||
if txt[xx+yy*w] = 1 then begin t:= yy; break; end;
|
||||
if t <> -1 then break;
|
||||
end;
|
||||
for yy:= h-1 downto 0 do
|
||||
begin
|
||||
for xx:= l to r do
|
||||
if txt[xx+yy*w] = 1 then begin b:= yy; break; end;
|
||||
if b <> -1 then break;
|
||||
end;
|
||||
if b - t + 1 > ocrdata.height then b:= b - (b-t+1-ocrdata.height);
|
||||
if r - l + 1 > ocrdata.width then r:= r - (r-l+1-ocrdata.width);
|
||||
for yy:= t to b do
|
||||
for xx:= l to r do
|
||||
glyph[(xx-l) + (yy-t)*ocrdata.width]:= txt[xx+yy*w];
|
||||
|
||||
ascii:= GuessGlyph(glyph,ocrdata);
|
||||
if (upper = -9001) or (left = -9001) then
|
||||
begin
|
||||
upper:= t - ocrdata.ascii[ord(ascii)].yoff;
|
||||
left:= l - ocrdata.ascii[ord(ascii)].xoff + ocrdata.ascii[ord(ascii)].width;
|
||||
x:= left;
|
||||
end else
|
||||
begin
|
||||
last:= left;
|
||||
left:= l - ocrdata.ascii[ord(ascii)].xoff;
|
||||
if last <> left then
|
||||
begin
|
||||
for spaces:= 1 to (left - last) div ocrdata.ascii[32].width do
|
||||
result:= result + ' ';
|
||||
end;
|
||||
left:= left + ocrdata.ascii[ord(ascii)].width;
|
||||
x:= left;
|
||||
end;
|
||||
|
||||
result:= result + ascii;
|
||||
|
||||
l:= -1;
|
||||
r:= -1;
|
||||
|
||||
end;
|
||||
inc(x);
|
||||
if txt[x+y*w] = 1 then
|
||||
begin
|
||||
empty:= false;
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
if (l = -1) and (not empty) then
|
||||
begin
|
||||
l:= x
|
||||
end else if (l <> -1) then
|
||||
begin
|
||||
if empty then
|
||||
r:= x - 1
|
||||
else if x = w-1 then
|
||||
r:= x;
|
||||
end;
|
||||
if (r <> -1) and (l <> -1) then
|
||||
begin
|
||||
t:= -1;
|
||||
b:= -1;
|
||||
SetLength(glyph,0);
|
||||
SetLength(glyph,ocrdata.width*ocrdata.height);
|
||||
for yy:= 0 to h-1 do
|
||||
begin
|
||||
for xx:= l to r do
|
||||
if txt[xx+yy*w] = 1 then begin t:= yy; break; end;
|
||||
if t <> -1 then break;
|
||||
end;
|
||||
for yy:= h-1 downto 0 do
|
||||
begin
|
||||
for xx:= l to r do
|
||||
if txt[xx+yy*w] = 1 then begin b:= yy; break; end;
|
||||
if b <> -1 then break;
|
||||
end;
|
||||
if b - t + 1 > ocrdata.height then b:= b - (b-t+1-ocrdata.height);
|
||||
if r - l + 1 > ocrdata.width then r:= r - (r-l+1-ocrdata.width);
|
||||
for yy:= t to b do
|
||||
for xx:= l to r do
|
||||
glyph[(xx-l) + (yy-t)*ocrdata.width]:= txt[xx+yy*w];
|
||||
|
||||
ascii:= GuessGlyph(glyph,ocrdata);
|
||||
if (upper = -9001) or (left = -9001) then
|
||||
begin
|
||||
upper:= t - ocrdata.ascii[ord(ascii)].yoff;
|
||||
left:= l - ocrdata.ascii[ord(ascii)].xoff + ocrdata.ascii[ord(ascii)].width;
|
||||
x:= left;
|
||||
end else
|
||||
begin
|
||||
last:= left;
|
||||
left:= l - ocrdata.ascii[ord(ascii)].xoff;
|
||||
if last <> left then
|
||||
begin
|
||||
for spaces:= 1 to (left - last) div ocrdata.ascii[32].width do
|
||||
result:= result + ' ';
|
||||
end;
|
||||
left:= left + ocrdata.ascii[ord(ascii)].width;
|
||||
x:= left;
|
||||
end;
|
||||
result:= result + ascii;
|
||||
l:= -1;
|
||||
r:= -1;
|
||||
end;
|
||||
inc(x);
|
||||
end;
|
||||
end;
|
||||
|
||||
function AvgColors(color1:TRGB32; weight1: integer; color2: TRGB32; weight2: integer): TRGB32;
|
||||
begin
|
||||
result.r:= (color1.r * weight1 + color2.r * weight2) div (weight1 + weight2);
|
||||
result.g:= (color1.g * weight1 + color2.g * weight2) div (weight1 + weight2);
|
||||
result.b:= (color1.b * weight1 + color2.b * weight2) div (weight1 + weight2);
|
||||
result.r:= (color1.r * weight1 + color2.r * weight2) div (weight1 + weight2);
|
||||
result.g:= (color1.g * weight1 + color2.g * weight2) div (weight1 + weight2);
|
||||
result.b:= (color1.b * weight1 + color2.b * weight2) div (weight1 + weight2);
|
||||
end;
|
||||
|
||||
procedure RGBtoXYZ(color: TRGB32; out X, Y, Z: real); inline;
|
||||
var
|
||||
nr,ng,nb: real;
|
||||
nr,ng,nb: real;
|
||||
begin
|
||||
nr:= color.r / 255.0;
|
||||
ng:= color.g / 255.0;
|
||||
nb:= color.b / 255.0;
|
||||
if nr <= 0.04045 then nr:= nr / 12.92 else nr:= power((nr + 0.055)/1.055,2.4);
|
||||
if ng <= 0.04045 then ng:= ng / 12.92 else ng:= power((ng + 0.055)/1.055,2.4);
|
||||
if nb <= 0.04045 then nr:= nb / 12.92 else nb:= power((nb + 0.055)/1.055,2.4);
|
||||
X:= 0.4124*nr + 0.3576*ng + 0.1805*nb;
|
||||
Y:= 0.2126*nr + 0.7152*ng + 0.0722*nb;
|
||||
Z:= 0.0193*nr + 0.1192*ng + 0.9505*nb;
|
||||
nr:= color.r / 255.0;
|
||||
ng:= color.g / 255.0;
|
||||
nb:= color.b / 255.0;
|
||||
if nr <= 0.04045 then nr:= nr / 12.92 else nr:= power((nr + 0.055)/1.055,2.4);
|
||||
if ng <= 0.04045 then ng:= ng / 12.92 else ng:= power((ng + 0.055)/1.055,2.4);
|
||||
if nb <= 0.04045 then nr:= nb / 12.92 else nb:= power((nb + 0.055)/1.055,2.4);
|
||||
X:= 0.4124*nr + 0.3576*ng + 0.1805*nb;
|
||||
Y:= 0.2126*nr + 0.7152*ng + 0.0722*nb;
|
||||
Z:= 0.0193*nr + 0.1192*ng + 0.9505*nb;
|
||||
end;
|
||||
|
||||
function labmod(i: real): real; inline;
|
||||
begin
|
||||
if i > power(0.206896552,3) then
|
||||
result:= power(i,0.333333333)
|
||||
else
|
||||
result:= 7.787037037*i + 0.137931034;
|
||||
if i > power(0.206896552,3) then
|
||||
result:= power(i,0.333333333)
|
||||
else
|
||||
result:= 7.787037037*i + 0.137931034;
|
||||
end;
|
||||
|
||||
function ColortoLab(c: TRGB32): tLab; inline;
|
||||
var
|
||||
X,Y,Z,sum,Xn,Yn,Zn: real;
|
||||
X,Y,Z,sum,Xn,Yn,Zn: real;
|
||||
begin
|
||||
RGBtoXYZ(c,X,Y,Z);
|
||||
sum:= X + Y + Z;
|
||||
if(sum = 0) then
|
||||
begin
|
||||
result.l := 0.0;
|
||||
result.a := 0.0;
|
||||
result.b := 0.0;
|
||||
end;
|
||||
Xn:= X / sum;
|
||||
Yn:= Y / sum;
|
||||
Zn:= Z / sum;
|
||||
result.L:= 116.0*labmod(y/yn) - 16.0;
|
||||
result.a:= 500.0*(labmod(x/xn)-labmod(y/yn));
|
||||
result.b:= 500.0*(labmod(y/yn)-labmod(z/zn));
|
||||
RGBtoXYZ(c,X,Y,Z);
|
||||
sum:= X + Y + Z;
|
||||
if(sum = 0) then
|
||||
begin
|
||||
result.l := 0.0;
|
||||
result.a := 0.0;
|
||||
result.b := 0.0;
|
||||
end;
|
||||
Xn:= X / sum;
|
||||
Yn:= Y / sum;
|
||||
Zn:= Z / sum;
|
||||
result.L:= 116.0*labmod(y/yn) - 16.0;
|
||||
result.a:= 500.0*(labmod(x/xn)-labmod(y/yn));
|
||||
result.b:= 500.0*(labmod(y/yn)-labmod(z/zn));
|
||||
end;
|
||||
|
||||
function colorDistSqr(a,b:TRGB32): integer; inline;
|
||||
begin
|
||||
result:= (a.r-b.r)*(a.r-b.r)+(a.b-b.b)*(a.b-b.b)+(a.g-b.g)*(a.g-b.g);
|
||||
result:= (a.r-b.r)*(a.r-b.r)+(a.b-b.b)*(a.b-b.b)+(a.g-b.g)*(a.g-b.g);
|
||||
end;
|
||||
|
||||
function ExtractText(colors: PRGB32;{colors: tRGBArray;} w,h: integer): TNormArray;
|
||||
@ -595,32 +560,5 @@ begin
|
||||
result:= norm;
|
||||
end;
|
||||
|
||||
function MakeTPAString(str: string): TpointArray;
|
||||
var
|
||||
i,j,c,off: integer;
|
||||
bmp: array of Tbmp;
|
||||
begin
|
||||
raise Exception.Create('MakeTPAString sucks ass, don''t use it.');
|
||||
c:= 0;
|
||||
off:= 0;
|
||||
SetLength(bmp,length(str));
|
||||
for i:= 0 to length(str)-1 do
|
||||
begin
|
||||
bmp[i]:= ReadBmp('/home/merlijn/Programs/mufasa/Fonts/StatChars/' + inttostr(ord(str[i+1])) + '.bmp');
|
||||
SetLength(result,c+bmp[i].width*bmp[i].height);
|
||||
for j:= 0 to bmp[i].width*bmp[i].height - 1 do
|
||||
begin
|
||||
if bmp[i].data[j].g = 255 then
|
||||
begin
|
||||
result[c].x:= j mod bmp[i].width + off;
|
||||
result[c].y:= j div bmp[i].width;
|
||||
inc(c);
|
||||
end;
|
||||
end;
|
||||
off:= off + bmp[i].width;
|
||||
SetLength(result,c);
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user