#include "ltdic.h"
L_LTDIC_API L_UINT16 L_DicomGetCompoundGraphicCount(hDS,pGraphicAnnSQItem, pCount)
Retrieves the number of compound graphic annotation objects in a certain "Graphic Annotation Sequence" (0070,0001) item.
A DICOM handle.
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. |
This function returns the number of compound graphic annotation objects in the specified "Graphic Annotation Sequence" (0070,0001) item in the "Graphic Annotation Module".
Required DLLs and Libraries
Win32, x64, Linux.
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 ApiCreateCompoundGraphicRuler(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 ApiCreateCompoundGraphicRectangle(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 ApiFreeDicomCompoundGraphic(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 ApiDicomCompoundGraphicTest(L_TCHAR *pszLayerName, L_TCHAR * pszOutFile)
{
HDICOMDS hDS = L_DicomCreateDS(NULL);
L_DicomInitDS(hDS, CLASS_GRAYSCALE_SOFTCOPY_PRESENTATION_STATE, DS_ADD_MANDATORY_MODULES_ONLY | DS_ADD_MANDATORY_ELEMENTS_ONLY);
L_DicomCreateGraphicAnnSQItem(hDS, 0, pszLayerName);
pDICOMELEMENT firstGraphicAnnSQItem = L_DicomFindFirstGraphicAnnSQItem(hDS);
DICOMCOMPOUNDGRAPHIC ruler = { 0 };
ruler.uStructSize = sizeof(DICOMCOMPOUNDGRAPHIC);
ApiCreateCompoundGraphicRuler(pszLayerName, &ruler);
L_DicomCreateCompoundGraphic(hDS, firstGraphicAnnSQItem, &ruler, FALSE);
DICOMCOMPOUNDGRAPHIC rotatedFilledRectangle = { 0 };
rotatedFilledRectangle.uStructSize = sizeof(DICOMCOMPOUNDGRAPHIC);
ApiCreateCompoundGraphicRectangle(pszLayerName, &rotatedFilledRectangle);
L_DicomCreateCompoundGraphic(hDS, firstGraphicAnnSQItem, &rotatedFilledRectangle, FALSE);
// Save the presentation state (with annotations)
L_DicomSaveDS(hDS, pszOutFile, 0);
ApiFreeDicomCompoundGraphic(&ruler);
ApiFreeDicomCompoundGraphic(&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 = L_DicomGetCompoundGraphicElement(hDS, firstGraphicAnnSQItem, 0);
pDICOMELEMENT pElementCompoundGraphicType = L_DicomFindFirstElement(hDS, element, TAG_COMPOUND_GRAPHIC_TYPE, FALSE);
if (pElementCompoundGraphicType != NULL)
{
L_TCHAR * pszType = L_DicomGetStringValue(hDS, pElementCompoundGraphicType, 0, 1);
UNREFERENCED_PARAMETER(pszType);
assert(lstrcmp(pszType, TEXT("RULER")) == 0);
}
// Now we have two compound graphic items: ruler, rectangle
// Count should be 2
L_UINT nCount = 0;
L_DicomGetCompoundGraphicCount(hDS, firstGraphicAnnSQItem, &nCount);
assert(nCount == 2);
// Get the number of points of the first item (ruler) -- this should be 2
L_DicomGetCompoundGraphicPointCount(hDS, firstGraphicAnnSQItem, 0, &nCount);
assert(nCount == 2);
// Get the number of major ticks in the ruler -- this should be 4
L_DicomGetCompoundGraphicMajorTickCount(hDS, firstGraphicAnnSQItem, 0, &nCount);
assert(nCount == 4);
// Remove the first compound graphic (the ruler)
L_DicomRemoveCompoundGraphic(hDS, firstGraphicAnnSQItem, 0);
// Read the first compound graphic -- this should now be the rectangle
DICOMCOMPOUNDGRAPHIC compoundGraphic = { 0 };
L_DicomGetCompoundGraphicInfo(hDS, firstGraphicAnnSQItem, 0, &compoundGraphic, sizeof(DICOMCOMPOUNDGRAPHIC));
assert(compoundGraphic.uType == DICANN_TYPE_RECTANGLE);
// Change the rectangle from filled, to non-filled
compoundGraphic.bFilled = FALSE;
L_DicomSetCompoundGraphicInfo(hDS, firstGraphicAnnSQItem, 0, &compoundGraphic);
// Verify that the rectangle is non-filled
L_DicomGetCompoundGraphicInfo(hDS, firstGraphicAnnSQItem, 0, &compoundGraphic, sizeof(DICOMCOMPOUNDGRAPHIC));
assert(compoundGraphic.bFilled == FALSE);
// Remove ALL compund graphics
L_DicomRemoveAllCompoundGraphics(hDS, firstGraphicAnnSQItem);
// Get the compound graphic count -- it should now be zero
L_DicomGetCompoundGraphicCount(hDS, firstGraphicAnnSQItem, &nCount);
assert(nCount == 0);
}