protected ImageComponent <int> Apply(ImageComponent <ushort> image) { Debug.Assert(image.red != null); Debug.Assert(image.blue != null); Debug.Assert(image.green != null); Debug.Assert(image.dim.Area >= 4); //calculate the max value for clip maxValue = (uint)(1 << image.ColorDepth) - 1; HistoRaw histo; //TODO cut the image in patch to reduce memory var buffer = new ImageComponent <int>(image.dim, image.ColorDepth); //apply the single pixel processing SinglePixelProcessing(image, buffer, CreateCurve()); ColorManipulation.SplitTone(buffer, new Pixel(SplitShadow), new Pixel(SplitHighlight), SplitBalance, maxValue); if (Rotation == 1 || Rotation == 3) { buffer.dim.Flip(); buffer.UncroppedDim.Flip(); } //clip Luminance.Clip(buffer); //apply histogram equalisation if any if (histogramEqual) { //calculate the histogram histo = HistogramHelper.CalculateLumaHistogram(buffer); HistogramHelper.HistogramEqualisation(buffer, histo); } //apply denoising if (denoise != 0) { buffer = Denoising.Apply(buffer, (int)denoise); } //apply sharpening (always last step) if (sharpness != 0) { buffer = Sharpening.Apply(buffer, (int)sharpness); } //return the final histogram return(buffer); }
public unsafe HistoRaw ApplyTo16Bits(ImageComponent <ushort> image, SoftwareBitmap bitmap, bool histogram) { Debug.Assert(bitmap.BitmapPixelFormat == BitmapPixelFormat.Rgba16); var buffer = Apply(image); //Clip the image //Luminance.Clip(buffer, 16); HistoRaw histo = null; //calculate the new histogram (create a 8 bits histogram) if (histogram) { histo = HistogramHelper.CalculateHistogram(buffer); } //copy the buffer to the image with clipping //calculte the shift between colordepth input and output int shift = image.ColorDepth - 16; using (BitmapBuffer buff = bitmap.LockBuffer(BitmapBufferAccessMode.Write)) using (var reference = buff.CreateReference()) { ((IMemoryBufferByteAccess)reference).GetBuffer(out var temp, out uint capacity); Parallel.For(0, buffer.dim.height, y => { long realY = y * buffer.dim.width; for (int x = 0; x < buffer.dim.width; x++) { long realPix = realY + x; long bufferPix = realPix * 8; temp[bufferPix] = (byte)(buffer.red[realPix] >> 8); temp[bufferPix + 1] = (byte)(buffer.red[realPix]); temp[bufferPix + 2] = (byte)(buffer.green[realPix] >> 8); temp[bufferPix + 3] = (byte)(buffer.green[realPix]); temp[bufferPix + 4] = (byte)(buffer.blue[realPix] >> 8); temp[bufferPix + 5] = (byte)(buffer.blue[realPix]); temp[bufferPix + 6] = 255; //set transparency to 255 else image will be blank temp[bufferPix + 7] = 255; //set transparency to 255 else image will be blank } }); } return(histo); }
public unsafe HistoRaw ApplyTo8Bits(ImageComponent <ushort> image, SoftwareBitmap bitmap, bool histogram) { Debug.Assert(image.red != null); Debug.Assert(image.blue != null); Debug.Assert(image.green != null); Debug.Assert(image.dim.Area >= 4); Debug.Assert(bitmap != null); Debug.Assert(image.dim.Area == bitmap.PixelHeight * bitmap.PixelWidth); var buffer = Apply(image); //Clip the image Luminance.Clip(buffer, 8); //calculate the new histogram (create a 8 bits histogram) HistoRaw histo = null; if (histogram) { histo = HistogramHelper.CalculateHistogram(buffer); } //copy the buffer to the image with clipping using (BitmapBuffer buff = bitmap.LockBuffer(BitmapBufferAccessMode.Write)) using (var reference = buff.CreateReference()) { ((IMemoryBufferByteAccess)reference).GetBuffer(out var temp, out uint capacity); Parallel.For(0, buffer.dim.height, y => { long realY = y * buffer.dim.width; for (int x = 0; x < buffer.dim.width; x++) { long realPix = realY + x; long bufferPix = realPix * 4; temp[bufferPix] = (byte)(buffer.blue[realPix]); temp[bufferPix + 1] = (byte)(buffer.green[realPix]); temp[bufferPix + 2] = (byte)(buffer.red[realPix]); temp[bufferPix + 3] = 255; //set transparency to 255 else image will be blank } }); } return(histo); }