今天处理识别模块
人机界面
人机界面中,工具栏就不用说了,水平层次太低。
主要是要将图片显示在可编辑的界面中。
一是显示出图片
if (FWorkMode == wmRecognize && FQaImage) { // 识别模块OcrModule:在期望位置画出图形
TRect drawRect = FQaImageBounds;
if(drawRect.left < 10) {
drawRect.right -= drawRect.left - 10;
drawRect.left = 10;
}
if(drawRect.top < 10) {
drawRect.bottom -= drawRect.top - 10;
drawRect.top = 10;
}
FQaImage->DoQaDraw(pb->Canvas->Handle, drawRect, 0, FDrawSmooth); // 在期望位置画出图形
}
二是画出标尺
TCanvas * canvas = pb->Canvas;
// 准备画出选择区域
canvas->Brush->Color = 0x00CFE8CC;
canvas->Pen->Style = psClear;
TRect r = TRect(0, 0, 0, 0);
DrawPartBackground(canvas, pb->ClientRect,
r, GlobalBrushData);
canvas->Brush->Style = bsSolid;
canvas->Pen->Style = psSolid;
double delta = 5;
int length = 5;
startPos /= delta;
canvas->Brush->Style = bsClear;
canvas->Font->Color = clOlive;
for (int i = begin / delta; i <= end / delta; ++i) {
length = 5;
int pos = startPos + (i - begin / delta);
if (pos % 10 == 0)
length *= 3;
else if (pos % 5 == 0)
length *= 2;
double p = 0;
if (length == 15) {
p = pos * delta / Ratio;
int ip = p;
if (ip != p)
p = ip +int((p - ip) * 10) / 10;
}
if (horzFlag) {
canvas->MoveTo(i * delta, w);
canvas->LineTo(i * delta, w - length);
if (length == 15)
canvas->TextOut(i * delta + 1, 0, p);
}
else {
canvas->MoveTo(w, i * delta);
canvas->LineTo(w - length, i * delta);
if (length == 15) {
UnicodeString str = p;
if (str.Length() > 3)
str.Delete(1, str.Length() - 3);
canvas->TextOut(0, i * delta + 1, str);
}
}
}
--w;
if (horzFlag) {
canvas->MoveTo(begin, w);
canvas->LineTo(end, w);
}
else {
canvas->MoveTo(w, 0);
canvas->LineTo(w, end);
}
运行结果:
手动分区
设计使用方式:
点击分区类型,如果未选中分区对象,则创建指定类型分区;如果选中分区对象,则指定所选中分区对象的类型
分区对象类型:
或下拉后:
目前先支持这些。
类型:文字0,条码1,图片2,表格3,公式4,矢量图5
enum TQaOcrRegionType {
ocrText = 0,
ocrBarCode = 1,
ocrPicture = 2,
ocrTable = 3,
ocrFormula = 4,
ocrVectorGraph = 5 };
先支持这么多吧。
嗯,一般的分区都是矩形的,使用起来有局限性,今天设计一下,分区可以是异形的,先完成椭圆和多边形吧。呃,要是以后把魔术棒方式实现了,用户可以更方便地进行分区设置,这个,想想都过瘾。先实现这几个简单的吧,魔术棒就等这个版本完成后再添加。
界面上加上选择按钮,将其名称改为"创建分区"
Button_SelectRect->Visible = (wmRecognize == FWorkMode || wmPicture == FWorkMode) ? true :false;
Button_ReverseSelect->Visible = wmRecognize == FWorkMode ? true :false;
Button_SelectRect->Caption = wmRecognize == FWorkMode ? L"创建分区" : L"选择";
再加上自动分区按钮,工具栏就成这个模样了
看起来还蛮舒服的。
创建操作,不外乎处理鼠标事件:MouseDown、MouseMove、MouseUp
MouseDown:
if (!IsObjectUnderConstructing && !Shift.Contains(ssRight)) { // 普通构造
CBW_DELETE(FSelectRegionObject);
cSelectedObjects->Selected = false;
cCurrentMeta = (TCbwObject*)(*CbwBuildObjectMap)[cClassType]();
AssignUItoObject(cCurrentMeta);
cCurrentMeta->Canvas = pb->Canvas;
FSelectRegionObject = cCurrentMeta;
TCbwBrushData * data = new TCbwBrushData;
data->GdiBrushStyle = bsClear;
FSelectRegionObject->BrushData = data;
delete data;
TCbwPenData * penData = new TCbwPenData;
*penData = *(FSelectRegionObject->PenData);
penData->Style = psDot;
FSelectRegionObject->PenData = penData;
delete penData;
}
if (!cCurrentMeta && Shift.Contains(ssRight)) {
SelectStateFlag = false;
PaintBox_Demo->Cursor = crDefault;
}
AdjustModelPoint(FBeginPointWithoutRatio, Shift.Contains(ssShift));
if (cCurrentMeta) {
cCurrentMeta->AddPoint(FBeginPointWithoutRatio); // 添加下一点
if (IsMultiPointMeta(cCurrentMeta) && Shift.Contains(ssRight))
cCurrentMeta->AddAllPoint(FCurrentPointWithoutRatio);
if (cCurrentMeta->IsAllObjectsConstructed)
SelectStateFlag = false;
else
IsObjectUnderConstructing = true;
}
MouseMove:
FCurrentPointWithoutRatio = TPoint(X / Ratio, Y / Ratio);
if (cCurrentMeta && !cCurrentMeta->IsAllObjectsConstructed)
cCurrentMeta->NextPoint = FCurrentPointWithoutRatio;
MouseUp:
TGlobalVariables::BaseModelPoint1.RegularPoint(X, Y, FRatio);
FCurrentPointWithoutRatio = TPoint(X / Ratio, Y / Ratio);
if (cCurrentMeta && !cCurrentMeta->IsAllObjectsConstructed)
cCurrentMeta->NextPoint = FCurrentPointWithoutRatio;
if (!IsObjectUnderConstructing)
return;
if (FCurrentPointWithoutRatio != FBeginPointWithoutRatio)
cCurrentMeta->AddPoint(FCurrentPointWithoutRatio);
if (cCurrentMeta->IsAllObjectsConstructed)
SelectStateFlag = false;
经过上述处理,已可画出各个分区对象
这些对象可被选择、拖动、缩放…,甚至可以拖动顶点,以前图形软件的组态功能用上了,哈。
下来就是可以设置这些分区的种类,不同类型以不同效果进行显示而已。
原来想加上过渡效果的,算了,不整那么花哨,哗众取宠的说。
这个功能倒是很简单,在类型选择事件中处理:
int tag = Sender->Tag;
TColor colors[] = {clRed, clBlue, clGreen, clPurple, clGray, clAqua };
if(cSelectedObjects->MetaNumber) {
CBW_ITERATOR(CbwObjects, cSelectedObjects->SubObjects) {
(*it)->Tag = tag;
cbw::util::TCbwBrushData * data = new cbw::util::TCbwBrushData;
*data = *((*it)->BrushData);
data->Color1 = colors[tag];
(*it)->BrushData = data;
delete data;
}
}
一个例示效果
举一个实际例子:
这个显示的颜色可以配置一下,加入到选项窗口中,之前界面
调整后选项设置界面
右边还有点空,给以后的选项留点空间,现在不着急考虑。
取颜色代码:
TColor colors[] = {
OptionForm->Shape_TextColor->Brush->Color,
OptionForm->Shape_BarCode->Brush->Color,
OptionForm->Shape_Picture->Brush->Color,
OptionForm->Shape_Table->Brush->Color,
OptionForm->Shape_Formula->Brush->Color,
OptionForm->Shape_Graph->Brush->Color
};
再处理一下选项中的颜色IO,今天工作告一段落。