Getting the color filtering working
This commit is contained in:
parent
86ee3b4b9c
commit
93735995b7
2 changed files with 213 additions and 18 deletions
|
|
@ -55,7 +55,19 @@ namespace MatterHackers.MatterControl.DesignTools
|
|||
|
||||
public event EventHandler EditComplete;
|
||||
|
||||
public void RebuildAlphaImage(ImageBuffer sourceImage, ImageBuffer alphaImage)
|
||||
public void RebuildAlphaImage(ImageBuffer sourceImage, ImageBuffer alphaImage, ImageToPathObject3D_2.AnalysisTypes analysisType)
|
||||
{
|
||||
if (analysisType == ImageToPathObject3D_2.AnalysisTypes.Colors)
|
||||
{
|
||||
RebuildColorToAlphaImage(sourceImage, alphaImage);
|
||||
}
|
||||
else
|
||||
{
|
||||
RebuildIntensityToAlphaImage(sourceImage, alphaImage);
|
||||
}
|
||||
}
|
||||
|
||||
private void RebuildIntensityToAlphaImage(ImageBuffer sourceImage, ImageBuffer alphaImage)
|
||||
{
|
||||
if (sourceImage == null)
|
||||
{
|
||||
|
|
@ -106,12 +118,12 @@ namespace MatterHackers.MatterControl.DesignTools
|
|||
for (int x = 0; x < sourceImage.Width; x++)
|
||||
{
|
||||
int imageBufferOffsetWithX = imageOffset + x * 4;
|
||||
var r = sourceBuffer[imageBufferOffsetWithX + 0];
|
||||
var b = sourceBuffer[imageBufferOffsetWithX + 0];
|
||||
var g = sourceBuffer[imageBufferOffsetWithX + 1];
|
||||
var b = sourceBuffer[imageBufferOffsetWithX + 2];
|
||||
destBuffer[imageBufferOffsetWithX + 0] = r;
|
||||
var r = sourceBuffer[imageBufferOffsetWithX + 2];
|
||||
destBuffer[imageBufferOffsetWithX + 0] = b;
|
||||
destBuffer[imageBufferOffsetWithX + 1] = g;
|
||||
destBuffer[imageBufferOffsetWithX + 2] = b;
|
||||
destBuffer[imageBufferOffsetWithX + 2] = r;
|
||||
destBuffer[imageBufferOffsetWithX + 3] = GetAlphaFromIntensity(r, g, b);
|
||||
}
|
||||
});
|
||||
|
|
@ -119,17 +131,154 @@ namespace MatterHackers.MatterControl.DesignTools
|
|||
alphaImage.MarkImageChanged();
|
||||
}
|
||||
|
||||
private static (float hue, float saturation) GetHue(byte bR, byte bG, byte bB)
|
||||
{
|
||||
var r = bR / 255.0f;
|
||||
var g = bG / 255.0f;
|
||||
var b = bB / 255.0f;
|
||||
var maxRGB = Math.Max(r, Math.Max(g, b));
|
||||
var minRGB = Math.Min(r, Math.Min(g, b));
|
||||
var deltaMaxToMin = maxRGB - minRGB;
|
||||
float r2, g2, b2;
|
||||
|
||||
var lightness0To1 = (minRGB + maxRGB) / 2.0;
|
||||
if (lightness0To1 <= 0.0)
|
||||
{
|
||||
return (0, 0);
|
||||
}
|
||||
|
||||
var saturation0To1 = deltaMaxToMin;
|
||||
if (saturation0To1 > 0.0)
|
||||
{
|
||||
saturation0To1 /= (lightness0To1 <= 0.5f) ? (maxRGB + minRGB) : (2.0f - maxRGB - minRGB);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (0, 0);
|
||||
}
|
||||
|
||||
r2 = (maxRGB - r) / deltaMaxToMin;
|
||||
g2 = (maxRGB - g) / deltaMaxToMin;
|
||||
b2 = (maxRGB - b) / deltaMaxToMin;
|
||||
var hue0To1 = 0.0f;
|
||||
if (r == maxRGB)
|
||||
{
|
||||
if (g == minRGB)
|
||||
{
|
||||
hue0To1 = 5.0f + b2;
|
||||
}
|
||||
else
|
||||
{
|
||||
hue0To1 = 1.0f - g2;
|
||||
}
|
||||
}
|
||||
else if (g == maxRGB)
|
||||
{
|
||||
if (b == minRGB)
|
||||
{
|
||||
hue0To1 = 1.0f + r2;
|
||||
}
|
||||
else
|
||||
{
|
||||
hue0To1 = 3.0f - b2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (r == minRGB)
|
||||
{
|
||||
hue0To1 = 3.0f + g2;
|
||||
}
|
||||
else
|
||||
{
|
||||
hue0To1 = 5.0f - r2;
|
||||
}
|
||||
}
|
||||
|
||||
hue0To1 /= 6.0f;
|
||||
|
||||
return (hue0To1, saturation0To1);
|
||||
}
|
||||
|
||||
private static byte GetAlphaFromHue(byte r, byte g, byte b, double start, double end)
|
||||
{
|
||||
var hs = GetHue(r, g, b);
|
||||
if (hs.saturation > .6 && hs.hue <= end && hs.hue > start)
|
||||
{
|
||||
return 255;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private void RebuildColorToAlphaImage(ImageBuffer sourceImage, ImageBuffer alphaImage)
|
||||
{
|
||||
if (sourceImage == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// build the alpha image
|
||||
if (alphaImage == null)
|
||||
{
|
||||
alphaImage = new ImageBuffer(sourceImage.Width, sourceImage.Height);
|
||||
}
|
||||
else if (alphaImage.Width != sourceImage.Width
|
||||
|| alphaImage.Height != sourceImage.Height)
|
||||
{
|
||||
alphaImage.Allocate(sourceImage.Width, sourceImage.Height, sourceImage.BitDepth, sourceImage.GetRecieveBlender());
|
||||
}
|
||||
|
||||
byte[] sourceBuffer = sourceImage.GetBuffer();
|
||||
byte[] destBuffer = alphaImage.GetBuffer();
|
||||
//Parallel.For(0, sourceImage.Height, (y) =>
|
||||
for(int y = 0; y < sourceImage.Height; y++)
|
||||
{
|
||||
int imageOffset = sourceImage.GetBufferOffsetY(y);
|
||||
|
||||
for (int x = 0; x < sourceImage.Width; x++)
|
||||
{
|
||||
int imageBufferOffsetWithX = imageOffset + x * 4;
|
||||
var b = sourceBuffer[imageBufferOffsetWithX + 0];
|
||||
var g = sourceBuffer[imageBufferOffsetWithX + 1];
|
||||
var r = sourceBuffer[imageBufferOffsetWithX + 2];
|
||||
destBuffer[imageBufferOffsetWithX + 0] = b;
|
||||
destBuffer[imageBufferOffsetWithX + 1] = g;
|
||||
destBuffer[imageBufferOffsetWithX + 2] = r;
|
||||
destBuffer[imageBufferOffsetWithX + 3] = GetAlphaFromHue(r, g, b, RangeStart, RangeEnd);
|
||||
}
|
||||
}
|
||||
//});
|
||||
|
||||
alphaImage.MarkImageChanged();
|
||||
}
|
||||
|
||||
class QuickHue : IThresholdFunction
|
||||
{
|
||||
public Color ZeroColor => throw new NotImplementedException();
|
||||
|
||||
public double Threshold(Color color)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public double Transform(Color color)
|
||||
{
|
||||
return GetHue(color.red, color.green, color.blue).hue;
|
||||
}
|
||||
}
|
||||
|
||||
public void BuildHistogramFromImage(ImageBuffer image, ImageToPathObject3D_2.AnalysisTypes analysisType)
|
||||
{
|
||||
// build the histogram cache
|
||||
var height = (int)(100 * GuiWidget.DeviceScale);
|
||||
_histogramRawCache = new ImageBuffer(256, height);
|
||||
var counts = new int[_histogramRawCache.Width];
|
||||
IThresholdFunction function = new MapOnMaxIntensity(RangeStart, RangeEnd);
|
||||
IThresholdFunction function = new MapOnMaxIntensity(0, 1);
|
||||
var bottom = 0;
|
||||
if (analysisType == ImageToPathObject3D_2.AnalysisTypes.Colors)
|
||||
{
|
||||
function = new HueThresholdFunction(RangeStart, RangeEnd);
|
||||
function = new QuickHue();
|
||||
bottom = (int)(10 * GuiWidget.DeviceScale);
|
||||
}
|
||||
|
||||
|
|
@ -158,9 +307,10 @@ namespace MatterHackers.MatterControl.DesignTools
|
|||
graphShape.MoveTo(0, bottom);
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
graphShape.LineTo(i, bottom + Easing.Exponential.Out(counts[i] / max) * graphHeight);
|
||||
graphShape.LineTo(i, bottom + counts[i] * graphHeight / max );
|
||||
}
|
||||
graphShape.LineTo(image.Width, bottom);
|
||||
graphShape.LineTo(256, bottom);
|
||||
graphShape.LineTo(0, bottom);
|
||||
graphics.Render(graphShape, 0, 0, theme.TextColor);
|
||||
|
||||
for(int i=0; i<256; i++)
|
||||
|
|
@ -296,6 +446,51 @@ namespace MatterHackers.MatterControl.DesignTools
|
|||
}
|
||||
};
|
||||
|
||||
// grabing the center
|
||||
bool centerDown = false;
|
||||
var centerX = 0.0;
|
||||
histogramBackground.MouseDown += (s, e) =>
|
||||
{
|
||||
if (e.Button == MouseButtons.Left)
|
||||
{
|
||||
centerDown = true;
|
||||
centerX = e.Position.X;
|
||||
}
|
||||
};
|
||||
|
||||
histogramBackground.MouseMove += (s, e) =>
|
||||
{
|
||||
if (centerDown)
|
||||
{
|
||||
var offset = e.Position.X - centerX;
|
||||
var newEnd = RangeEnd + offset / _histogramRawCache.Width;
|
||||
newEnd = agg_basics.Clamp(newEnd, RangeStart, 1);
|
||||
|
||||
var newStart = RangeStart + offset / _histogramRawCache.Width;
|
||||
newStart = agg_basics.Clamp(newStart, 0, newEnd);
|
||||
|
||||
if (RangeStart != newStart
|
||||
&& RangeEnd != newEnd)
|
||||
{
|
||||
RangeStart = newStart;
|
||||
RangeEnd = newEnd;
|
||||
leftHandle.Position = new Vector2(RangeStart * _histogramRawCache.Width, 0);
|
||||
rightHandle.Position = new Vector2(RangeEnd * _histogramRawCache.Width + handleWidth, 0);
|
||||
RangeChanged?.Invoke(this, null);
|
||||
histogramBackground.Invalidate();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
histogramBackground.MouseUp += (s, e) =>
|
||||
{
|
||||
if (centerDown)
|
||||
{
|
||||
centerDown = false;
|
||||
EditComplete?.Invoke(this, null);
|
||||
}
|
||||
};
|
||||
|
||||
return histogramWidget;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ namespace MatterHackers.MatterControl.DesignTools
|
|||
Histogram.BuildHistogramFromImage(SourceImage, AnalysisType);
|
||||
Histogram.RangeChanged += (s, e) =>
|
||||
{
|
||||
Histogram.RebuildAlphaImage(SourceImage, _image);
|
||||
Histogram.RebuildAlphaImage(SourceImage, _image, AnalysisType);
|
||||
};
|
||||
|
||||
Histogram.EditComplete += (s, e) =>
|
||||
|
|
@ -94,7 +94,7 @@ namespace MatterHackers.MatterControl.DesignTools
|
|||
switch (AnalysisType)
|
||||
{
|
||||
case AnalysisTypes.Intensity:
|
||||
Histogram.RebuildAlphaImage(SourceImage, _image);
|
||||
Histogram.RebuildAlphaImage(SourceImage, _image, AnalysisType);
|
||||
break;
|
||||
|
||||
case AnalysisTypes.Transparency:
|
||||
|
|
@ -132,13 +132,9 @@ namespace MatterHackers.MatterControl.DesignTools
|
|||
switch (AnalysisType)
|
||||
{
|
||||
case AnalysisTypes.Intensity:
|
||||
Histogram.BuildHistogramFromImage(sourceImage, AnalysisType);
|
||||
Histogram.RebuildAlphaImage(sourceImage, Image);
|
||||
break;
|
||||
|
||||
case AnalysisTypes.Colors:
|
||||
Histogram.BuildHistogramFromImage(sourceImage, AnalysisType);
|
||||
Histogram.RebuildAlphaImage(sourceImage, Image);
|
||||
Histogram.RebuildAlphaImage(sourceImage, Image, AnalysisType);
|
||||
break;
|
||||
|
||||
case AnalysisTypes.Transparency:
|
||||
|
|
@ -246,8 +242,11 @@ namespace MatterHackers.MatterControl.DesignTools
|
|||
&& invalidateArgs.Source != this
|
||||
&& !RebuildLocked)
|
||||
{
|
||||
Histogram.BuildHistogramFromImage(SourceImage, AnalysisType);
|
||||
Histogram.RebuildAlphaImage(SourceImage, _image);
|
||||
if (AnalysisType != AnalysisTypes.Transparency)
|
||||
{
|
||||
Histogram.BuildHistogramFromImage(SourceImage, AnalysisType);
|
||||
Histogram.RebuildAlphaImage(SourceImage, _image, AnalysisType);
|
||||
}
|
||||
await Rebuild();
|
||||
}
|
||||
else if ((invalidateArgs.InvalidateType.HasFlag(InvalidateType.Properties) && invalidateArgs.Source == this))
|
||||
|
|
@ -288,6 +287,7 @@ namespace MatterHackers.MatterControl.DesignTools
|
|||
new AlphaFunction());
|
||||
break;
|
||||
|
||||
case AnalysisTypes.Colors:
|
||||
case AnalysisTypes.Intensity:
|
||||
this.GenerateMarchingSquaresAndLines(
|
||||
(progress0to1, status) =>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue