public void Rasterize(Raster raster, string symbol) { using (var g = Graphics.FromImage(_bitmap)) { g.FillRectangle(Brushes.White, _rectangle); g.DrawString(symbol, _font, Brushes.Black, _rectangleF, _format); } var bits = _bitmap.LockBits(_rectangle, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); Marshal.Copy(bits.Scan0, _raw, 0, _raw.Length); _bitmap.UnlockBits(bits); int k = 0; for (int y = 0; y < _size; y++) { for (int x = 0; x < _size; x++) { raster.Data[y, x] = _raw[k]; k += 3; } } }
public void Process(Raster input, Raster output, int inSize, int outSize, int distance, int ss) { ProcessForward(input, output, inSize, distance, ss, _dist); ProcessBackward(input, output, inSize, distance, ss, _dist); }
void ProcessForward(Raster input, Raster output, int inSize, int distance, int ss, Point[,] dist) { for (int y = 0; y < inSize; y++) { for (int x = 0; x < inSize; x++) { bool inner = input.Data[y, x] < 128; var minDistance = inner ? int.MaxValue : int.MinValue; int mx = -distance; int my = -distance; for (int k = 0; k < 4; k++) { int dx = 0; int dy = 0; switch (k) { case 0: dx = -1; dy = 0; break; case 1: dx = -1; dy = -1; break; case 2: dx = 0; dy = -1; break; case 3: dx = 1; dy = -1; break; } int rx = x + dx; int ry = y + dy; if (rx < 0 || rx >= inSize || ry < 0 || ry >= inSize) { continue; } bool inner2 = input.Data[ry, rx] < 128; if (inner == inner2) { dx += dist[ry, rx].X; dy += dist[ry, rx].Y; } var ddd = dx * dx + dy * dy; if (!inner) { ddd = -ddd; } if (inner && ddd < minDistance) { minDistance = ddd; mx = dx; my = dy; } if (!inner && ddd > minDistance) { minDistance = ddd; mx = dx; my = dy; } } if (mx > short.MaxValue) { mx = short.MaxValue; } if (mx < short.MinValue) { mx = short.MinValue; } if (my > short.MaxValue) { my = short.MaxValue; } if (my < short.MinValue) { my = short.MinValue; } dist[y, x].X = (short)mx; dist[y, x].Y = (short)my; } } }
void ProcessBackward(Raster input, Raster output, int inSize, int distance, int ss, Point[,] dist) { for (int y = inSize - 1; y >= 0; y--) { for (int x = inSize - 1; x >= 0; x--) { bool inner = input.Data[y, x] < 128; var minDistance = inner ? int.MaxValue : int.MinValue; int mx = distance; int my = distance; for (int k = 0; k < 5; k++) { int dx = 0; int dy = 0; switch (k) { case 0: dx = 1; dy = 0; break; case 1: dx = 1; dy = 1; break; case 2: dx = 0; dy = 1; break; case 3: dx = -1; dy = 1; break; case 4: dx = 0; dy = 0; break; } int rx = x + dx; int ry = y + dy; if (rx < 0 || rx >= inSize || ry < 0 || ry >= inSize) { continue; } bool inner2 = input.Data[ry, rx] < 128; if (inner == inner2) { dx += dist[ry, rx].X; dy += dist[ry, rx].Y; } var ddd = dx * dx + dy * dy; if (!inner) { ddd = -ddd; } if (inner && ddd < minDistance) { minDistance = ddd; mx = dx; my = dy; } if (!inner && ddd > minDistance) { minDistance = ddd; mx = dx; my = dy; } } if (mx > short.MaxValue) { mx = short.MaxValue; } if (mx < short.MinValue) { mx = short.MinValue; } if (my > short.MaxValue) { my = short.MaxValue; } if (my < short.MinValue) { my = short.MinValue; } dist[y, x].X = (short)mx; dist[y, x].Y = (short)my; if (x % ss == ss / 2 && y % ss == ss / 2) { bool minus = minDistance < 0; double val = (Math.Sqrt(Math.Abs((double)minDistance)) / distance); val = ((minus ? -val : val) + 1) / 2; int v = (int)(val * 255); if (v < 0) { v = 0; } if (v > 255) { v = 255; } output.Data[y / ss, x / ss] = (byte)v; } } } }