Retrieves the number of compound graphic annotation objects in a certain "Graphic Annotation Sequence" (0070,0001) item.
#include "ltdic.h"
L_UINT16 LDicomDS::GetCompoundGraphicCount(pGraphicAnnSQItem, pCount)
Pointer to an item element under the "Graphic Annotation Sequence" (0070,0001) in the "Graphic Annotation Module".
Pointer to a variable, which will be updated with the graphical annotation object count.
Value | Meaning |
---|---|
DICOM_SUCCESS | The function was successful. |
>0 | An error occurred. Refer to Return Codes. |
Win32, x64
This example creates and saves a DICOM presentation state that contains two DICOM Compound Graphic objects: (1) a ruler and (2) a rotated filled rectangle
L_VOID CreateCompoundGraphicRuler(L_TCHAR *pszLayerName, pDICOMCOMPOUNDGRAPHIC pCompoundGraphic)
{
pCompoundGraphic->pszLayerName = pszLayerName;
pCompoundGraphic->uUnits = DICANN_UNIT_PIXEL;
pCompoundGraphic->uType = DICANN_TYPE_RULER;
pDICOMANNPOINT pts = (pDICOMANNPOINT)malloc(sizeof(DICOMANNPOINT) * 2);
if (pts)
{
pts[0].fX = 300.0f;
pts[0].fY = 100.0f;
pts[1].fX = 450.0f;
pts[1].fY = 100.0f;
pCompoundGraphic->pAnnPoints = pts;
pCompoundGraphic->nPointCount = 2;
}
pCompoundGraphic->uCompoundGraphicInstanceId = 100;
pCompoundGraphic->uGraphicGroupId = 0;
pCompoundGraphic->dRotationAngle = 0.0;
pCompoundGraphic->ptRotationPoint.fX = 0.0f;
pCompoundGraphic->ptRotationPoint.fY = 0.0f;
pCompoundGraphic->fGapLength = 0.0f;
pCompoundGraphic->fDiameterOfVisibility = 0;
pCompoundGraphic->uTickAlignment = DICANN_TICK_ALIGNMENT_CENTER;
pCompoundGraphic->uTickLabelAlignment = DICANN_TICK_LABEL_ALIGNMENT_BOTTOM;
pCompoundGraphic->bShowTickLabel = TRUE;
pCompoundGraphic->bFilled = FALSE;
pCompoundGraphic->uOptions = DICANN_OPTIONS_LINE_STYLE | DICANN_OPTIONS_TEXT_STYLE | DICANN_OPTIONS_COMPOUND_GRAPHIC_INSTANCE_ID;
// TextStyle
pDICOMTEXTSTYLE pTextStyle = (pDICOMTEXTSTYLE)malloc(sizeof(DICOMTEXTSTYLE));
if (pTextStyle)
{
ZeroMemory(pTextStyle, sizeof(DICOMTEXTSTYLE));
pTextStyle->uStructSize = sizeof(DICOMTEXTSTYLE);
pTextStyle->uTextOptions = DICANN_TEXT_OPTIONS_FONT_NAME;
_tcscpy_s(pTextStyle->szFontName, TEXT("Arial"));
_tcscpy_s(pTextStyle->szCssFontName, TEXT("serif"));
pTextStyle->uTextColorCieLabValue[0] = 34866; // Red
pTextStyle->uTextColorCieLabValue[1] = 53484;
pTextStyle->uTextColorCieLabValue[2] = 50171;
pTextStyle->uHorizontalAlign = DICANN_HORIZONTAL_ALIGNMENT_CENTER;
pTextStyle->uVerticalAlign = DICANN_HORIZONTAL_ALIGNMENT_CENTER;
pTextStyle->shadowStyle.uStructSize = sizeof(DICOMSHADOWSTYLE);
pTextStyle->shadowStyle.uShadowStyle = DICANN_SHADOW_STYLE_OFF;
pTextStyle->shadowStyle.fShadowOffsetX = 0;
pTextStyle->shadowStyle.fShadowOffsetY = 0;
pTextStyle->shadowStyle.uShadowColorCieLabValue[0] = 0;
pTextStyle->shadowStyle.uShadowColorCieLabValue[1] = 0;
pTextStyle->shadowStyle.uShadowColorCieLabValue[2] = 0;
pTextStyle->shadowStyle.fShadowOpacity = 0.0f;
pTextStyle->bUnderlined = FALSE;
pTextStyle->bItalic = FALSE;
pTextStyle->bBold = FALSE;
pCompoundGraphic->pTextStyle = pTextStyle;
}
// LineStyle
pDICOMLINESTYLE pLineStyle = (pDICOMLINESTYLE)malloc(sizeof(DICOMLINESTYLE));
if (pLineStyle)
{
ZeroMemory(pLineStyle, sizeof(DICOMLINESTYLE));
pLineStyle->uStructSize = sizeof(DICOMLINESTYLE);
pLineStyle->uLineOptions = DICANN_LINE_OPTIONS_PATTERN_OFF_COLOR_CIELAB_VALUE | DICANN_LINE_OPTIONS_PATTERN_OFF_OPACITY;
pLineStyle->shadowStyle.uStructSize = sizeof(DICOMSHADOWSTYLE);
pLineStyle->shadowStyle.uShadowStyle = DICANN_SHADOW_STYLE_OFF;
pLineStyle->shadowStyle.fShadowOpacity = 0.0f;
pLineStyle->shadowStyle.fShadowOffsetX = 0.0f;
pLineStyle->shadowStyle.fShadowOffsetY = 0.0f;
pLineStyle->shadowStyle.uShadowColorCieLabValue[0] = 0;
pLineStyle->shadowStyle.uShadowColorCieLabValue[1] = 0;
pLineStyle->shadowStyle.uShadowColorCieLabValue[2] = 0;
// This is 'blue'
pLineStyle->uPatternOnColorCieLabValue[0] = 21169;
pLineStyle->uPatternOnColorCieLabValue[1] = 53249;
pLineStyle->uPatternOnColorCieLabValue[2] = 5175;
pLineStyle->uPatternOffColorCieLabValue[0] = 0;
pLineStyle->uPatternOffColorCieLabValue[1] = 0;
pLineStyle->uPatternOffColorCieLabValue[2] = 0;
pLineStyle->fLineThickness = 1.0f;
pLineStyle->uLineDashingStyle = DICANN_LINE_DASH_STYLE_SOLID;
pLineStyle->uLinePattern = 0xFFFF;
pLineStyle->fPatternOnOpacity = 1.0f;
pLineStyle->fPatternOffOpacity = 0.0f;
pCompoundGraphic->pLineStyle = pLineStyle;
}
// RULER does not have a fill style
// Major Ticks Sequence
pDICOMMAJORTICK pMajorTicks = (pDICOMMAJORTICK)malloc(sizeof(DICOMMAJORTICK) * 4);
if (pMajorTicks)
{
ZeroMemory(pMajorTicks, sizeof(DICOMMAJORTICK) * 4);
L_INT nTickCount = 4;
L_FLOAT fTickIncrement = (L_FLOAT)(1.0 / (L_FLOAT)nTickCount);
for (int i = 0; i < nTickCount; i++)
{
pMajorTicks[i].uStructSize = sizeof(DICOMMAJORTICK);
pMajorTicks[i].fTickPosition = i * fTickIncrement;
wsprintf(pMajorTicks[i].szTickLabel, TEXT("Label %d"), i);
}
pCompoundGraphic->nMajorTickCount = 4;
pCompoundGraphic->pMajorTicks = pMajorTicks;
}
}
// Creates a RECTANGLE compound graphic (rotated, filled)
L_VOID CreateCompoundGraphicRectangle(L_TCHAR *pszLayerName, pDICOMCOMPOUNDGRAPHIC pCompoundGraphic)
{
pCompoundGraphic->pszLayerName = pszLayerName;
pCompoundGraphic->uUnits = DICANN_UNIT_PIXEL;
pCompoundGraphic->uType = DICANN_TYPE_RECTANGLE;
pDICOMANNPOINT pts = (pDICOMANNPOINT)malloc(2 * sizeof(DICOMANNPOINT));
if (pts)
{
pts[0].fX = 100.0f;
pts[0].fY = 100.0f;
pts[1].fX = 200.0f;
pts[2].fY = 200.0f;
pCompoundGraphic->pAnnPoints = pts;
pCompoundGraphic->nPointCount = 2;
}
pCompoundGraphic->uCompoundGraphicInstanceId = 200;
pCompoundGraphic->uGraphicGroupId = 0;
pCompoundGraphic->dRotationAngle = 45.0;
pCompoundGraphic->ptRotationPoint.fX = 150.0f;
pCompoundGraphic->ptRotationPoint.fY = 150.0f;
pCompoundGraphic->bFilled = TRUE;
pCompoundGraphic->uOptions = DICANN_OPTIONS_FILL_STYLE | DICANN_OPTIONS_COMPOUND_GRAPHIC_INSTANCE_ID;
// LineStyle
pDICOMLINESTYLE pLineStyle = (pDICOMLINESTYLE)malloc(sizeof(DICOMLINESTYLE));
if (pLineStyle)
{
ZeroMemory(pLineStyle, sizeof(DICOMLINESTYLE));
pLineStyle->uStructSize = sizeof(DICOMLINESTYLE);
pLineStyle->uLineOptions = DICANN_LINE_OPTIONS_NONE;
pLineStyle->shadowStyle.uStructSize = sizeof(DICOMSHADOWSTYLE);
pLineStyle->shadowStyle.uShadowStyle = DICANN_SHADOW_STYLE_OFF;
pLineStyle->shadowStyle.fShadowOpacity = 0.0f;
pLineStyle->shadowStyle.fShadowOffsetX = 0.0f;
pLineStyle->shadowStyle.fShadowOffsetY = 0.0f;
pLineStyle->shadowStyle.uShadowColorCieLabValue[0] = 0;
pLineStyle->shadowStyle.uShadowColorCieLabValue[1] = 1;
pLineStyle->shadowStyle.uShadowColorCieLabValue[2] = 2;
// red
pLineStyle->uPatternOnColorCieLabValue[0] = 24886;
pLineStyle->uPatternOnColorCieLabValue[1] = 53484;
pLineStyle->uPatternOnColorCieLabValue[2] = 50171;
pLineStyle->uPatternOffColorCieLabValue[0] = 0;
pLineStyle->uPatternOffColorCieLabValue[1] = 0;
pLineStyle->uPatternOffColorCieLabValue[2] = 0;
pLineStyle->fLineThickness = 2.0f;
pLineStyle->uLineDashingStyle = DICANN_LINE_DASH_STYLE_SOLID;
pLineStyle->uLinePattern = 0xFFFF;
pLineStyle->fPatternOnOpacity = 1.0f;
pLineStyle->fPatternOffOpacity = 0.0f;
pCompoundGraphic->pLineStyle = pLineStyle;
}
// FillStyle
pDICOMFILLSTYLE pFillStyle = (pDICOMFILLSTYLE)malloc(sizeof(DICOMFILLSTYLE));
if (pFillStyle)
{
ZeroMemory(pFillStyle, sizeof(DICOMFILLSTYLE));
pFillStyle->uStructSize = sizeof(DICOMFILLSTYLE);
pFillStyle->uFillOptions = DICANN_FILL_OPTIONS_NONE;
// blue
pFillStyle->uPatternOnColorCieLabValue[0] = 21169;
pFillStyle->uPatternOnColorCieLabValue[1] = 53249;
pFillStyle->uPatternOnColorCieLabValue[2] = 5175;
pFillStyle->uPatternOffColorCieLabValue[0] = 0;
pFillStyle->uPatternOffColorCieLabValue[0] = 1;
pFillStyle->uPatternOffColorCieLabValue[0] = 2;
pFillStyle->fPatternOnOpacity = 1.0f;
pFillStyle->fPatternOffOpacity = 0.0f;
pFillStyle->uFillMode = DICANN_FILL_MODE_SOLID;
pCompoundGraphic->pFillStyle = pFillStyle;
}
}
L_VOID FreeDicomCompoundGraphic(pDICOMCOMPOUNDGRAPHIC pDicomCompoundGraphic)
{
if (pDicomCompoundGraphic)
{
if (pDicomCompoundGraphic->pAnnPoints != NULL)
free(pDicomCompoundGraphic->pAnnPoints);
if (pDicomCompoundGraphic->pLineStyle)
free(pDicomCompoundGraphic->pLineStyle);
if (pDicomCompoundGraphic->pFillStyle)
free(pDicomCompoundGraphic->pFillStyle);
if (pDicomCompoundGraphic->pMajorTicks)
free(pDicomCompoundGraphic->pMajorTicks);
if (pDicomCompoundGraphic->pTextStyle)
free(pDicomCompoundGraphic->pTextStyle);
}
}
L_VOID DicomCompoundGraphicTest(L_TCHAR *pszLayerName, L_TCHAR * pszOutFile)
{
LDicomDS ds;
ds.InitDS(CLASS_GRAYSCALE_SOFTCOPY_PRESENTATION_STATE, DS_ADD_MANDATORY_MODULES_ONLY | DS_ADD_MANDATORY_ELEMENTS_ONLY);
ds.CreateGraphicAnnSQItem(0, pszLayerName);
pDICOMELEMENT firstGraphicAnnSQItem = ds.FindFirstGraphicAnnSQItem();
DICOMCOMPOUNDGRAPHIC ruler = { 0 };
ruler.uStructSize = sizeof(DICOMCOMPOUNDGRAPHIC);
CreateCompoundGraphicRuler(pszLayerName, &ruler);
ds.CreateCompoundGraphic(firstGraphicAnnSQItem, &ruler, FALSE);
DICOMCOMPOUNDGRAPHIC rotatedFilledRectangle = { 0 };
rotatedFilledRectangle.uStructSize = sizeof(DICOMCOMPOUNDGRAPHIC);
CreateCompoundGraphicRectangle(pszLayerName, &rotatedFilledRectangle);
ds.CreateCompoundGraphic(firstGraphicAnnSQItem, &rotatedFilledRectangle, false);
// Save the presentation state (with annotations)
ds.SaveDS(pszOutFile, 0);
FreeDicomCompoundGraphic(&ruler);
FreeDicomCompoundGraphic(&rotatedFilledRectangle);
L_TCHAR szMessage[200] = { 0 };
wsprintf((LPWSTR)szMessage, TEXT("Presentation State Saved: '%s'"), pszOutFile);
MessageBox(NULL, (LPCTSTR)szMessage, TEXT("DicomCompoundGraphicTest"), MB_OK);
// Find the second CompoundGraphicElement item -- this should be the rectangle
pDICOMELEMENT element = ds.GetCompoundGraphicElement(firstGraphicAnnSQItem, 0);
pDICOMELEMENT pElementCompoundGraphicType = ds.FindFirstElement(element, TAG_COMPOUND_GRAPHIC_TYPE, FALSE);
if (pElementCompoundGraphicType != NULL)
{
L_TCHAR * pszType = ds.GetStringValue(pElementCompoundGraphicType, 0, 1);
assert(lstrcmp(pszType, TEXT("RULER")) == 0);
}
// Now we have two compound graphic items: ruler, rectangle
// Count should be 2
L_UINT nCount = 0;
ds.GetCompoundGraphicCount(firstGraphicAnnSQItem, &nCount);
assert(nCount == 2);
// Get the number of points of the first item (ruler) -- this should be 2
ds.GetCompoundGraphicPointCount(firstGraphicAnnSQItem, 0, &nCount);
assert(nCount == 2);
// Get the number of major ticks in the ruler -- this should be 4
ds.GetCompoundGraphicMajorTickCount(firstGraphicAnnSQItem, 0, &nCount);
assert(nCount == 4);
// Remove the first compound graphic (the ruler)
ds.RemoveCompoundGraphic(firstGraphicAnnSQItem, 0);
// Read the first compound graphic -- this should now be the rectangle
DICOMCOMPOUNDGRAPHIC compoundGraphic = { 0 };
ds.GetCompoundGraphicInfo(firstGraphicAnnSQItem, 0, &compoundGraphic, sizeof(DICOMCOMPOUNDGRAPHIC));
assert(compoundGraphic.uType == DICANN_TYPE_RECTANGLE);
// Change the rectangle from filled, to non-filled
compoundGraphic.bFilled = FALSE;
ds.SetCompoundGraphicInfo(firstGraphicAnnSQItem, 0, &compoundGraphic);
// Verify that the rectangle is non-filled
ds.GetCompoundGraphicInfo(firstGraphicAnnSQItem, 0, &compoundGraphic, sizeof(DICOMCOMPOUNDGRAPHIC));
assert(compoundGraphic.bFilled == FALSE);
// Remove ALL compund graphics
ds.RemoveAllCompoundGraphics(firstGraphicAnnSQItem);
// Get the compound graphic count -- it should now be zero
ds.GetCompoundGraphicCount(firstGraphicAnnSQItem, &nCount);
assert(nCount == 0);
}