private static Color GetBestPixel(Color true_color, IColorAlgorithm algorithm, IJavaVersion mapping) { // partial transparency is not allowed if (true_color.A < 128) { return(Color.FromArgb(0, 0, 0, 0)); } if (NearestColorCache.TryGetValue(true_color, out var cached)) { return(cached); } Color best_approximate = Color.Empty; double mindist = Double.PositiveInfinity; // find the color in the palette that is closest to this one foreach (Color mapcolor in mapping.GetAllColors().Where(o => o.A == 255)) { double distance = algorithm.Distance(true_color, mapcolor); if (mindist > distance) { mindist = distance; best_approximate = mapcolor; } } NearestColorCache.Set(true_color, best_approximate); return(best_approximate); }
public static IEnumerable <JavaMap> FromSettings(MapCreationSettings settings) { Bitmap original = ResizeImg(settings.Original, MAP_WIDTH * settings.SplitW, MAP_HEIGHT * settings.SplitH, settings.InterpMode); LockBitmap final = new LockBitmap((Bitmap)original.Clone()); final.LockBits(); // first index = which map this is var colors = new byte[settings.SplitW * settings.SplitH][]; for (int i = 0; i < colors.Length; i++) { colors[i] = new byte[MAP_WIDTH * MAP_HEIGHT]; } #region java map algorithm for (int y = 0; y < final.Height; y++) { for (int x = 0; x < final.Width; x++) { Color oldpixel = final.GetPixel(x, y); Color newpixel = Color.Empty; // partial transparency is not allowed if (oldpixel.A < 128) { newpixel = Color.FromArgb(0, 0, 0, 0); } else { if (!NearestColorCache.TryGetValue(oldpixel, out newpixel)) { double mindist = Double.PositiveInfinity; // find the color in the palette that is closest to this one foreach (Color mapcolor in ColorToByte.Keys.Where(o => o.A == 255)) { double distance = ColorDistance(oldpixel, mapcolor); if (mindist > distance) { mindist = distance; newpixel = mapcolor; } } NearestColorCache[oldpixel] = newpixel; } } final.SetPixel(x, y, newpixel); if (settings.Dither) { // floyd-steinberg int error_a = oldpixel.A - newpixel.A; int error_r = oldpixel.R - newpixel.R; int error_g = oldpixel.G - newpixel.G; int error_b = oldpixel.B - newpixel.B; GiveError(final, x + 1, y, error_a, error_r, error_g, error_b, 7); GiveError(final, x - 1, y + 1, error_a, error_r, error_g, error_b, 3); GiveError(final, x, y + 1, error_a, error_r, error_g, error_b, 5); GiveError(final, x + 1, y + 1, error_a, error_r, error_g, error_b, 1); } int currentmap = y / MAP_HEIGHT * settings.SplitW + x / MAP_WIDTH; int currentpixel = MAP_WIDTH * (y % MAP_HEIGHT) + (x % MAP_WIDTH); if (newpixel == Color.FromArgb(0, 0, 0, 0)) { colors[currentmap][currentpixel] = 0x00; } else { colors[currentmap][currentpixel] = ColorToByte[newpixel]; } } } #endregion final.UnlockBits(); var maps = new List <JavaMap>(); for (int y = 0; y < settings.SplitH; y++) { for (int x = 0; x < settings.SplitW; x++) { Rectangle crop = new Rectangle( x * original.Width / settings.SplitW, y * original.Height / settings.SplitH, original.Width / settings.SplitW, original.Height / settings.SplitH); maps.Add(new JavaMap( CropImage(original, crop), CropImage(final.GetImage(), crop), colors[settings.SplitW * y + x])); } } return(maps); }