ALPRIM Ver 1.0 リファレンスマニュアル

目次
  1. レイヤとCLUSTER構造体
    1. レイヤ
    2. PRIMITIVE構造体
    3. CLUSTER構造体
    4. ALTABLE構造体
    5. ライブラリのファイル構成
  2. 各論
    1. インスタンスの構築と破棄
      2000年11月06日更新 ライセンスコードに加えて、ライセンスコードファイルも指定できるようになった
    2. 画像の設定
    3. ビットマップ→プリミティブ変換
    4. クラスタ抽出
    5. クラスタの角度推定
    6. クラスタの外接矩形計算
    7. 表抽出
    8. プリミティブ選択操作
    9. 直線による文字列選択
    10. 雑音の選択
    11. 枠に接触するプリミティブの選択
    12. プリミティブのレイヤ間移動
    13. レイヤ削除
    14. レイヤのビットマップ取得
    15. クラスタのビットマップ取得
    16. レイヤのビットマップを任意倍率で取得
    17. プリミティブの特徴計算
    18. オーバーライド(クラスタ抽出)
    19. オーバーライド(プリミティブのレイヤ間移動)
    20. オーバーライド(文字の定義)
    21. アンドゥ機能サポート関数(2000年10月10日追加)
  3. 2000年07月13日更新
    1. CJocrPrimEXクラスによる新機能追加
    2. パラメータファイル仕様
  4. 2000年10月10日更新
    1. CLUSTER構造体の更新
    2. ABSTRACTPARAMETER構造体の更新
    3. ABSTRACTPARAMETER::mcontrolフラグの追加
    4. CJocrPrimEXクラスによる角度推定
    5. クラスタの外接矩形計算の機能追加
    6. アンドゥ機能サポート関数の追加(各論:21)
    7. DLL、ヘッダファイルの追加
    8. CJocrPrimRDクラスによる角度推定
  5. 2001年07月25日更新
    1. PRIMFEATURE構造体の更新
    2. mgetvalidclusternum関数のマニュアル記述の削除
  6. 2002年07月26日更新
    1. ライブラリ内部で確保しているメモリの総バイト数を取得
    2. プリミティブ編集機能
    3. アンドゥ機能サポート関数(新版)
    4. レイヤ間移動関数の追加
    5. 初期化チェック関数の追加
    6. プリミティブのビットマップ取得
  7. 2002年07月31日更新
    1. 破線抽出
    2. 文字抽出パラメータの推定
  8. 2003年04月01日更新
    1. ラスタ編集コマンド


マニュアルホームページ

ユーザーズマニュアル


1.レイヤとCLUSTER構造体


1.1 レイヤ

CJocrPrimでは0~254までの255のレイヤが存在します。ビットマップをプリミティブに変換した場合、全てのプリミティブは、レイヤ0に格納されます。ユーザーの操作や雑音除去等の一括処理関数で、プリミティブを255層のレイヤに移動して、ビットマップ逆変換、削除、文字認識、ベクトル変換といった処理を、各レイヤに対して行うことができます。
たとえば、文字に相当するプリミティブだけをレイヤ1に移動したとします。レイヤ0をビットマップに逆変換すると、文字以外のビットマップ画像となっています。レイヤ1をビットマップに逆変換すると文字部分だけのビットマップ画像となっています。

目次


1.2 PRIMITIVE構造体


プリミティブの構造体は以下のようになっています。テキストブロック抽出クラス(CJocrPrimクラスやCJocrPrimクラス)のサブクラスを開発する場合を除いて、開発者は通常この構造体に直接アクセスしません。参考までに挙げておきます。
// プリミティブ特徴構造体
typedef struct _PRIMFEATURE {
    int                pixel;        // プリミティブ領域の面積
    int                length;       // プリミティブ領域の周囲長
    double             cx;           // 重心x
    double             cy;           // 重心y

// featureexは2001年07月25日追加
// 2001年07月25日時点では常にNULL。構造体の内容も未確定(コンパイルには問題なし)
	PRIMFEATUREEX*	featureex;	     // 拡張特徴(将来の拡張用、円形度・線幅等・2次モーメント特徴などが拡張される予定)
} PRIMFEATURE;


typedef struct _PRIMITIVE {
    unsigned char   layer;      // プリミティブのレイヤ番号
    unsigned char   undo;       // プリミティブの元のレイヤ
    unsigned char   unused;     // 使われていない時1
    unsigned char   flag;       // 汎用制御フラグ
    int             xmin;       // プリミティブ領域の左上(Y軸正方向が下の場合)座標
    int             ymin;
    int             xmax;       // プリミティブ領域の右下(Y軸正方向が下の場合)座標
    int             ymax;
    PRIMFEATURE*    feature;
} PRIMITIVE;
目次

1.3 CLUSTER構造体


クラスタの構造体は以下のようになっています。
typedef struct _CLUSTER {
    int             num;        // prim配列の要素数
    int             validnum;   // prim配列の有効要素数
    int             max;        // prim配列のサイズ
    PRIMITIVE**     pprim;
    unsigned char   flag;       // 0...通常のクラスタ(fusionする)
                                // 1...孤立クラスタ(fusionしない)
    unsigned char   loc;        // 0...枠の遠く:隣接セグメントのクラスタと無関係
                                // 1...上枠の近く:上セグメントのクラスタとfusion
                                // 2...下枠の近く:下セグメントのクラスタとfusion
                                // 4...左枠の近く:左セグメントのクラスタとfusion
                                // 8...右枠の近く:右セグメントのクラスタとfusion
    unsigned char   unused;     // 0...使われている
                                // 1...使われていない
    unsigned char   reserved2;
    short           line;       // 表の場合の行
    short           column;     // 表の場合の列
    PRIMITIVE*      parent;     // クラスタの属するプリミティブ(表など)
    long            pwidthmax;  // クラスタ内要素の最大幅
    long            pheightmax; // クラスタ内要素の最大高さ
    long            xmin;       // クラスタの左上(Y軸正方向が下の場合)の座標
    long            ymin;
    long            xmax;       // クラスタの右下(Y軸正方向が下の場合)の座標
    long            ymax;

// angleは2000年10月10日追加
	double			angle;		// クラスタの推定・指定角度(機能追加用)
	void*			pdata;		// 予備
} CLUSTER;
目次

1.4 ALTABLE構造体


表の構造体は以下のようになっています。
typedef struct _ALTABLE {
    int             num;        // クラスタ数
    int             max;        // クラスタ配列領域のサイズ
    CLUSTER**       ppcluster;  // クラスタ配列
    PRIMITIVE*      prim;       // 表に相当するプリミティブ
    long            xmin;       // 表の左上(Y軸正方向が下の場合)座標
    long            ymin;
    long            xmax;      // 表の右下(Y軸正方向が下の場合)座標
    long            ymax;
} ALTABLE;

目次

リファレンスマニュアル 2000年10月10日DLL追加

1.5 ライブラリのファイル構成

クラス名 CJocrPrimRDまたはCJocrPrimEXまたはCJocrPrim
ヘッダファイル ocrdef.h
ocrco.h
primitive.h
cjocrprim.h
absparam.h
cjocrprimex.h
cjocrprimrd.h
errcode.h
必要なLIB NGKOCR4.LIB
必要なDLL NGKOCR1.DLL
NGKOCR2.DLL
NGKOCR4.DLL
ALVEC.DLL
ALPOLYGON.DLL
コンパイル定数 USENGKDLL4

2.各論


2.1 インスタンスの構築と破棄

目次
ライブラリライセンサーから供給される20桁のコードを指定してインスタンスを構築します。
あるいは、ライブラリライセンサーから供給される、ライセンスコードファイルのパスを指定します。
CJocrPrim* prim = new CJocrPrim("ABCDEFGHJKLMNPQ23456");
....
delete prim;
あるいは

CJocrPrim* prim = new CJocrPrim("C:\\Program Files\\Foo\\primitive.kcd");
....
delete prim;
初期化されているかどうかのチェックは以下のようにmchecklimitを使って行う。 ライセンスコードの期限切れやハードウェアロック不良などの理由でライブラ リが使えない場合は、返り値が1となる。無期限のライセンスファイル等を使っ ている場合はチェックの必要は無い。
        if(mpjocrprim->mchecklimit(3)) {
            delete mpjocrrecognize;
            mpjocrrecognize = NULL;
        }
//      int         mchecklimit(int level)
//      入力
//          int     level;      // ライブラリユーザーの場合常に3
//      返り値が1の場合初期化ができていない

目次


2.2 画像の設定

目次

インスタンスを作った後に、ドキュメント画像の先頭アドレス、背景のビット値、幅と高さをセットします。
画像がバイト境界でない場合は、1行のバイト数(スキャンラインサイズ)を指定するバージョンの関数を用いて設定します。
// ドキュメント画像の設定
    void msetdocument(unsigned char* buffer,int background,int width,int height);
// スキャンラインサイズの指定
    void msetdocument(unsigned char* buffer,int background,int width,int scanlinesize,int height);
    入力
    unsigned char*  buffer;         // 画像の先頭アドレス
    int             background;     // 背景のビット値(0...bit0が背景/1...bit1が背景)
    int             width;          // 画像の幅(ピクセル単位)
    int             scanlinesize;   // 1行のバイト数
    int             height;         // 画像の高さ(ピクセル単位)

目次


2.3 ビットマップ→プリミティブ変換

目次

ビットマップデータであるドキュメント画像をプリミティブデータに変換します。ビットマップデータの一部の変換も可能です。通常は4連結でつながっている前景領域をプリミティブとしますが、関数に"8"がついているものを使うと、8連結でつながっている前景領域をプリミティブとみなします。

4連結と8連結
// ビットマップ→プリミティブ変換
// ビットマップ全体の変換
    int makeprim();
    int makeprim8();
// 長方形領域(傾き不可)を指定して、その内部だけ変換
    int makeprim(int x1,int y1,int x2,int y2);
    int makeprim8(int x1,int y1,int x2,int y2);
    入力
    int        x1,y1;    長方形の左上座標
    int        x2,y2;    長方形の右下座標
    返り値
        0................正常終了
        MEMORY_SHORTAGE..メモリが不足している

// 任意の凸矩形領域を指定して、その内部だけ変換
// 任意の角度の長方形も可
    int makeprim(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4);
    int makeprim8(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4);
    入力
    int        x1,y1;   凸矩形の4つの座標(順番は任意でも良い)
    int        x2,y2;
    int        x3,y3;
    int        x4,y4;
    返り値
        0...............正常終了
        MEMORY_SHORTAGE.メモリが不足している
// プリミティブ数の取得
    int mgetvalidprimitivenum();
// layer上のプリミティブ数の取得
    int mgetvalidprimitivenum(int layer);
    返り値
        変換した結果のプリミティブの数

目次



#include    "ocrdef.h"
#include    "ocrco.h"
#include    "cjocrprim.h"
#include    "errcode.h"
...
....
// ライセンサーから供給される20桁のコードあるいはライセンスコードファイルのパスを指定して、ライブラリを初期化
CJocrPrim* pjocrprim = new CJocrPrim("ABCDEFGHJKLMNPQ23456");
// ライセンスコードパスの場合はCJocrPrim* prim = new CJocrPrim("C:\\Program Files\\Foo\\primitive.kcd");
pjocrprim->msetdocument(mdata,0,mwidth,mheight);        // 背景が0前景が1のモノクロ画像
ret = pjocrprim->makeprim();
if(ret < 0) {
    エラー;
}
delete pjocrprim;
...

目次


2.4 クラスタ抽出

目次

複数のプリミティブをまとめてクラスタとして抽出します。まとめる基準として、各プリミティブの大きさ、各プリミティブ間の距離、各クラスタのサイズ、各クラスタを構成するプリミティブの数といった4つのパラメータの上限値と下限値を指定します。
クラスタ抽出は、仮想関数をオーバーライドすることによって、完全にカスタマイズすることができます。詳しくは、オーバーライド(クラスタ抽出)をご覧ください。
// dpiの設定
// ポイント単位をピクセル単位に変換するためにdpiを設定します
    void msetdpi(int dpi);
    入力
        int         dpi;        // 解像度
// 文字サイズの設定
// 最大プリミティブサイズと最小プリミティブサイズを指定
    void msetpoint(int maxpoint,int minpoint);
    入力
        int         maxpoint;   // 最大プリミティブサイズ(minpointポイント以上(72ポイント=1インチ))
        int         minpoint;   // 最小プリミティブサイズ(1ポイント以上(72ポイント=1インチ))
// 文書タイプの設定
// 斜めの場合のポイント数の解釈が変わる
// 斜めの指定が無いと、角度推定は0度あるいは90度のどちらかに限定される。
    void msetvflag(int vflag);
    入力
       int         vflag;       // 1...横書きのみ(bit0)
                                // 2...縦書きのみ(bit1)
                                // 3...横書き+縦書き(斜めなし)
                                // 4...斜めあり(bit0,bit1の値は無視)
// 1行文字数、1ブロック行数の設定、文字間、行間
// いわゆるクラスタのサイズと、一つのクラスタにまとめるプリミティブ間の距離の指定に相当する
// charperline×lineperblockが1クラスタの最大プリミティブ数となる
    void msetcharline(int charperline,int lineperblock,int charspace,int linespace);
    入力
        int         charperline;    // 1行文字数
        int         lineperblock;   // 1段落行数
        int         chaspace;       // 横方向(縦書きでは縦方向)のプリミティブ間の距離
                                    // (ポイント(72ポイント=1インチ))
        int         linespace;      // 縦方向(縦書きでは横方向)のプリミティブ間の距離
                                    // (ポイント(72ポイント=1インチ))
// 1クラスタの文字数の最小値
// 1クラスタに含まれるプリミティブ数に相当する
    void msetminnum(int aminnum);
    入力
        int         aminnum;    // 最小のプリミティブ数
///////////////////////
// 最小・最大文字サイズの推定
    void minferpoint(int& amin,int& amax,int layer);
    入力
        int         layer;      // layer内で推定
    出力
        int&        amin;       // 最小文字サイズ(ポイント(72ポイント=1インチ))
        int&        amax;       // 最大文字サイズ(ポイント(72ポイント=1インチ))
/////////////////
// クラスタの抽出
// 上記のパラメータに基づいてクラスタを抽出する
    int mabstractcluster(int from,int to);
    入力
        int         from;      // 移動元レイヤ
        int         to;        // 移動先レイヤ
    返り値
        0以上.............抽出したクラスタ数
        MEMORY_SHORTAGE...メモリが不足している
// 抽出クラスタデータの取得
// 呼ぶ側でのバッファpclusterを確保する
// 内部でクラスタ領域をスタティックに持っているが、そこには計算途中で破棄された無効な
// クラスタも含まれているので、有効クラスタだけ抜き出すという意味で、この関数が提供さ
// れている
    void mgetvalidcluster(CLUSTER* pcluster);
    入力
    CLUSTER*        pcluster;       クラスタを入れるバッファ
                                    sizeof(CLUSTER) * 抽出したクラスタ数
    出力
    CLUSTER*        pcluster;       抽出したクラスタデータ

目次



#include    "ocrdef.h"
#include    "ocrco.h"
#include    "cjocrprim.h"
#include    "errcode.h"
...
....
// ライセンサーから供給される20桁のコードあるいはライセンスコードファイルのパスを指定して、ライブラリを初期化
CJocrPrim* pjocrprim = new CJocrPrim("ABCDEFGHJKLMNPQ23456");
// ライセンスコードパスの場合はCJocrPrim* prim = new CJocrPrim("C:\\Program Files\\Foo\\primitive.kcd");
pjocrprim->msetdocument(mdata,0,mwidth,mheight);      // 背景が0前景が1のモノクロ画像
ret = pjocrprim->makeprim();
if(ret < 0) {
    エラー;
}
// クラスタの抽出
int clusternum = pjocrprim->mabstractcluster(0,1);
if(clusternum < 0) {
    エラー;
}
CLUSTER* pcluster = (CLUSTER*)malloc(sizeof(CLUSTER) * clusternum);
if(pcluster) {
    // クラスタの取得
    mgetvalidcluster(pcluster);
}
delete pjocrprim;
...

目次


2.5 クラスタの角度推定

目次

抽出したクラスタをテキストの段落と考えたときのクラスタの角度を推定する。各プリミティブ同士の接続角度やクラスタを囲む最小面積の矩形の角度などから総合的に推定されます。
角度は、y軸正方向が下の場合は時計周りが正、y軸正方向が上の場合は反時計周りが正となるラジアン単位の角度です。
// クラスタの角度推定計算
    void mcalcangle(CLUSTER* pcluster,double& angle);
    入力
        CLUSTER*    pcluster;       クラスタ(mgetvalidclusterで取得したクラスタ)
    出力
        double&     angle;          推定角度(ラジアン)
指定された角度から±5度の範囲で角度を推定します。moveprimlinestring関数等で、ユーザーが指定した角度を基準に角度を推定する場合には、こちらの関数を使います。
// クラスタの角度推定計算
    void mcalcanglespec(CLUSTER* pcluster,double& angle);
    入力
        CLUSTER*    pcluster;       クラスタ(mgetvalidclusterで取得したクラスタ)
        double&     angle;          指定角度(ラジアン)
    出力
        double&     angle;          推定角度(ラジアン)

目次



#include    "ocrdef.h"
#include    "ocrco.h"
#include    "cjocrprim.h"
#include    "errcode.h"
...
....
// ライセンサーから供給される20桁のコードあるいはライセンスコードファイルのパスを指定して、ライブラリを初期化
CJocrPrim* pjocrprim = new CJocrPrim("ABCDEFGHJKLMNPQ23456");
// ライセンスコードパスの場合はCJocrPrim* prim = new CJocrPrim("C:\\Program Files\\Foo\\primitive.kcd");
pjocrprim->msetdocument(mdata,0,mwidth,mheight);      // 背景が0前景が1のモノクロ画像
ret = pjocrprim->makeprim();
if(ret < 0) {
    エラー;
}
// クラスタの抽出(クラスタに属するプリミティブはレイヤ1へ移動)
int clusternum = pjocrprim->mabstractcluster(0,1);
if(clusternum < 0) {
    エラー;
}
CLUSTER* pcluster = (CLUSTER*)malloc(sizeof(CLUSTER) * clusternum);
if(pcluster) {
    // クラスタの取得
    mgetvalidcluster(pcluster);
    for(int i = 0 ; i < clusternum ; i++) {
        double    angle;
        pjocrprim->mcalcangle(pcluster + i,angle);  // angleが推定された角度(ラジアン)
                                                    // 実際のベースラインの角度はangleかangle+π/2
        ....
        ...
    }
}
delete pjocrprim;
...
目次


2.6 クラスタの外接矩形計算

目次

この関数は、クラスタの外接矩形を取得する関数です。テキストの段落として考える場合、ベースライン(横書きではテキストの下のライン、縦書きではテキストの右のライン)が、どこにあるかは、この関数の結果から推定する必要があります。
たとえば横書きでは、
  1. 水平に近い下側の辺がベースラインである。
  2. 長辺の下側の辺がベースラインである。
といった基準が考えられるが、この2つの基準が矛盾する可能性もあり、100%の精度で推定することは難しくなります。
この関数の返す外接矩形は、デフォルトでは枠の1ピクセル外側にクラスタ(テキストブロック)の最外周枠が来るようになっています。extに1.0以上の値を指定するようにするとクラスタよりもextピクセル(少数点以下切り捨て)外側に枠が設定されます。
デフォルトのクラスタの外接枠の計算は、クラスタを構成するプリミティブの最小外接矩形を囲む外接枠であるため、斜めに傾いたクラスタ(テキストブロック)では、外接枠が実際の図形から離れてしまいます。

傾いた枠
2000年10月10日外接枠計算において、斜めのテキストブロックにおいても、外接枠が実際の図形から離れないようにすることができるようになりました。

第8引数についての記述追加(2021/07/04)
クラスタの角度推定(mcalcangle)による角度推定、あるいはユーザーのマウス操作等による角度指定の後に、その部分のクラスタ(テキストブロック)の外接長方形枠を計算するために使います
  1. angleが水平、垂直に近い場合はrecalcflagが1でも0でも結果は変わりません。
  2. それ以外で斜めの枠を計算する場合に、枠と文字の間に隙間ができることがあります。 recalcflagが1の場合は隙間を図形にぶつかるまで縮小します。
  3. 第7引数のextが0.0以外の場合枠を拡縮しますが、拡縮はrecalcflagによる縮小処理の後 に行います。文字枠にぶつかってしまうのでextを負にすることはお勧めしません。

// 座標の順番は、以下の通りになっている。
// [0]           |           [1]
//  +------------+------------+
//  |     2      |      1     |
// -+------------+------------+-軸線
//  |     3      |      4     |
//  +------------+------------+
// [3]           |           [2]
//        mcalcframeによる枠の座標配置
//        0...クラスタ中心に対して、第2象限
//        1...クラスタ中心に対して、第1象限
//        2...クラスタ中心に対して、第4象限
//        3...クラスタ中心に対して、第3象限
// クラスタの外接枠計算
    void mcalcframe(CLUSTER* pcl,double angle,double* px,double* py,double& dh,double& dv,double ext = 0.0,int recalcflag);
    入力
    CLUSTER*        pcl;        // クラスタ
    double          angle;      // 軸線の角度(ラジアン)
    double          ext;        // 全ての座標をextピクセルだけ外側に広げる
                                // デフォルト値は0.0

// 2000年10月10日機能追加
    int             recalcflag  // 1にした場合、外接枠がプリミティブに接触するまで縮小する
                                // 斜めの外接矩形の枠とプリミティブの隙間を縮小する
                                // デフォルト値は0
    出力
    double*         px;         // px[4]...外接枠の座標
    double*         py;         // py[4]...外接枠の座標
mcalcframe
                                // dhの角度がangle(y軸正方向が下の場合時計周りが正)
                                                  (y軸正方向が上の場合反時計周りが正)
    double&         dh;         // クラスタの軸線の長さ(必ずしも水平に近いわけではない)
    double&         dv;         // クラスタの軸線と垂直に交差する線の長さ(必ずしも垂直に近いわけではない)

mcalcangle/mcalcframe組み合わせのコード例についての記述追加(2021/07/04)
mcalcangleで角度を推定した後にmcalcframeで外接長方形枠座標を計算するコードの例を以下に示します。
{
//  CLUSTER* pcluster;
//  pclusterは何らかのAPIによって抽出したクラスタであるとする
	double		angle;
	double		dh,dv;
	double		x[4];
	double		y[4];

	mpjocrprim->mcalcangle(pcluster,angle);         // pclusterを元にangleを求める
	mpjocrprim->mcalcframe(pcluster,angle,x,y,dh,dv,0.0,1); // pclusterとangleを元にx[4],y[4],dh,dvを求める
                                                    // recalcflagは1なので斜めの場合も枠と文字の間に余分な空白が無くなる
//  (x[3],y[3])-(x[2],y[2])がテキスト行のベースライン
//  行の高さ(幅)はdv
}
目次



#include    "ocrdef.h"
#include    "ocrco.h"
#include    "cjocrprim.h"
#include    "errcode.h"
...
....
// ライセンサーから供給される20桁のコードあるいはライセンスコードファイルのパスを指定して、ライブラリを初期化
CJocrPrim* pjocrprim = new CJocrPrim("ABCDEFGHJKLMNPQ23456");
// ライセンスコードパスの場合はCJocrPrim* prim = new CJocrPrim("C:\\Program Files\\Foo\\primitive.kcd");
pjocrprim->msetdocument(mdata,0,mwidth,mheight);      // 背景が0前景が1のモノクロ画像
ret = pjocrprim->makeprim();
if(ret < 0) {
    エラー;
}
// クラスタの抽出
int clusternum = pjocrprim->mabstractcluster(0,1);
if(clusternum < 0) {
    エラー;
}
CLUSTER* pcluster = (CLUSTER*)malloc(sizeof(CLUSTER) * clusternum);
if(pcluster) {
    // クラスタの取得
    mgetvalidcluster(pcluster);
    for(int i = 0 ; i < clusternum ; i++) {
        double    x[4];
        double    y[4];
        double    dh
        double    dv;
        pjocrprim->mcalcframe(pcluster + i,0,x,y,dh,dv);    // 角度0度として外接矩形を取得
        ....
        ...
    }
}
delete pjocrprim;
...
目次


2.7 表抽出

目次

表を抽出します。mabstractclusterの後に呼びます。表には
  1. 1つのクラスタを外枠で囲んだもの
  2. 2つ以上のクラスタがあり、各クラスタ間が線図形で区切られているもの、最外周の外枠は無くてもよい
という2つのタイプが存在します。通常の長方形でセルが区切られた表ではなく、以下のようなものも、表に含まれます。

変な表
表は単独のプリミティブである必要があります。罫線は特に直線である必要はありません。
///////////////////////
// 表処理オペレーション
// クラスタ抽出(mabstractcluster)の後にコールする
    int mabstracttable(int clusterlayer,int from,int to);
    入力
      int       clusterlayer;       // クラスタを抽出したレイヤ
      int       from;               // 表を抽出するレイヤ
      int       to;                 // 抽出した表の移動先
    返り値
        0以上.............抽出した表の数
        MEMORY_SHORTAGE...メモリ不足
// 抽出した表の数の取得
    int         mgettablenum();
// 抽出した表の取得
    ALTABLE*    mgettable();        // 内部のポインタを指しているので、解放、変更は不可
表に属するクラスタのアドレスはALTABLE構造体に格納されている。各クラスタが表の何行目、何列目に属するかは、クラスタ構造体のline、columnメンバに代入されている。行と列のカウントは1行目、1列目から始まる。
目次



#include    "ocrdef.h"
#include    "ocrco.h"
#include    "cjocrprim.h"
#include    "errcode.h"
...
....
// ライセンサーから供給される20桁のコードあるいはライセンスコードファイルのパスを指定して、ライブラリを初期化
CJocrPrim* pjocrprim = new CJocrPrim("ABCDEFGHJKLMNPQ23456");
// ライセンスコードパスの場合はCJocrPrim* prim = new CJocrPrim("C:\\Program Files\\Foo\\primitive.kcd");
pjocrprim->msetdocument(mdata,0,mwidth,mheight);      // 背景が0前景が1のモノクロ画像
ret = pjocrprim->makeprim();
if(ret < 0) {
    エラー;
}
// クラスタの抽出
ret = pjocrprim->mabstractcluster(0,1);
// 表の抽出
ret = pjocrprim->mabstracttable(1,0,1);
int tablenum = pjocrprim->mgettablenum();
if(tablenum) {
    // 表の取得
    ALTABLE* ptable = pjocrprim->mgettable();
    ....
}
delete pjocrprim;
...
目次


2.8 プリミティブ選択操作

目次

ユーザーの操作(マウス等)によって、プリミティブを選択するときに利用する関数。
// 矩形内にかかるプリミティブをfromからtoへ移動
    int moveprimrecthook(int x1,int y1,int x2,int y2,int from,int to,int mojiflag);
// 矩形内にかかるプリミティブをfromからtoへ移動+移動したプリミティブをクラスタ化
    int moveprimrecthookcluster(int x1,int y1,int x2,int y2,int from,int to,int mojiflag);
    入力
    int             x1,y1;      // 長方形の座標
    int             x2,y2;
    int             from;       // 移動元レイヤ
    int             to;         // 移動先レイヤ
    int             mojiflag;   // 1の場合は、msetpointで指示された文字サイズに収まるプリミティブだけを移動する
                                // オーバーライド(文字の定義)でmojifilter関数をオーバーライドしている場合は、そちらを優先
    返り値
    0以上..........移動したプリミティブの数
    負.............MEMORY_SHORTAGEメモリ不足
// 斜め矩形内にかかるプリミティブをfromからtoへ移動
    int moveprimrecthook(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4,int from,int to,int mojiflag);
// 斜め矩形内にかかるプリミティブをfromからtoへ移動をクラスタ化
    int moveprimrecthookcluster(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4,int from,int to,int mojiflag);
    入力
    int             x1,y1;      // 斜め矩形の座標(座標の順番は任意)
    int             x2,y2;
    int             x3,y3;
    int             x4,y4;
    int             from;       // 移動元レイヤ
    int             to;         // 移動先レイヤ
    int             mojiflag;   // 1の場合は、msetpointで指示された文字サイズに収まるプリミティブだけを移動する
                                // オーバーライド(文字の定義)でmojifilter関数をオーバーライドしている場合は、そちらを優先
    返り値
    0以上..........移動したプリミティブの数
    負.............MEMORY_SHORTAGEメモリ不足
// 矩形内に完全に含まれるプリミティブをfromからtoへ移動
    int moveprimrect(int x1,int y1,int x2,int y2,int from,int to,int mojiflag);
// 矩形内に完全に含まれるプリミティブをfromからtoへ移動をクラスタ化
    int moveprimrectcluster(int x1,int y1,int x2,int y2,int from,int to,int mojiflag);
    入力
    int             x1,y1;      // 長方形の座標
    int             x2,y2;
    int             from;       // 移動元レイヤ
    int             to;         // 移動先レイヤ
    int             mojiflag;   // 1の場合は、msetpointで指示された文字サイズに収まるプリミティブだけを移動する
                                // オーバーライド(文字の定義)でmojifilter関数をオーバーライドしている場合は、そちらを優先
    返り値
    0以上..........移動したプリミティブの数
    負.............MEMORY_SHORTAGEメモリ不足
// 斜め矩形内完全に含まれるプリミティブをfromからtoへ移動
    int moveprimrect(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4,int from,int to,int mojiflag);
// 斜め矩形内完全に含まれるプリミティブをfromからtoへ移動をクラスタ化
    int moveprimrectcluster(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4,int from,int to,int mojiflag);
    入力
    int             x1,y1;      // 斜め矩形の座標(座標の順番は任意)
    int             x2,y2;
    int             x3,y3;
    int             x4,y4;
    int             from;       // 移動元レイヤ
    int             to;         // 移動先レイヤ
    int             mojiflag;   // 1の場合は、msetpointで指示された文字サイズに収まるプリミティブだけを移動する
                                // オーバーライド(文字の定義)でmojifilter関数をオーバーライドしている場合は、そちらを優先
    返り値
    0以上..........移動したプリミティブの数
    負.............MEMORY_SHORTAGEメモリ不足
// 直線に接触するプリミティブをfromからtoへ移動
    int moveprimline(int x1,int y1,int x2,int y2,int from,int to);
// 直線に接触するプリミティブをfromからtoへ移動をクラスタ化
    int moveprimlinecluster(int x1,int y1,int x2,int y2,int from,int to);
    入力
    int             x1,y1;      // 直線の始点
    int             x2,y2;      // 直線の終点
    int             from;       // 移動元レイヤ
    int             to;         // 移動先レイヤ
    返り値
    0以上..........移動したプリミティブの数
    負.............MEMORY_SHORTAGEメモリ不足

目次


2.9 直線による文字列選択

目次

2点で指定した線分に沿った文字列を、選択してfromからtoへ移動します。同時にクラスタ化します。通常は、msetpointで指示された文字サイズに収まるプリミティブだけを移動しますが、オーバーライド(文字の定義)でmojifilter関数をオーバーライドしている場合は、そちらを優先します。

// 直線に接触するプリミティブ+プリミティブの構成する矩形に含まれるプリミティブをfromからtoへ移動
    int moveprimlinestring(int x1,int y1,int x2,int y2,int from,int to,double* px,double* py);
    入力
    int             x1,y1;      // 直線の始点
    int             x2,y2;      // 直線の終点
    int             from;       // 移動元レイヤ
    int             to;         // 移動先レイヤ
	double*			px;			// sizeof(double) * 4の配列のアドレス(動作チェック用)
	double*			py;			// sizeof(double) * 4の配列のアドレス(動作チェック用)
    返り値
        0以上.............移動したプリミティブの数
        MEMORY_SHORTAGE...メモリ不足

サンプルコード
線分に沿った文字列を選択して傾きを推定し外接矩形を求めます。
#include    "ocrdef.h"
#include    "ocrco.h"
#include    "cjocrprim.h"
#include    "errcode.h"
...
....
// ライセンサーから供給される20桁のコードあるいはライセンスコードファイルのパスを指定して、ライブラリを初期化
CJocrPrim* pjocrprim = new CJocrPrim("ABCDEFGHJKLMNPQ23456");
// ライセンスコードパスの場合はCJocrPrim* prim = new CJocrPrim("C:\\Program Files\\Foo\\primitive.kcd");
pjocrprim->msetdocument(mdata,0,mwidth,mheight);      // 背景が0前景が1のモノクロ画像
ret = pjocrprim->makeprim();
if(ret < 0) {
    エラー;
}
...
// マウス等で(x1,y1)から(x2,y2)までの座標を指定する
...
double  x[4];
double  y[4];
ret = pjocrprim->moveprimlinestring(x1,y1,x2,y2,from,to,x,y);
if(ret > 0) {
        CLUSTER cluster;
        pjocrprim->mgetvalidcluster(&cluster);
        double  angle;
        angle = atan2((double)(y2 - y1),(double)(x2 - x1));
        // ユーザーが指定した線分の角度から±5度の範囲で角度推定
        pjocrprim->mcalcanglespec(&cluster,angle);
        double  dh,dv;
        // 外接枠の計算(プリミティブの外接枠の外接枠を計算)
        pjocrprim->mcalcframe(mpcluster,angle,x,y,dh,dv);
        ...
}
delete pjocrprim;
...
目次


2.10 雑音の選択

目次
// ノイズをlayerに移動
    int movenoise(int xsize,int ysize,int from,int to);
    入力
    int         xsize;          // 幅xsizeピクセル以下かつ高さysizeピクセル以下
    int         ysize;          // をノイズとして処理する
    int         from;           // 移動元レイヤ
    int         to;             // 移動先レイヤ
    返り値
    0以上..........移動したプリミティブの数
    負.............MEMORY_SHORTAGEメモリ不足

目次



#include    "ocrdef.h"
#include    "ocrco.h"
#include    "cjocrprim.h"
#include    "errcode.h"
...
....
// ライセンサーから供給される20桁のコードあるいはライセンスコードファイルのパスを指定して、ライブラリを初期化
CJocrPrim* pjocrprim = new CJocrPrim("ABCDEFGHJKLMNPQ23456");
// ライセンスコードパスの場合はCJocrPrim* prim = new CJocrPrim("C:\\Program Files\\Foo\\primitive.kcd");
pjocrprim->msetdocument(mdata,0,mwidth,mheight);        // 背景が0前景が1のモノクロ画像
ret = pjocrprim->makeprim();
if(ret < 0) {
    エラー;
}
// 雑音の選択
pjocrprim->movenoise(7,7,0,1);  // 縦横いずれも7ピクセル以下の4連結bit1領域を雑音とする
                                // 雑音に相当するプリミティブをレイヤ1へ移動する
// 雑音の除去
pjocrprim->mdeleteprim(1);      // レイヤ1のプリミティブを消去する
                                // 元データにも反映する
delete pjocrprim;
...
目次


2.11 枠に接触するプリミティブの選択

目次
// 最外周フレームに接触するプリミティブをlayerへ移動
    int movetouchframe(int from,int to);
    入力
        int        from;        // 移動元レイヤ
        int        to;          // 移動先レイヤ
    返り値
    0以上..........移動したプリミティブの数
    負.............MEMORY_SHORTAGEメモリ不足

目次



#include    "ocrdef.h"
#include    "ocrco.h"
#include    "cjocrprim.h"
#include    "errcode.h"
...
....
// ライセンサーから供給される20桁のコードあるいはライセンスコードファイルのパスを指定して、ライブラリを初期化
CJocrPrim* pjocrprim = new CJocrPrim("ABCDEFGHJKLMNPQ23456");
// ライセンスコードパスの場合はCJocrPrim* prim = new CJocrPrim("C:\\Program Files\\Foo\\primitive.kcd");
pjocrprim->msetdocument(mdata,0,mwidth,mheight);        // 背景が0前景が1のモノクロ画像
ret = pjocrprim->makeprim();
if(ret < 0) {
    エラー;
}
// 枠に接触するプリミティブの選択
pjocrprim->movetouchframe(0,1);    // 最外周に接触するプリミティブをレイヤ1へ移動する
// 枠に接触するプリミティブの除去
pjocrprim->mdeleteprim(1);         // レイヤ1のプリミティブを消去する
                                   // 元データにも反映する
delete pjocrprim;
...
目次


2.12 プリミティブのレイヤ間移動

目次
// プリミティブをレイヤfromからtoに移動
    int            moveprim(int from = 0,int to = 1);
    入力
        int        from;        // 移動元レイヤ
        int        to;          // 移動先レイヤ
    返り値
        移動したプリミティブの数
// プリミティブをレイヤfromからtoに移動(長方形指定)
    int            moveprimloc(int x1,int y1,int x2,int y2,int from,int to);
    入力
        int        x1,int y1,int x2,int y2; // (x1,y1)-(x2,y2) 長方形の左上、右下座標
    返り値
        移動したプリミティブの数
// amin<= pixel <= amaxピクセルのプリミティブをレイヤfromからtoに移動
    int            moveprimpixel(int amin,int amax,int from = 0,int to = 1);
    入力
        int        amin,amax;              プリミティブの最小面積と最大面積
    返り値
        移動したプリミティブの数
// amin<= 面積 <= amax、heightmin <= 高さ <= heightmax、widthmin <= 幅 <= widthmaxのプリミティブをレイヤfromからtoに移動
    int             moveprimsizepixel(int areamin,int areamax,int widthmin,int heightmin,int widthmax,int heightmax,int from,int to);
    入力
        int         areamin,int areamax;    面積の範囲(単位:平方ピクセル)
        int         widthmin,heightmin;     幅と高さの最小値(単位:ピクセル)
        int         widthmax,heightmax;     幅と高さの最大値(単位:ピクセル)
    返り値
        移動したプリミティブの数

目次


2.13 レイヤ削除

目次
// layer上のプリミティブ除去と元画像への反映
    void mdeleteprim(int layer);
    入力
        int        layer;        // 移動先レイヤ

目次


2.14 レイヤのビットマップ取得

目次

モノクロでの取得のみ。

// プリミティブ→ビットマップ逆変換
// 幅と高さは元のドキュメントと同じ
// コールする側でバッファを確保、管理、解放する
// 入力
//    int             layer;      0~255...逆変換するレイヤ
// 出力
//  unsigned char* pdata;       ビットマップ
void makebitmap(int layer,unsigned char* pdata);

目次


2.15 クラスタのビットマップ取得

目次

クラスタを囲む矩形内部にクラスタに属さないプリミティブが存在する場合があります。この関数を使えば、純粋にクラスタに属するプリミティブのビットマップだけを取得することができます。
文字認識などの処理の前に呼び出します。

// バッファの管理はライブラリ内部で行われる
// 入力
//    CLUSTER*          pcluster;   クラスタ
//    double            angle;      回転角
// 出力
//    unsigned char*&   pdata;      ビットマップ
//    int&              width;      ビットマップの幅(ピクセル単位)
//    int&              height;     ビットマップの高さ(ピクセル単位)
// クラスタのビットマップ取得
void makebitmapcluster(CLUSTER* pcluster,unsigned char*& pdata,int& width,int& height);
// クラスタに属するプリミティブをangleライジアン回転したビットマップを返す
// クラスタのビットマップ取得(angleラジアン回転)
void makebitmapcluster(CLUSTER* pcluster,double angle,unsigned char*& pdata,int& width,int& height);

目次



#include    "ocrdef.h"
#include    "ocrco.h"
#include    "cjocrprim.h"
#include    "errcode.h"
...
....
// ライセンサーから供給される20桁のコードあるいはライセンスコードファイルのパスを指定して、ライブラリを初期化
CJocrPrim* pjocrprim = new CJocrPrim("ABCDEFGHJKLMNPQ23456");
// ライセンスコードパスの場合はCJocrPrim* prim = new CJocrPrim("C:\\Program Files\\Foo\\primitive.kcd");
pjocrprim->msetdocument(mdata,0,mwidth,mheight);        // 背景が0前景が1のモノクロ画像
ret = pjocrprim->makeprim();
if(ret < 0) {
    エラー;
}
// ユーザーの操作でプリミティブをレイヤ1へ移動
// 斜め矩形内にかかるプリミティブをfromからtoへ移動+移動したプリミティブをクラスタ化
pjocrprim->moveprimrecthookcluster(x1,y1,x2,y2,x3,y3,y4,y4,0,1);
// クラスタを取得
// クラスタのビットマップ取得(angleラジアン回転)
double             angle = atan2((double)(y2 - y1),(double)(x2 - x1));
mpjocrprim->makebitmapcluster(mpjocrprim->mgetcluster(),angle,pdata,width,height);
// pdataにwidth×heightピクセルデータが入る
// 矩形の(x1,y1)-(x2,y2)が水平になるようにangle角回転される
delete pjocrprim;
...
目次


2.16 レイヤのビットマップを任意倍率で取得

目次

モノクロでの取得と255色カラーでの取得の2通りになります。

// 入力
//      int             layer;      表示用データに変換するレイヤ(モノクロのみ)
//      int             width;      作成する画像の幅
//      int             height;     作成する画像の高さ
//      int             offsetx;    x軸オフセット
//      int             offsety;    y軸オフセット
//      double          mag;        倍率(等倍は1.0)
// 出力
//      unsigned char*  pdata;  表示用のデータ(width×heightのdibを入れるために十分なサイズ)
// 指定レイヤDIBモノクロ(4バイトバウンダリ)
    void makedispdatadib2(int layer,int width,int height,int offsetx,int offsety,double mag,unsigned char* pdata);
// DIB255色カラー画像データ作成(4バイトバウンダリ)
// 属するレイヤ=パレットインデックスになる
    void makedispdatadib255(int width,int height,int offsetx,int offsety,double mag,unsigned char* pdata);

目次


2.17 プリミティブの特徴計算

目次

全てのプリミティブの面積、周囲長、重心といった特徴を計算します。
周囲長や重心の計算は計算量が多いため、特に使わない場合は、mcalcfeaturepixelで面積だけ計算します。

// プリミティブ特徴計算
//      int             mcalcfeature();
// プリミティブ特徴計算(面積のみ)
//      int             mcalcfeaturepixel();

目次


2.18 オーバーライド(クラスタ抽出)

目次

クラスタ抽出をオーバーライドしてカスタマイズします

// カスタマイズを反映するクラスタ抽出
//      int             mabstractclusterfilter(int from,int to);
// オーバーライド用の関数
// 返り値が1のものをクタスタ化の対象とする
//      virtual int     mprimitivefilter(PRIMITIVE* prim);
// 返り値が1のものを一つのクラスタにまとめる
//      virtual int     mlocationfilter(PRIMITIVE* prim1,PRIMITIVE* prim2);
// 返り値が1のものを有効クラスタとする
//      virtual int     mclusterfilter(CLUSTER* pcluster);
オーバーライド用の三つの仮想関数を用いて、クラスタ抽出をカスタマイズします。オーバーライドをするには、CJocrPrimクラスのサブクラスを定義する必要があります。また、オーバーライド関数、mlocationfilterの中では、以下の関数を使うことができます。
// 二つのプリミティブの間にセパレータ(クラスタに属さない図形の一部)があるときに1を返す。
//      virtual int     mlocationfilter(PRIMITIVE* prim1,PRIMITIVE* prim2);
オーバーライドを使ったクラスタ抽出のコード例を以下にあげます。
class CJocrSub : public CJocrPrim {
        public:
                CJocrSub(char* code) : CJocrPrim(alcode){}
                ~CJocrSub(){}
        private:
                int             minpixel;       // プリミティブの最小面積
                int             maxpixel;       // プリミティブの最大面積
                double  minrate;        // プリミティブの最小高さ/幅
                double  maxrate;        // プリミティブの最大高さ/幅
        private:
                double  mindist;        // プリミティブ間の最小距離
                double  maxdist;        // プリミティブ間の最大距離
        private:
                int             mleft;          // クラスタの位置(左上)
                int             mtop;           // クラスタの位置(左上)
                int             mright;         // クラスタの位置(右下)
                int             mbottom;        // クラスタの位置(右下)
        public:
                void    msetparameter(int aminpixel,int amaxpixel,double aminrate,double amaxrate)
                {
                        minpixel = aminpixel;   // プリミティブの最小面積
                        maxpixel = amaxpixel;   // プリミティブの最大面積
                        minrate = aminrate;             // プリミティブの最小高さ/幅
                        maxrate = amaxrate;             // プリミティブの最大高さ/幅
                }
                void    msetparameter(double amindist,double amaxdist)
                {
                        mindist = amindist;
                        maxdist = amaxdist;
                }
                void    msetparameter(int left,int top,int right,int bottom)
                {
                        mleft = left;           // クラスタの位置(左上)
                        mtop = top;                     // クラスタの位置(左上)
                        mright = right;         // クラスタの位置(右下)
mbottom = bottom;       // クラスタの位置(右下)
                }
        public:
                // オーバーライド
                virtual int     mprimitivefilter(PRIMITIVE* prim)
                {
                        PRIMFEATURE* feature = prim->feature;
                        if(feature && minpixel <= feature->pixel && feature->pixel <= maxpixel)
                                return 1;
                        return 0;
                }
                // オーバーライド
                virtual int     mlocationfilter(PRIMITIVE* prim1,PRIMITIVE* prim2)
                {
                        double  cx1 = (prim1->xmin + prim1->xmax) / 2.0;
                        double  cy1 = (prim1->ymin + prim1->ymax) / 2.0;
                        double  cx2 = (prim2->xmin + prim2->xmax) / 2.0;
                        double  cy2 = (prim2->ymin + prim2->ymax) / 2.0;
                        double  d = sqrt((cx2 - cx1) * (cx2 - cx1) + (cy2 - cy1) * (cy2 - cy1));
                        if(mindist <= d &&  d < maxdist && !mcheckseparator(prim1,prim2))
                                return 1;
                        return 0;
                }
                // オーバーライド
                virtual int     mclusterfilter(CLUSTER* pcluster)
                {
                        if(pcluster->xmin < mleft) return(0);
                        if(mright < pcluster->xmax) return(0);
                        if(pcluster->ymin < mtop) return(0);
                        if(mbottom < pcluster->ymax) return(0);
                        return(1);
                }
};
基本クラスでは、プリミティブのサイズによってクラスタ化の対象とするかどうかを決めますが、サブクラスでは、プリミティブの面積と縦横比でクラスタ化の対象とするかどうかを決めます。
基本クラスでは、プリミティブ間の市街地距離によって、同じクラスタにまとめるかどうかを決めますが、サブクラスでは、ユークリッド距離で決めるようにします。
基本クラスでは、クラスタのサイズとクラスタ内のプリミティブ数によって、有効クラスタとするかどうかを決めますが、サブクラスではクラスタの位置で決めるようにカスタマイズします。

目次


2.19 オーバーライド(プリミティブのレイヤ間移動)

目次

プリミティブのレイヤ間移動をオーバーライドしてカスタマイズします

// カスタマイズを反映するレイヤ間移動関数
//      int             moveprimfilter(int from,int to);
// オーバーライド用の関数
// 返り値が1のものを移動の対象とする
//      virtual int     mprimitivefilter(PRIMITIVE* prim);
オーバーライド用の1つの仮想関数を用いて、レイヤ間移動をカスタマイズします。オーバーライドをするには、CJocrPrimクラスのサブクラスを定義する必要があります。オーバーライド(クラスタ抽出)を参照してください。

目次


2.20 オーバーライド(文字の定義)

目次

プリミティブ選択操作におけるmojiflagや直線による文字列選択での文字を規定する関数をオーバーライドする。通常はクラスタ抽出のmsetpointで指示された文字サイズに収まるプリミティブだけを移動する。

// 返り値1のものを移動する
virtual int mojifilter(PRIMITIVE* prim);
入力
    PRIMITIVE* prim;    // 判定対象のプリミティブ
返り値
    1...primは文字の全部あるいは一部である
    0...primは文字の一部でも全部でもない

例えばサブクラスを作って以下のような関数を定義すると(mdpiは解像度とする)、0.5インチ角すなわち36ポイント以下のプリミティブが文字の全部あるいは一部として処理されます。

virtual int mojifilter(PRIMITIVE* prim)
{
    int     width = prim->xmax - prim->xmin;
    int     height = prim->ymax - prim->ymin;
    if(width <= mdpi / 2 && height <= mdpi / 2)
        return(1);
    else
        return(0);
}

目次


2.21 アンドゥ機能サポート

目次
アンドゥ機能をサポートするために、現在のプリミティブとクラスタの内容を取得、再設定するための関数をいくつか提供します。
プリミティブ、クラスタのそれぞれに対して、
  1. 内容を取得するために必要なバッファのサイズの取得
  2. 1で得たバッファサイズのバッファを確保して内容を取得する
  3. 取得バッファの現在のプリミティブやクラスタに反映させる
という関数が提供されます。
        // プリミティブ
        // プリミティブ領域の保存サイズ取得
        // 返り値
        //   プリミティブの内容を全て保存するために必要なバッファサイズ
        int           mgetsavesize();
        // プリミティブのレイヤ等の保存
        // 入力/出力
        //   char*    buffer;         プリミティブの内容を保存するバッファ
        //                            mgetsavesizeで取得したサイズ以上が必要
        // バッファには以下のようにデータが入ります
        // +----------------------+
        // | 有効プリミティブ数 n | 4bytes
        // +----------------------+
        // |  PRIMITIVE 0         | sizeof(PRIMITIVE)
        // +----------------------+
        // |  PRIMITIVE 1         | sizeof(PRIMITIVE)
        // +----------------------+
        // |  PRIMITIVE ...       | sizeof(PRIMITIVE)
        // +----------------------+
        // |  PRIMITIVE n - 1     | sizeof(PRIMITIVE)
        // +----------------------+
        // 返り値
        //  0....正常終了
        //  負...エラー
        int           makesavebuffer(char* buffer);
        // プリミティブのレイヤ等の読み込み
        // 前提:全く同じ画像で、同じ連結条件(4連結か8連結か)でmakeprimが終了している必要がある
        // 注意:mgetsavesizeで取得したバッファとmreflectloadbufferで与えるバッファとは少し異なっている
        // 入力
        //   int      rvalidnum;      mgetsavebufferで取得したバッファの先頭4バイト(有効プリミティブ数)
        //   char*    buffer;         mgetsavebufferで取得したバッファの先頭4バイトを除いたもの
        // +----------------------+
        // |  PRIMITIVE 0         | sizeof(PRIMITIVE)
        // +----------------------+
        // |  PRIMITIVE 1         | sizeof(PRIMITIVE)
        // +----------------------+
        // |  PRIMITIVE ...       | sizeof(PRIMITIVE)
        // +----------------------+
        // |  PRIMITIVE n - 1     | sizeof(PRIMITIVE)
        // +----------------------+
        int               mreflectloadbuffer(int rvalidnum,char* buffer);
        //  0....正常終了
        //  負...エラー(画像やmakeprimの条件が異なっている場合を含む)
// クラスタ情報
        // クラスタの保存サイズ取得
        // 入力
        //   CLUSTER*     pcluster;   保存サイズを取得するクラスタ
        // 返り値
        //   pclusterを保存するために必要なバッファのサイズ
        int              mgetsaveclustersize(CLUSTER* pcluster);
        // クラスタ保存バッファの生成
        // 入力
        //   CLUSTER*     pcluster;   保存するクラスタ
        // 入出力
        //   char*        buffer;     クラスタの内容、mgetsaveclustersize/0で取得したサイズ以上必要
        // +----------------------+
        // |  CLUSTER             | sizeof(CLUSTER)
        // +----------------------+--------------------
        // |                      | sizeof(int)       これ以下をmrellectclusterbufferの第2引数で渡す
        // +----------------------+
        // |                      | sizeof(int)
        // +----------------------+
        // |                      | sizeof(int)
        // +----------------------+
        // 返り値
        //  0....正常終了
        //  負...エラー
        int               makesaveclusterbuffer(CLUSTER* pcluster,char* buffer);
        // クラスタ本体のロード(CLUSTERをロードして、pprim領域を確保後、pprim領域をロード)
        // プリミティブのレイヤ等の読み込み
        // 前提:全く同じ画像で、同じ連結条件(4連結か8連結か)でmakeprimが終了している必要がある
        // 注意:この関数を呼ぶ前にsizeof(CLUSTER)の領域を確保して、mgetsaveclusterbufferで保存したバッファの先頭の
        // sizeof(CLUSTER)バイトをコピーする
        // 入力
        //   CLUSTER*     pcluster;   上記「注意」を参照
        //   int*         pi;         mgetsavebufferで取得したバッファの先頭sizeof(CLUSTER)バイトを除いたもの
        // 返り値
        //  0....正常終了
        //  負...エラー
        int               mreflectclusterbuffer(CLUSTER* pcluster,int* pi);
目次


2.22 ライブラリ内部で確保しているメモリの総バイト数を取得

目次
ライブラリ内部で、現時点で確保しているメモリの総バイト数を取得する。
OSのメモリサイズと比較して、アンドゥバッファのサイズを設定したりすることなどに利用する。
        int               mgetmemoryinfo();
目次




2.23 プリミティブ編集機能

目次
プリミティブを移動、削除、挿入するといった編集処理を行う。
挿入、分離等あたらしいプリミティブが発生する場合は、msetinsertmaxで挿入バッファ領域のサイズを設定する必要がある。
msetinsertmaxは、makeprimやmakeprim8の前にコールする。
// プリミティブ構造編集
// 挿入可能なプリミティブ数の上限を設定する
// 上限に達した場合は、medit_insertやmedit_separateでエラーが返る
// その場合はクラスをいったん破棄して、再度new、その後msetinsertmaxしなおしてから再挿入
// 入力
//    int       insertmax;        デフォルト値は0、通常のA3,400dpi日本語文書では10000で十分
void            msetinsertmax(int insertmax){minsertmax = insertmax;}

基本的なプリミティブの削除、挿入、移動は以下の通り。
削除と移動だけを行う場合はmsetinsertmaxは不要である。
引数にPRMITIVEが指定されているものは1つのプリミティブに対する編集操作である。
引数にCLUSTERが指定されているものは1つのクラスタに対する編集操作である。

// プリミティブを削除
// 重複プリミティブ対応
// 入力
//   int        flag;        1...画像データに反映させる
//   PRIMITIVE* prim;        プリミティブ(アドレスを用いるのでコピーは駄目)
int             medit_delete(int flag,PRIMITIVE* prim);
int             medit_delete(int flag,CLUSTER* pcluster);
// プリミティブを挿入(pjocrprimがthisの場合はコピーとなる)
// 入力
//  int       flag;        1...画像データに反映させる
//   CJocrPrim* pjocrprim;   prim/pclusterの属するCJocrPrimのインスタンス
//   PRIMITIVE* prim;        挿入プリミティブ(アドレスを用いるのでコピーは駄目)
//   CLUSTER*   pcluster;    primの属するCJocrPrimのインスタンス
//   int        left,top;    移動先
int             medit_insert(int flag,CJocrPrim* pjocrprim,PRIMITIVE* prim,int left,int top,PRIMITIVE*& priminsert);
int             medit_insert(int flag,CJocrPrim* pjocrprim,CLUSTER* pcluster,int left,int top);
// プリミティブを移動(コピー+削除ではコストが大きいためこちらを用いると良い)
// 入力
//   int        flag;        1...画像データに反映させる
//   PRIMITIVE* prim;        プリミティブ(アドレスを用いるのでコピーは駄目)
//   int        left,top;    移動先
int             medit_move(int flag,PRIMITIVE* prim,int left,int top);
int             medit_move(int flag,CLUSTER* pcluster,int left,int top);

クラスタ単位の移動をサポートするために、全てのプリミティブをクラスタ化する関数を用意した。
クラスタの取得は、通常通りmgetcluster関数によって行う(できるクラスタは1つ)。

// 全てのプリミティブをクラスタ化
// レンダリングやクラスタ移動に用いる
int             mallprim2cluster();

クラスタ分割では、プリミティブの数が増えるためmsertinsertmaxをあらかじめコールしておくことが必要となる。
medit_separateは、切断線は画素の間(画素の左上を端点とする)とみなされるため、切断によって画像が変化することは無い。
medit_severは、切断線は画素の上とみなされるため、切断線上の画素が消える。
いずれの場合も切断線は複数の線分(ポリラインではなく、それぞれ離れた線分)で指定する。
medit_separateとmedit_sever
// クラスタを分割(ピクセルデータの消長が存在しない。表示上切れ目は存在しない)
// (処理コストが高いので注意:分割対象が多い場合は再初期化のほうが速い)
// 入力
//    int         linenum;           線分の数
//    int*        px1;               線分始点のx座標値
//    int*        py1;               線分始点のy座標値
//    int*        px2;               線分終点のx座標
//    int*        py2;               線分終点のy座標
//    CLUSTER*    pcluster;          切断対象のクラスタ
// 返り値
//    0.......正常終了
//    負......エラー
int                medit_separate(int linenum,int* px1,int* py1,int* px2,int* py2,CLUSTER* pcluster);
int                medit_sever(int linenum,int* px1,int* py1,int* px2,int* py2,CLUSTER* pcluster);
// ひとつのプリミティブから線分と線幅を指定した線ラスタの分離

つながった複数の線分(ポリライン)に沿った線画像を切断して独立したプリミティブにすることができる。
枠線と接触した文字の分離などに応用することができる。
medit_separateline
// ポリライン(始点と終点がつながった複数の線分)に沿ったプリミティブの分離
// 入力
//    int            flag;            0...ビットマップに反映しない
//                                    1...ビットマップに反映する
//    int            bridgeflag;      0...ブリッジ処理を行わない
//                                    1...ブリッジ処理を行う
//    int            horizontalflag;  0...斜め線
//                                    1...水平・垂直線が対象(通常は0のままでもOK)
//    int            pointnum;        ポリラインのポイント数
//    int*           px;              pointnum個のx座標値
//    int*           py;              pointnum個のy座標値
//    int            lwidth;          線幅
//    PRIMITIVE*    prim;             元のプリミティブ、primが削除されて分割されたプリミティブが挿入される
// 返り値
//    0.......正常終了
//    負......エラー
int                    medit_separateline(int flag,int bridgeflag,int horizontalflag,int pointnum,int* px,int* py,int lwidth,PRIMITIVE* prim);
目次




2.24 アンドゥ機能サポート関数(新版)

目次

アンドゥやファイル保存のために、プリミティブ構造を単一のバッファとして返す。
makesavebufferやmreflectloadbufferを使ったものはレイヤ移動の状態だけを保存するため、
プリミティブの移動、挿入、削除には対応できない。
プリミティブ編集の結果を反映するためにはこちらを使う。
全てのプリミティブ情報(レイヤ情報も一部に含まれる)を保存することができる。
画像を再現するためのデータを含んでいるため画像保存にも利用することができる。
int                    mgetprim2rlbuffersize();
// 返り値
//    プリミティブ構造にバッファ変換したときのバッファサイズ
int                    mprim2rl(unsigned char* retbuffer);
// プリミティブ構造のバッファ変換
// 入力
//    unsigned char*    retbuffer;            mgetprim2rlbuffersizeで取得したサイズのバッファ
// 返り値
//    0.......正常終了
//    負......エラー
int                    mrl2prim(unsigned char* buffer);
// プリミティブ構造の再現
// 入力
//    unsigned char*    buffer;               PRIMRLバッファ==mprim2rlで取得したもの
// 返り値
//    0.......正常終了
//    負......エラー
目次


2.25 プリミティブのビットマップ取得

目次
引数で指定したプリミティブのビットマップ画像を取得する。
// バッファの管理はライブラリ内部で行われる
// 入力
//    PRIMITIVE*        prim;       プリミティブ
// 出力
//    unsigned char*&   pdata;      ビットマップ
//    int&              width;      ビットマップの幅(ピクセル単位)
//    int&              height;     ビットマップの高さ(ピクセル単位)
// クラスタのビットマップ取得
// プリミティブのビットマップ取得
void          makebitmapprimitive(PRIMITIVE* prim,unsigned char*& pdata,int& width,int& height);


目次



マニュアルホームページ

ユーザーズマニュアル