How DicomObjects handles Width and Level values

The Width and Level properties of an image are unusual, in that they are both stored as a part of the image, and are also transient DicomImage properties, regularly adjusted by users. This page explains the relationship between the persistent and transient values.


The Persistent Values

These are held in attributes 0028,1050 & 0028,1051 in the image. It is important to realise that they are optional attributes, and not every image contains these attributes. DicomObjects never changes the value of any attribute of a DicomImage or DicomDataSet unless this is specifically requested by the programmer. The values of the Width and Level attributes are no exception.

The Transient Values

These are simply properties of a DicomImage and when changed cause the image (if in a DicomViewer's collection) to be redisplayed with a revised mapping between pixel data and screen values.

How they relate to each other

The only relationship between the persistent and transient values is that the persistent values (if present) are used to initialise the transient values when the DicomImage is first created, or if the SetDefaultWindows method is used. At this time, the following procedure is used:

  • If the 0028,1050 & 0028,1051 attributes exist, then these are used to set the Width & Level properties.
  • If they are not present, but a Modality_LUT is present, then they are set so as to cover the output range of that LUT
  • Otherwise, they are set to cover the range of pixel values in the image

Saving Width & Level Values

In general, DICOM image objects should not be altered once created and the behaviour of many PACS is unpredictable if modified images are sent to them, so changing the persistent data is discouraged, but of course this is sometimes necessary (and reasonable if you are the initial creator of an image!), in which case the values can be copied back into the image as follows:


Image.Attributes.Add(0x0028, 0x1050, Image.Level);
Image.Attributes.Add(0x0028, 0x1051, Image.Width);


Image.DataSet.Add(0x0028, 0x1050, Image.Level);
Image.DataSet.Add(0x0028, 0x1051, Image.Width);