private static unsafe void CreateImagePixelModuleRasterRgb(IDicomAttributeProvider target, IPresentationImage sourceImage) { target[DicomTags.SamplesPerPixel].SetInt32(0, 3); target[DicomTags.PhotometricInterpretation].SetStringValue(PhotometricInterpretation.Rgb.Code); target[DicomTags.Rows].SetInt32(0, sourceImage.ClientRectangle.Height); target[DicomTags.Columns].SetInt32(0, sourceImage.ClientRectangle.Width); target[DicomTags.BitsAllocated].SetInt32(0, 8); target[DicomTags.BitsStored].SetInt32(0, 8); target[DicomTags.HighBit].SetInt32(0, 7); target[DicomTags.PixelRepresentation].SetInt32(0, 0); target[DicomTags.PlanarConfiguration].SetInt32(0, 0); target[DicomTags.PixelAspectRatio].SetStringValue(@"1\1"); using (var helper = new RenderImageHelper(sourceImage)) { // because we effectively "flattened" the image here, any header information regarding orientation, position and pixel spacing is now invalid // (cause they just got baked into the pixel data) target[DicomTags.ImageOrientationPatient].SetStringValue2(helper.GetImageOrientationPatient()); target[DicomTags.ImagePositionPatient].SetStringValue2(helper.GetImagePositionPatient()); target[DicomTags.PixelSpacing].SetStringValue2(helper.GetPixelSpacing()); var pixelDataAttribute = (DicomAttributeBinary)target[DicomTags.PixelData]; using (var stream = pixelDataAttribute.AsStream()) using (var bitmap = helper.Image.RenderImage(sourceImage.ClientRectangle)) { stream.Seek(0, SeekOrigin.Begin); var pixelCount = bitmap.Width * bitmap.Height; var rgbLength = pixelCount * 3; var pPixelData = Marshal.AllocHGlobal(pixelCount * 4); try { bitmap.CopyArgbDataTo(pPixelData); var pValue = (int *)pPixelData; for (var n = 0; n < pixelCount; ++n) { var value = *pValue++; // endianess concerns (i.e. ARGB vs BGRA) eliminated by reading as int stream.WriteByte((byte)(value >> 16)); // R stream.WriteByte((byte)(value >> 8)); // G stream.WriteByte((byte)(value)); // B } } finally { Marshal.FreeHGlobal(pPixelData); } if (rgbLength % 2 != 0) { ++rgbLength; stream.WriteByte(0); } stream.SetLength(rgbLength); } } }
private static unsafe void CreateImagePixelModuleRasterRgb(IDicomAttributeProvider target, IPresentationImage sourceImage) { target[DicomTags.SamplesPerPixel].SetInt32(0, 3); target[DicomTags.PhotometricInterpretation].SetStringValue(PhotometricInterpretation.Rgb.Code); target[DicomTags.Rows].SetInt32(0, sourceImage.ClientRectangle.Height); target[DicomTags.Columns].SetInt32(0, sourceImage.ClientRectangle.Width); target[DicomTags.BitsAllocated].SetInt32(0, 8); target[DicomTags.BitsStored].SetInt32(0, 8); target[DicomTags.HighBit].SetInt32(0, 7); target[DicomTags.PixelRepresentation].SetInt32(0, 0); target[DicomTags.PlanarConfiguration].SetInt32(0, 0); target[DicomTags.PixelAspectRatio].SetStringValue(@"1\1"); using (var helper = new RenderImageHelper(sourceImage)) { // because we effectively "flattened" the image here, any header information regarding orientation, position and pixel spacing is now invalid // (cause they just got baked into the pixel data) target[DicomTags.ImageOrientationPatient].SetStringValue2(helper.GetImageOrientationPatient()); target[DicomTags.ImagePositionPatient].SetStringValue2(helper.GetImagePositionPatient()); target[DicomTags.PixelSpacing].SetStringValue2(helper.GetPixelSpacing()); var pixelDataAttribute = (DicomAttributeBinary) target[DicomTags.PixelData]; using (var stream = pixelDataAttribute.AsStream()) using (var bitmap = helper.Image.RenderImage(sourceImage.ClientRectangle)) { stream.Seek(0, SeekOrigin.Begin); var pixelCount = bitmap.Width*bitmap.Height; var rgbLength = pixelCount*3; var pPixelData = Marshal.AllocHGlobal(pixelCount*4); try { bitmap.CopyArgbDataTo(pPixelData); var pValue = (int*) pPixelData; for (var n = 0; n < pixelCount; ++n) { var value = *pValue++; // endianess concerns (i.e. ARGB vs BGRA) eliminated by reading as int stream.WriteByte((byte) (value >> 16)); // R stream.WriteByte((byte) (value >> 8)); // G stream.WriteByte((byte) (value)); // B } } finally { Marshal.FreeHGlobal(pPixelData); } if (rgbLength%2 != 0) { ++rgbLength; stream.WriteByte(0); } stream.SetLength(rgbLength); } } }