Color GetClosestColor(Color c) { stopwatch_gcc.Start(); Color result; switch (mode) { case 1: result = palette[ColorsHelper.closestColor1(palette, c)]; break; case 2: result = palette[ColorsHelper.closestColor2(palette, c)]; break; case 3: result = palette[ColorsHelper.closestColor3(palette, c)]; break; default: throw new InvalidOperationException(); } stopwatch_gcc.Stop(); return(result); }
void ProcessImage(Bitmap m) { try { this.InvokeX(() => { DisableMainPanel(); }); void ProcessUsingLockbitsAndParallel(Bitmap processedBitmap) {//this was also copied with modifications BitmapData bitmapData = processedBitmap.LockBits(new Rectangle(0, 0, processedBitmap.Width, processedBitmap.Height), ImageLockMode.ReadWrite, processedBitmap.PixelFormat); int bytesPerPixel = Image.GetPixelFormatSize(processedBitmap.PixelFormat) / 8; int byteCount = bitmapData.Stride * processedBitmap.Height; int heightInPixels = bitmapData.Height; int widthInBytes = bitmapData.Width * bytesPerPixel; byte[] pixels = new byte[byteCount]; IntPtr ptrFirstPixel = bitmapData.Scan0; Marshal.Copy(ptrFirstPixel, pixels, 0, pixels.Length); var thecache = cache[mode - 1]; Parallel.For(0, heightInPixels, new ParallelOptions() { MaxDegreeOfParallelism = maxParallelism }, y => { int currentLine = y * bitmapData.Stride; for (int x = 0; x < widthInBytes; x = x + bytesPerPixel) { byte oldBlue = pixels[currentLine + x]; byte oldGreen = pixels[currentLine + x + 1]; byte oldRed = pixels[currentLine + x + 2]; byte oldAlpha = 255; if (bytesPerPixel > 3) { oldAlpha = pixels[currentLine + x + 3]; } // calculate new pixel value if (oldAlpha < 127) { oldAlpha = 0; } else { oldAlpha = 255; } var oldc = Color.FromArgb(oldAlpha, oldRed, oldGreen, oldBlue); var oldargb = oldc.ToArgb(); Color c; if (oldAlpha == 0) { //c = Color.FromArgb(WorldData.FromBlockColorToArgb(WorldData.BlockColors[(ushort)BlockId.Black])); //c = Color.Transparent; c = Color.FromArgb(0, 0, 0, 0); } else { Trace.Assert(oldAlpha == 255); if (thecache.ContainsKey(oldargb)) { c = Color.FromArgb(RoomData.FromBlockColorToARGB(RoomData.BlockColors[thecache[oldargb]])); } else { c = GetClosestColor(oldc); if (!thecache.TryAdd(oldargb, palettebid[c.ToArgb()])) { Console.WriteLine("someone was faster than me! " + oldargb.ToString("X6")); } cacheModified = true; } } image[x / bytesPerPixel, y] = c; //Console.WriteLine($"{x / bytesPerPixel},{y}"); oldRed = c.R; oldGreen = c.G; oldBlue = c.B; pixels[currentLine + x] = oldBlue; pixels[currentLine + x + 1] = oldGreen; pixels[currentLine + x + 2] = oldRed; if (bytesPerPixel > 3) { pixels[currentLine + x + 3] = oldAlpha; } } }); // copy modified bytes back Marshal.Copy(pixels, 0, ptrFirstPixel, pixels.Length); processedBitmap.UnlockBits(bitmapData); } imgw = m.Width; imgh = m.Height; image = new Color[imgw, imgh]; Stopwatch stopwatch = Stopwatch.StartNew(); stopwatch_gcc.Reset(); ColorsHelper.ResetTimers(); ProcessUsingLockbitsAndParallel(m); stopwatch_gcc.Stop(); stopwatch.Stop(); Console.WriteLine($"in GetClosestColor: {stopwatch_gcc.Elapsed}"); Console.WriteLine($"total: {stopwatch.Elapsed}"); ColorsHelper.PrintTimers(); this.InvokeX(() => { pictureBox1.Image?.Dispose(); pictureBox1.Image = m; originalSize = new Size(imgw, imgh); trackBar3_Scroll(this, null); pictureBox1.Location = new Point(0, 0); EnableMainPanel(); this.AllowDrop = true; button2.Enabled = true; trackBar3.Enabled = true; button3.Enabled = true; }); } catch { Debugger.Break(); throw; } }