Okay, over a year has passed and I've finally gotten around to revisiting this plugin. Thanks to help from both Curtis and EER, I've almost got this finished. Maybe it's just because I've been doing a lot of programming (in various non-C# languages) this year, but replacing the global class with a global variable was a fairly thing to do.
For the most part it works, but occasionally it produces transparent, horizontal lines instead of a completely solid color. It seems to happen mostly with elliptical selections, although I have seen it with rectangular ones, too. I have not seen them when averaging the entire image. Strangely enough, if I force CodeLab to re-render it, sometimes the transparent lines go away.
I should point out that it happens whether or not a put the IsVisible check as part of the rendering in the final for loop.
Any thoughts or advice? Thanks!
EDIT: I removed both instances of the isVisible line and adjusted the rest of the code accordingly. It now seems to work for most selections, but with some selections, or if nothing is selected, it seems to either show a dark gray or just the top left pixel color. I've updated the code below with the changes.
CodeLab code:
private bool set = false;
private ColorBgra AverageColor;
// Based on Rik Hemsley's code posted on the org.kde.kde-core-devel list.
ColorBgra average(ColorBgra fg, ColorBgra bg)
{
const double d0 = (double)256;
const double d1 = 0.2979;
const double d2 = 0.5866;
const double d3 = 0.1145;
const double d4 = -0.1687;
const double d5 = 0.3312;
const double d6 = 0.5000;
const double d7 = 0.4183;
const double d8 = 0.0816;
const double d9 = 1.4022;
const double d10 = 0.3456;
const double d11 = 0.7145;
const double d12 = 1.7710;
const double mix = 0.5;
double y, cb, cr, y0, cb0, cr0, y1, cb1, cr1;
double r0, g0, b0, r1, g1, b1;
ColorBgra ret = fg;
r0 = (double)fg.R / d0;
g0 = (double)fg.G / d0;
b0 = (double)fg.B / d0;
r1 = (double)bg.R / d0;
g1 = (double)bg.G / d0;
b1 = (double)bg.B / d0;
y0 = d1 * r0 + d2 * g0 + d3 * b0;
cb0 = d4 * r0 - d5 * g0 + d6 * b0;
cr0 = d6 * r0 - d7 * g0 - d8 * b0;
y1 = d1 * r1 + d2 * g1 + d3 * b1;
cb1 = d4 * r1 - d5 * g1 + d6 * b1;
cr1 = d6 * r1 - d7 * g1 - d8 * b1;
y = y0 + mix * (y1 - y0 );
cb = cb0 + mix * (cb1 - cb0);
cr = cr0 + mix * (cr1 - cr0);
ret.R = (byte)(d0 * (y + d9 * cr));
ret.G = (byte)(d0 * (y - d10 * cb - d11 * cr));
ret.B = (byte)(d0 * (y + d12 * cb));
ret.A = (byte)255; // always set to no transparency to make the result visible
return ret;
}
void Render(Surface dst, Surface src, Rectangle rect)
{
PdnRegion selectionRegion = EnvironmentParameters.GetSelection(src.Bounds);
ColorBgra CurrentPixel;
if (AverageColor == null)
{
AverageColor = src[rect.Top,rect.Left];
}
if (!set)
{
set = true;
for (int y = rect.Top; y < rect.Bottom; y++)
{
for (int x = rect.Left; x < rect.Right; x++)
{
CurrentPixel = src[x,y];
AverageColor = average(AverageColor, CurrentPixel);
}
}
}
// fill out selection with average color
for (int y = rect.Top; y < rect.Bottom; y++)
{
for (int x = rect.Left; x < rect.Right; x++)
{
dst[x,y] = AverageColor;
}
}
}