LEADTOOLS supports importing and exporting to the IBM FileNet P8 and Daeja annotation formats. These formats store each object in a separate XML data or file.
P8 annotations come in the following format:
<FnAnno>
<PropDesc
F_ANNOTATEDID="{CB201A02-AF04-4808-A4E9-02692037AA9E}"
F_CLASSID="{D91B9511-9B46-4DF8-BA26-A672094688CD}"
F_ID="{CD364A2D-E80C-4157-BD77-D8ACF7AB31DE}"
F_ENTRYDATE="2018-02-28T08:16:05.0000000-08:00"
F_MODIFYDATE="2018-02-28T08:16:05.0000000-08:00"
F_NAME="1234"
F_MULTIPAGETIFFPAGENUMBER="0"
F_PAGENUMBER="1"
F_CLASSNAME="Highlight"
F_LEFT="1.0" F_TOP="1.0" F_HEIGHT="0.5" F_WIDTH="2.0" F_TEXT_BACKMODE="1" F_BRUSHCOLOR="65535" F_LINE_COLOR="65535" F_LINE_WIDTH="0">
<F_POINTS />
<F_TEXT />
<F_CUSTOM_BYTES />
</PropDesc>
</FnAnno>
Refer to the FileNet P8 documentation for the meaning of each property and attribute. In general, the F_CLASSNAME attribute contains the type of the annotation (line, rectangle, highlight, etc) and F_ID is the unique identifier of this object. F_PAGENUMBER contains the 1-based number of the page in the document of this object.
Support is provided through the AnnCodecs class with the following methods:
ConvertFromIBMP8: Converts a P8 annotation object to a LEADTOOLS AnnObject.
ConvertToIBMP8: Converts a LEADTOOLS AnnObject to P8 annotation object.
If the application is only interested in importing P8 annotations to LEADTOOLS, then ConvertFromIBMP8 is sufficient. For instance, this code snippet shows how to loop through a group of XML files on disk containing P8 annotations, converts them to LEADTOOLS AnnObject instance and add them to a container:
// inputDir contains one or more .xml files containing P8 annotation objects
private static AnnContainer P8_2_LEAD(string inputDir)
{
// Create the container, the code can be modified to use an existing container.
AnnContainer annContainer = new AnnContainer();
annContainer.Size = LeadSizeD.Create(8.5 * 720, 11 * 720);
annContainer.Mapper.MapResolutions(300, 300, 300, 300);
annContainer.PageNumber = 1;
IBMP8ReadOptions readOptions = new IBMP8ReadOptions();
// We must use a rendering engine and a mapper to help with calculating font sizes
readOptions.RenderingEngine = new Leadtools.Annotations.Rendering.AnnWinFormsRenderingEngine();
readOptions.Mapper = annContainer.Mapper;
foreach (var inputFile in Directory.EnumerateFiles(inputDir, "*.xml"))
{
// Get the P8 XML
string p8 = File.ReadAllText(inputFile);
// Convert the object to LEAD
AnnObject annObject = AnnCodecs.ConvertFromIBMP8(p8, readOptions);
// Add it to our container
annContainer.Children.Add(annObject);
}
return annContainer;
}
Exporting from LEAD annotations to P8 is also easy. This code will loop through all the AnnObject items in a container and saves them to a directory as IBMP8 objects:
// outputDir will contain one or more .xml files containing P8 annotation objects
private static void LEAD_2_P8(AnnContainer annContainer, string outputDir)
{
IBMP8WriteOptions writeOptions = new IBMP8WriteOptions();
// We must use a mapper to help with calculating font sizes
writeOptions.Mapper = annContainer.Mapper;
int objectNumber = 1;
foreach (AnnObject annObject in annContainer.Children)
{
// Convert to P8
string p8 = AnnCodecs.ConvertToIBMP8(annObject, writeOptions);
// Save to disk
string fileName = "object" + objectNumber;
objectNumber++;
File.WriteAllText(Path.Combine(outputDir, fileName), p8);
}
}
In addition to these methods, AnnCodecs also contains the following helper methods:
ReadIBMP8PropDescAttr: Gets the value of an attribute from the P8 data.
WriteIBMP8PropDescAttr: Sets or replaces the value of an attribute in the P8 data.
For example, to read the value of the F_PAGENUMBER value from P8 annotation to determine in what container (in a list) this annotation should be added, use the following code:
private static int FindPageNumber(string p8)
{
const string attributeName = AnnCodecs.IBM_PAGENUMBER; // Or use "F_PAGENUMBER" directly
string value = AnnCodecs.ReadIBMP8PropDescAttr(p8, attributeName);
// Does it exist and has a value?
if (!string.IsNullOrEmpty(value))
{
// Yes, parse it
return int.Parse(value);
}
// No, default to first page
return 1;
}
And the following code can quickly update or replace the page number value in P8 data:
private static void UpdatePageNumber(string p8, int pageNumber)
{
const string attributeName = AnnCodecs.IBM_PAGENUMBER; // Or use "F_PAGENUMBER" directly
string value = pageNumber.ToString();
IBMP8WriteOptions writeOptions = new IBMP8WriteOptions();
AnnCodecs.WriteIBMP8PropDescAttr(p8, attributeName, value, writeOptions);
}
Daeja Annotations come in the following format:
[LINE]
X1 = 1135
Y1 = 919
X2 = 1124
Y2 = 828
PAGE = 1
LINEWIDTH = 1
COLOR = 255, 0, 0
LABEL = Line3
TOOLTIP = 0.305"
RULERTOOL = 1
PAGESIZE = 2550, 3300
EDIT = 1
CREATEDATE = 26 JUL 2018, 19:14:41, EEST
MODIFIEDDATE = 26 JUL 2018, 19:14:41, EEST
Refer to the IBM Daeja documentation for the meaning of each property and attribute.
Support is provided through the AnnCodecs class with the following methods:
AnnCodecs.ConvertFromIBMDaeja: Converts IBM Daeja annotations to LEADTOOLS annotations.
AnnCodecs.ConvertToIBMDaeja: Converts LEADTOOLS annotations to IBM Daeja annotations.
The following Daeja annotations are supported:
ARROW, FREEHAND, HIGHLIGHT, HIGHLIGHTPOLYGON, NOTE, OPENPOLYGON, OVAL, POLYGON, RECTANGLE, REDACT, REDACTPOLYGON, STAMP, and TEXT.
The following Daeja annotation is not supported:
CUSTOM
If the application is only interested in importing Daeja annotations to LEADTOOLS, then ConvertFromIBMDaeja is sufficient. For instance, the following code snippet shows how to read an IBM Daeja annotations file, convert the annotations to LEADTOOLS AnnObjects and add them to a container:
private static AnnContainer Daeja_2_LEAD(string inputDaejaFile)
{
// If the input Daeja file does not have a page size, provide one.
// Assume a default of 8.5 by 11 inches with resolution equal to 300
// Size is in container coordinates
var pageSize = LeadSizeD.Create(8.5 * 720, 11 * 720);
double resolution = 300;
var mapper = new AnnContainerMapper(resolution, resolution, resolution, resolution);
var readOptions = new IBMDaejaReadOptions();
readOptions.Mapper = mapper;
readOptions.PageSize = pageSize;
// Convert Daeja annotations to LEADTOOLS annotations
string daeja = File.ReadAllText(inputDaejaFile);
AnnContainer annContainer = AnnCodecs.ConvertFromIBMDaeja(daeja, readOptions);
return annContainer;
}
Exporting from LEADTOOLS annotations to IBM Daeja is also easy:
private static void LEAD_2_Daeja(AnnContainer annContainer, string outputDaejaFile)
{
// Get the mapper from the container
var writeOptions = new IBMDaejaWriteOptions();
writeOptions.Mapper = annContainer.Mapper;
// Save LEADTOOLS annotations to Daeja
string daeja = AnnCodecs.ConvertToIBMDaeja(annContainer, writeOptions);
// Save the loaded Daeja to disk
File.WriteAllText(outputDaejaFile, daeja);
}