static void msdfErrorCorrection(FloatRGBBmp output, Vector2 threshold) { List <Pair <int, int> > clashes = new List <Msdfgen.Pair <int, int> >(); int w = output.Width, h = output.Height; for (int y = 0; y < h; ++y) { for (int x = 0; x < w; ++x) { if ((x > 0 && pixelClash(output.GetPixel(x, y), output.GetPixel(x - 1, y), threshold.x)) || (x < w - 1 && pixelClash(output.GetPixel(x, y), output.GetPixel(x + 1, y), threshold.x)) || (y > 0 && pixelClash(output.GetPixel(x, y), output.GetPixel(x, y - 1), threshold.y)) || (y < h - 1 && pixelClash(output.GetPixel(x, y), output.GetPixel(x, y + 1), threshold.y))) { clashes.Add(new Pair <int, int>(x, y)); } } } int clash_count = clashes.Count; for (int i = 0; i < clash_count; ++i) { Pair <int, int> clash = clashes[i]; FloatRGB pixel = output.GetPixel(clash.first, clash.second); float med = median(pixel.r, pixel.g, pixel.b); pixel.r = med; pixel.g = med; pixel.b = med; } //for (std::vector<std::pair<int, int>>::const_iterator clash = clashes.begin(); clash != clashes.end(); ++clash) //{ // FloatRGB & pixel = output(clash->first, clash->second); // float med = median(pixel.r, pixel.g, pixel.b); // pixel.r = med, pixel.g = med, pixel.b = med; //} }
static bool pixelClash(FloatRGB a, FloatRGB b, double threshold) { // Only consider pair where both are on the inside or both are on the outside bool aIn = ((a.r > 0.5f) ? 1 : 0) + ((a.g > .5f) ? 1 : 0) + ((a.b > .5f) ? 1 : 0) >= 2; bool bIn = ((b.r > 0.5f) ? 1 : 0) + ((b.g > .5f) ? 1 : 0) + ((b.b > .5f) ? 1 : 0) >= 2; if (aIn != bIn) { return(false); } // If the change is 0 <-> 1 or 2 <-> 3 channels and not 1 <-> 1 or 2 <-> 2, it is not a clash if ((a.r > .5f && a.g > .5f && a.b > .5f) || (a.r < .5f && a.g < .5f && a.b < .5f) || (b.r > .5f && b.g > .5f && b.b > .5f) || (b.r < .5f && b.g < .5f && b.b < .5f)) { return(false); } // Find which color is which: _a, _b = the changing channels, _c = the remaining one float aa, ab, ba, bb, ac, bc; if ((a.r > .5f) != (b.r > .5f) && (a.r < .5f) != (b.r < .5f)) { aa = a.r; ba = b.r; if ((a.g > .5f) != (b.g > .5f) && (a.g < .5f) != (b.g < .5f)) { ab = a.g; bb = b.g; ac = a.b; bc = b.b; } else if ((a.b > .5f) != (b.b > .5f) && (a.b < .5f) != (b.b < .5f)) { ab = a.b; bb = b.b; ac = a.g; bc = b.g; } else { return(false); // this should never happen } } else if ((a.g > .5f) != (b.g > .5f) && (a.g < .5f) != (b.g < .5f) && (a.b > .5f) != (b.b > .5f) && (a.b < .5f) != (b.b < .5f)) { aa = a.g; ba = b.g; ab = a.b; bb = b.b; ac = a.r; bc = b.r; } else { return(false); } // Find if the channels are in fact discontinuous return((Math.Abs(aa - ba) >= threshold) && (Math.Abs(ab - bb) >= threshold) && Math.Abs(ac - .5f) >= Math.Abs(bc - .5f)); // Out of the pair, only flag the pixel farther from a shape edge }
public static int[] ConvertToIntBmp(FloatRGBBmp input) { int height = input.Height; int width = input.Width; int[] output = new int[input.Width * input.Height]; for (int y = height - 1; y >= 0; --y) { for (int x = 0; x < width; ++x) { //a b g r //---------------------------------- FloatRGB pixel = input.GetPixel(x, y); //a b g r //for big-endian color //int abgr = (255 << 24) | // Vector2.Clamp((int)(pixel.r * 0x100), 0xff) | // Vector2.Clamp((int)(pixel.g * 0x100), 0xff) << 8 | // Vector2.Clamp((int)(pixel.b * 0x100), 0xff) << 16; //for little-endian color int abgr = (255 << 24) | Vector2.Clamp((int)(pixel.r * 0x100), 0xff) << 16 | Vector2.Clamp((int)(pixel.g * 0x100), 0xff) << 8 | Vector2.Clamp((int)(pixel.b * 0x100), 0xff); output[(y * width) + x] = abgr; //---------------------------------- /**it++ = clamp(int(bitmap(x, y).r*0x100), 0xff); * it++ = clamp(int(bitmap(x, y).g*0x100), 0xff); * it++ = clamp(int(bitmap(x, y).b*0x100), 0xff);*/ } } return(output); }
public void SetPixel(int x, int y, FloatRGB value) { this.buffer[x + (y * Width)] = value; }
public static int[] ConvertToIntBmp(FloatRGBBmp input, bool flipY) { int height = input.Height; int width = input.Width; int[] output = new int[input.Width * input.Height]; if (flipY) { int dstLineHead = width * (height - 1); for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { //a b g r //---------------------------------- FloatRGB pixel = input.GetPixel(x, y); //a b g r //for big-endian color //int abgr = (255 << 24) | // Vector2.Clamp((int)(pixel.r * 0x100), 0xff) | // Vector2.Clamp((int)(pixel.g * 0x100), 0xff) << 8 | // Vector2.Clamp((int)(pixel.b * 0x100), 0xff) << 16; //for little-endian color output[dstLineHead + x] = (255 << 24) | Vector2.Clamp((int)(pixel.r * 0x100), 0xff) << 16 | Vector2.Clamp((int)(pixel.g * 0x100), 0xff) << 8 | Vector2.Clamp((int)(pixel.b * 0x100), 0xff); //output[(y * width) + x] = abgr; //---------------------------------- /**it++ = clamp(int(bitmap(x, y).r*0x100), 0xff); * it++ = clamp(int(bitmap(x, y).g*0x100), 0xff); * it++ = clamp(int(bitmap(x, y).b*0x100), 0xff);*/ } dstLineHead -= width; } } else { int dstLineHead = 0; for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { //a b g r //---------------------------------- FloatRGB pixel = input.GetPixel(x, y); //a b g r //for big-endian color //int abgr = (255 << 24) | // Vector2.Clamp((int)(pixel.r * 0x100), 0xff) | // Vector2.Clamp((int)(pixel.g * 0x100), 0xff) << 8 | // Vector2.Clamp((int)(pixel.b * 0x100), 0xff) << 16; //for little-endian color output[dstLineHead + x] = (255 << 24) | Vector2.Clamp((int)(pixel.r * 0x100), 0xff) << 16 | Vector2.Clamp((int)(pixel.g * 0x100), 0xff) << 8 | Vector2.Clamp((int)(pixel.b * 0x100), 0xff); //output[(y * width) + x] = abgr; //---------------------------------- /**it++ = clamp(int(bitmap(x, y).r*0x100), 0xff); * it++ = clamp(int(bitmap(x, y).g*0x100), 0xff); * it++ = clamp(int(bitmap(x, y).b*0x100), 0xff);*/ } dstLineHead += width; } } return(output); }
public void SetPixel(int x, int y, FloatRGB value) { _buffer[x + (y * _w)] = value; }