I'm currently using fo-dicon to build a simple dicom viewer in C#. I am currently increasing or decreasing the brightness and contrast by adjusting window width & center values.
How do I invert the grayscale using the InvertLut class?
public WriteableBitmap DisplayedImage {get;set;}
//...
private void ExecuteLoadImageCommand()
{
_dicomFile = DicomFile.Open(GetImageFileName());
_dicomImage = new DicomImage(_dicomFile.Dataset);
WindowLevel = _dicomImage.WindowCenter;
WindowWidth = _dicomImage.WindowWidth;
var grayScaleOptions = GrayscaleRenderOptions.FromBitRange(_dicomFile.Dataset);
Depth = grayScaleOptions.BitDepth.BitsAllocated;
DisplayedImage = _dicomImage.RenderImage().As<WriteableBitmap>();
}
With the solution provided in below fo-dicom issue, i was able to invert the image. I did not use InvertLUT class.
https://github.com/fo-dicom/fo-dicom/issues/784
I had to convert from WritableBitmap to Bitmap, then again to WritableBitmap.
Solution:
public static class BitmapHelper
{
[DllImport("kernel32.dll", EntryPoint = "RtlMoveMemory")]
public static extern void CopyMemory(IntPtr dest, IntPtr source, int Length);
public static void ConvertToWritableBitmap(Bitmap bitmap, ref WriteableBitmap writeableBitmap)
{
BitmapData data = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
try
{
writeableBitmap.Lock();
CopyMemory(writeableBitmap.BackBuffer, data.Scan0,
(writeableBitmap.BackBufferStride * bitmap.Height));
writeableBitmap.AddDirtyRect(new Int32Rect(0, 0, bitmap.Width, bitmap.Height));
writeableBitmap.Unlock();
}
finally
{
bitmap.UnlockBits(data);
bitmap.Dispose();
}
}
/// <summary>
///
/// </summary>
/// <param name="image"></param>
/// <returns></returns>
public static Bitmap InvertBitmapPixels(WriteableBitmap writeableBitmap)
{
var image = BitmapFromWriteableBitmap(writeableBitmap);
// create the negative color matrix
ColorMatrix color_matrix = new ColorMatrix(
new float[][] {
new float[] {-1, 0, 0, 0, 0},
new float[] {0, -1, 0, 0, 0},
new float[] {0, 0, -1, 0, 0},
new float[] {0, 0, 0, 1, 0},
new float[] {1, 1, 1, 0, 1}
}
);
// create some image attributes
ImageAttributes attributes = new ImageAttributes();
attributes.SetColorMatrix(color_matrix);
var bmp = new Bitmap(image);
{
using (var g = Graphics.FromImage(bmp))
{
g.DrawImage(
image,
new Rectangle(0, 0, image.Width, image.Height),
0, 0, bmp.Width, bmp.Height,
GraphicsUnit.Pixel,
attributes
);
}
return bmp;
}
}
public static Bitmap BitmapFromWriteableBitmap(WriteableBitmap writeBmp)
{
System.Drawing.Bitmap bmp;
using (MemoryStream outStream = new MemoryStream())
{
BitmapEncoder enc = new BmpBitmapEncoder();
enc.Frames.Add(BitmapFrame.Create((BitmapSource)writeBmp));
enc.Save(outStream);
bmp = new System.Drawing.Bitmap(outStream);
}
return bmp;
}
}
To invert:
var image = BitmapHelper.InvertBitmapPixels(_writableBitmapImage);
BitmapHelper.ConvertToWritableBitmap(image, ref _writableBitmapImage);