Beispiel #1
0
        private void Window_ImageReady(object sender, MapCreationSettings settings)
        {
            var pending = new PendingMapsWithID(GetSafeID(), settings, WorldSide);

            ImportSide.AddPending(pending);
            pending.ProgressChanged += Pending_ProgressChanged;
        }
Beispiel #2
0
        private void ConfirmButton_Click(object sender, EventArgs e)
        {
            int index = EditingIndex;
            int final;

            if (SingleImage)
            {
                final = index;
            }
            else
            {
                final = ApplyAllCheck.Checked ? InputPaths.Length - 1 : EditingIndex;
            }
            for (int i = index; i <= final; i++)
            {
                if (i > index)
                {
                    ProcessNextImage(true);
                }
                if (CurrentImage == null)
                {
                    return;
                }
                bool dithered = AllowDither && DitherChecked;
                var  settings = new MapCreationSettings(CurrentImage, (int)WidthInput.Value, (int)HeightInput.Value, GetInterpolationMode(), dithered, StretchChecked);
                ImageReady?.Invoke(this, settings);
            }
            EditingIndex = final;
            ProcessNextImage(false);
        }
Beispiel #3
0
        public static IEnumerable <BedrockMap> FromSettings(MapCreationSettings settings)
        {
            Bitmap     original = ResizeImg(settings.Original, MAP_WIDTH * settings.SplitW, MAP_HEIGHT * settings.SplitH, settings.InterpMode, !settings.Stretch);
            LockBitmap final    = new LockBitmap((Bitmap)original.Clone());

            final.LockBits();
            // first index = which map this is
            var colors = new byte[settings.NumberOfMaps][];

            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);
                    var map_image = CropImage(final.GetImage(), crop);
                    //if (!IsEmpty(map_image))
                    maps.Add(new BedrockMap(
                                 CropImage(original, crop),
                                 map_image,
                                 colors[settings.SplitW * y + x]));
                }
            }
            return(maps);
        }
Beispiel #4
0
        private Task ImportFromSettings(long id, Edition edition, MapCreationSettings settings)
        {
            var number = settings.NumberOfMaps;
            var boxes  = new MapIDControl[number];

            for (int i = 0; i < number; i++)
            {
                var box = new MapIDControl(id + i);
                boxes[i]       = box;
                box.MouseDown += Box_MouseDown;
            }
            SendToZone(boxes, MapStatus.Importing);
            Task <IEnumerable <Map> > t;

            if (edition == Edition.Java)
            {
                t = new Task <IEnumerable <Map> >(() =>
                {
                    return(JavaMap.FromSettings(settings));
                });
            }
            else
            {
                t = new Task <IEnumerable <Map> >(() =>
                {
                    return(BedrockMap.FromSettings(settings));
                });
            }
            t.ContinueWith((prev) =>
            {
                settings.Dispose();
                if (t.IsFaulted)
                {
                    MessageBox.Show($"Failed to create some maps for this reason: {ExceptionMessage(t.Exception)}", "Map load error!");
                    RemoveFromZone(boxes, MapStatus.Importing);
                }
                var results = prev.Result.ToArray();
                for (int i = 0; i < number; i++)
                {
                    boxes[i].SetBox(new MapPreviewBox(results[i]));
                }
            }, TaskScheduler.FromCurrentSynchronizationContext());
            return(t);
        }
        private async Task GetMaps(MapCreationSettings settings, MinecraftWorld world)
        {
            var progress = new Progress <MapCreationProgress>();

            progress.ProgressChanged += (s, e) => ProgressChanged?.Invoke(this, e);
            var maps = (await Task.Run(() => world.MapsFromSettings(settings, progress))).ToList();

            lock (IDModificationLock)
            {
                var ids = UsedIDs;
                foreach (int index in DiscardIndexes.OrderByDescending(x => x))
                {
                    ids.RemoveAt(index);
                    maps.RemoveAt(index);
                }
                ResultMaps = ids.Zip(maps, (k, v) => new { k, v }).ToDictionary(x => x.k, x => x.v);
            }
            Finish();
        }
Beispiel #6
0
        private void ConfirmUntil(int final_index)
        {
            int index = EditingIndex;

            for (int i = index; i <= final_index; i++)
            {
                if (i > index)
                {
                    ProcessNextImage(true);
                }
                if (CurrentImage == null)
                {
                    return;
                }
                bool dithered = ApproximateColorOptions && DitherChecked;
                var  settings = new MapCreationSettings(CurrentImage, (int)WidthInput.Value, (int)HeightInput.Value, GetInterpolationMode(), dithered, StretchChecked, GetAlgorithm());
                ImageReady?.Invoke(this, settings);
            }
            EditingIndex = final_index;
            ProcessNextImage(false);
        }
Beispiel #7
0
 // user needs to call this
 public abstract IEnumerable <Map> MapsFromSettings(MapCreationSettings settings, IProgress <MapCreationProgress> progress);
 public PendingMapsWithID(long first_id, MapCreationSettings settings, MinecraftWorld world)
 {
     UsedIDs  = Util.CreateRange(first_id, settings.NumberOfMaps).ToList();
     Settings = settings;
     _        = GetMaps(settings, world);
 }
Beispiel #9
0
 public override IEnumerable <Map> MapsFromSettings(MapCreationSettings settings, IProgress <MapCreationProgress> progress)
 {
     // bedrock maps are fast enough that reporting progress is not needed
     return(BedrockMap.FromSettings(settings));
 }
Beispiel #10
0
 public override IEnumerable <Map> MapsFromSettings(MapCreationSettings settings, IProgress <MapCreationProgress> progress)
 {
     return(JavaMap.FromSettings(settings, Version, progress));
 }
Beispiel #11
0
        public static IEnumerable <JavaMap> FromSettings(MapCreationSettings settings)
        {
            Bitmap     original = ResizeImg(settings.Original, MAP_WIDTH * settings.SplitW, MAP_HEIGHT * settings.SplitH, settings.InterpMode, !settings.Stretch);
            LockBitmap final    = new LockBitmap((Bitmap)original.Clone());

            final.LockBits();
            // first index = which map this is
            var colors = new byte[settings.NumberOfMaps][];

            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.Set(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);
                    var map_image = CropImage(final.GetImage(), crop);
                    // if (!IsEmpty(map_image))
                    // currently commented out because the user can pretty easily check if there are going to be empty maps
                    // also it breaks the temporary loading maps that assume exactly width*height outputs
                    maps.Add(new JavaMap(
                                 CropImage(original, crop),
                                 map_image,
                                 colors[settings.SplitW * y + x]));
                }
            }
            return(maps);
        }
Beispiel #12
0
        public static IEnumerable <JavaMap> FromSettings(MapCreationSettings settings, IJavaVersion mapping, IProgress <MapCreationProgress> progress)
        {
            Bitmap     original = ResizeImg(settings.Original, MAP_WIDTH * settings.SplitW, MAP_HEIGHT * settings.SplitH, settings.InterpMode, !settings.Stretch);
            LockBitmap final    = new LockBitmap((Bitmap)original.Clone());

            final.LockBits();
            // first index = which map this is
            var colors = new byte[settings.NumberOfMaps][];

            for (int i = 0; i < colors.Length; i++)
            {
                colors[i] = new byte[MAP_WIDTH * MAP_HEIGHT];
            }

            var report = new MapCreationProgress();

            #region java map algorithm
            for (int y = 0; y < final.Height; y++)
            {
                report.PercentageComplete = ((decimal)y) / final.Height;
                progress.Report(report);
                for (int x = 0; x < final.Width; x++)
                {
                    Color oldpixel = final.GetPixel(x, y);
                    var   newpixel = GetBestPixel(oldpixel, settings.Algorithm, mapping);
                    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] = mapping.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);
                    var map_image = CropImage(final.GetImage(), crop);
                    maps.Add(new JavaMap(
                                 CropImage(original, crop),
                                 map_image,
                                 colors[settings.SplitW * y + x]));
                }
            }
            return(maps);
        }