public static void test(ref Bitmap bmp, int avgMapSize, int smoothness, bool showSmoothness, float thresh) { BitmapData data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, bmp.PixelFormat); int stride = data.Stride; int bppModifier = bmp.PixelFormat == System.Drawing.Imaging.PixelFormat.Format24bppRgb ? 3 : 4; int red, green, blue = 0; // Make a copy int length = Math.Abs(data.Stride) * data.Height; byte[] copy = new byte[length]; Marshal.Copy(data.Scan0, copy, 0, copy.Length); // Compute average float[] averageMap = new float[length]; ImageProcessing.computeAvgMap(ref averageMap, stride, bppModifier, bmp.Width, bmp.Height, copy, avgMapSize); // Get image smoothness float[] smoothnessMap = new float[length]; ImageProcessing.computeSmoothnessMap(ref smoothnessMap, averageMap, stride, bppModifier, bmp.Width, bmp.Height, copy, smoothness); unsafe { byte *ptr = (byte *)data.Scan0; for (int y = 0; y < bmp.Height; y++) { for (int x = 0; x < bmp.Width; x++) { bool above = smoothnessMap[y * bmp.Width + x] > thresh; int val = showSmoothness ? (above ? 200 : 0) : (int)averageMap[y * bmp.Width + x]; // Write result ptr[(x * bppModifier) + y * stride] = (byte)val; ptr[(x * bppModifier) + y * stride + 1] = (byte)val; ptr[(x * bppModifier) + y * stride + 2] = (byte)val; } } } }
// Smart edges (tm) ;-) public static void SmartMergeVertical(ref Bitmap bmp, int xpos, int mergeSize, int smoothness, int avgMapSize, float stopThreshold) { BitmapData data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, bmp.PixelFormat); int stride = data.Stride; int bppModifier = bmp.PixelFormat == System.Drawing.Imaging.PixelFormat.Format24bppRgb ? 3 : 4; int red, green, blue = 0; int red2, green2, blue2 = 0; unsafe { byte *ptr = (byte *)data.Scan0; // Make a copy int length = Math.Abs(data.Stride) * data.Height; byte[] copy = new byte[length]; Marshal.Copy(data.Scan0, copy, 0, copy.Length); // Compute average float[] averageMap = new float[length]; ImageProcessing.computeAvgMap(ref averageMap, stride, bppModifier, bmp.Width, bmp.Height, copy, avgMapSize); // Get image smoothness float[] smoothnessMap = new float[length]; ImageProcessing.computeSmoothnessMap(ref smoothnessMap, averageMap, stride, bppModifier, bmp.Width, bmp.Height, copy, smoothness); // Stops int[] stops = new int[bmp.Height]; getStops(ref stops, smoothnessMap, averageMap, xpos, bmp.Width, bmp.Height, smoothness, mergeSize, stopThreshold); for (int y = 0; y < bmp.Height; y++) { //// Decide on a direction (left or right) //bool dirIsRight = false; //float smoothleft = smoothnessMap[y * bmp.Width + (xpos - smoothness)]; //float smoothright = smoothnessMap[y * bmp.Width + (xpos + smoothness)]; //dirIsRight = smoothleft < smoothright; //// Determine a 'stop' //int stopx = xpos; //for (int sx = dirIsRight ? xpos + 2*smoothness : xpos - 2*smoothness; dirIsRight ? sx < xpos + mergeSize : sx > xpos - mergeSize; sx += dirIsRight ? 1 : -1) //{ // if (smoothnessMap[y * bmp.Width + sx] > stopThreshold) // { // stopx = sx; // break; // } //} int stopx = stops[y]; bool dirIsRight = stopx <= xpos ? false : true; // How many smoothing pixels? int nbPixels = Math.Abs(stopx - xpos); // Make border for (int x = dirIsRight ? xpos : xpos - 1; dirIsRight?x <stopx : x> stopx; x += (dirIsRight ? 1 : -1)) { // Get x,y color int idx = (y * stride) + x * bppModifier; red = ptr[idx + 2]; green = ptr[idx + 1]; blue = ptr[idx]; // Get merge color (symetry) int symx = dirIsRight ? (xpos - (x - xpos) + 1) : (xpos + (xpos - x)); int symidx = (y * stride) + symx * bppModifier; red2 = ptr[symidx + 2]; green2 = ptr[symidx + 1]; blue2 = ptr[symidx]; // Get merge factor f(x) // todo: si stops du haut s'arrête avant, fusion inclut pixel du haut (pareil pour bas) float localPixWeight = 0;// (float)Math.Abs((float)x - (float)xpos) / (float)nbPixels; //if (x > xpos) localPixWeight = 1;// 1.0f / localPixWeight; float symPixWeight = 1.0F - localPixWeight; // Merge red = (int)(localPixWeight * (float)red + symPixWeight * (float)red2); green = (int)(localPixWeight * (float)green + symPixWeight * (float)green2); blue = (int)(localPixWeight * (float)blue + symPixWeight * (float)blue2); // Write result ptr[(x * bppModifier) + y * stride] = (byte)blue; ptr[(x * bppModifier) + y * stride + 1] = (byte)green; ptr[(x * bppModifier) + y * stride + 2] = (byte)red; } } } }