Esempio n. 1
0
 public JavaMap(byte[] colors) : base(colors)
 {
     if (colors.Length != MAP_WIDTH * MAP_HEIGHT)
     {
         throw new ArgumentException($"Invalid image dimensions: {colors.Length} is not {MAP_WIDTH}*{MAP_HEIGHT}");
     }
     Image = new LockBitmap(MAP_WIDTH, MAP_HEIGHT);
     Image.LockBits();
     for (int y = 0; y < MAP_HEIGHT; y++)
     {
         for (int x = 0; x < MAP_WIDTH; x++)
         {
             byte color = colors[(MAP_WIDTH * y) + x];
             if (ByteToColor.TryGetValue(color, out Color col))
             {
                 Image.SetPixel(x, y, col);
             }
             else
             {
                 Image.SetPixel(x, y, Color.Transparent);
             }
         }
     }
     Image.UnlockBits();
     Original = Image.GetImage();
 }
Esempio n. 2
0
        public static IEnumerable <BedrockMap> 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 * 4];
            }

            #region bedrock map algorithm
            for (int y = 0; y < final.Height; y++)
            {
                for (int x = 0; x < final.Width; x++)
                {
                    Color realpixel = final.GetPixel(x, y);
                    Color nearest   = Color.FromArgb(realpixel.A < 128 ? 0 : 255, realpixel.R, realpixel.G, realpixel.B);
                    final.SetPixel(x, y, nearest);
                    int currentmap = y / MAP_HEIGHT * settings.SplitW + x / MAP_WIDTH;
                    int byteindex  = MAP_WIDTH * 4 * (y % MAP_HEIGHT) + 4 * (x % MAP_WIDTH);
                    colors[currentmap][byteindex]     = nearest.R;
                    colors[currentmap][byteindex + 1] = nearest.G;
                    colors[currentmap][byteindex + 2] = nearest.B;
                    // saving the alpha works just fine, but bedrock renders each pixel fully solid or transparent
                    // it rounds (<128: invisible, >=128: solid)
                    colors[currentmap][byteindex + 3] = nearest.A;
                }
            }
            #endregion
            final.UnlockBits();

            var maps = new List <BedrockMap>();
            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 BedrockMap(
                                 CropImage(original, crop),
                                 CropImage(final.GetImage(), crop),
                                 colors[settings.SplitW * y + x]));
                }
            }
            return(maps);
        }
Esempio n. 3
0
 private static void GiveError(LockBitmap img, int x, int y, int alpha, int red, int green, int blue, int proportion)
 {
     if (x >= 0 && y >= 0 && x < img.Width && y < img.Height)
     {
         Color old = img.GetPixel(x, y);
         img.SetPixel(x, y, Color.FromArgb(
                          ByteClamp(old.A, (alpha * proportion) >> 4),
                          ByteClamp(old.R, (red * proportion) >> 4),
                          ByteClamp(old.G, (green * proportion) >> 4),
                          ByteClamp(old.B, (blue * proportion) >> 4)
                          ));
     }
 }
Esempio n. 4
0
 public BedrockMap(byte[] colors) : base(colors)
 {
     if (colors.Length != MAP_WIDTH * MAP_HEIGHT * 4)
     {
         throw new ArgumentException($"Invalid image dimensions: {colors.Length} is not {MAP_WIDTH}*{MAP_HEIGHT}*4");
     }
     Image = new LockBitmap(MAP_WIDTH, MAP_HEIGHT);
     Image.LockBits();
     for (int y = 0; y < MAP_HEIGHT; y++)
     {
         for (int x = 0; x < MAP_WIDTH; x++)
         {
             int byteindex = (MAP_WIDTH * 4 * y) + (4 * x);
             Image.SetPixel(x, y, Color.FromArgb(colors[byteindex + 3], colors[byteindex], colors[byteindex + 1], colors[byteindex + 2]));
         }
     }
     Image.UnlockBits();
     Original = Image.GetImage();
 }
Esempio n. 5
0
 protected Map(Bitmap original, Bitmap converted, byte[] colors)
 {
     Original = original;
     Image    = new LockBitmap((Bitmap)converted.Clone());
     Colors   = colors;
 }
Esempio n. 6
0
        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);
        }