/// <summary> /// Permette di esportare tutte le immagini della collezione in una cartella /// </summary> /// <param name="PathOut"></param> /// <param name="OriginalName"></param> /// <param name="FormatoOutput"></param> public void Export(String PathOut, String OriginalName, FormatoOut FormatoOutput = FormatoOut.jpg) { StateChange?.Invoke(this, State.InWorking); if (!Directory.Exists(PathOut)) { Directory.CreateDirectory(PathOut); } if (ic.IsEmpty) { StateChange?.Invoke(this, State.Finish); return; } ImageFormat format; if (FormatoOutput == FormatoOut.jpg) { format = ImageFormat.Jpeg; } else if (FormatoOutput == FormatoOut.png) { format = ImageFormat.Png; } else if (FormatoOutput == FormatoOut.bmp) { format = ImageFormat.Bmp; } else { format = ImageFormat.Jpeg; } String Ext = FormatoOutput.ToString(); int current = 0; int tot = ic.Collection.Count; foreach (Image i in ic.Collection) { ProgressChange?.Invoke(this, current++, tot); ExportSingle(i, format, Path.Combine(PathOut, OriginalName + "_" + current + "." + Ext)); } StateChange?.Invoke(this, State.Finish); }
public void MakeProgress(float deltaTime) { float currentProgress = Mathf.Min(Duration, CurrentProgress + deltaTime * AssignedDesk.Skill); m_UI.SetProgressBar(currentProgress / Duration); CurrentProgress = currentProgress; ProgressChange?.Invoke(CurrentProgress); if (CurrentProgress >= Duration) { IsCompleted = true; } }
/// <inheritdoc /> public PackingResult PlaceRects(int width, int height, IEnumerable <PPRect> rects, CancellationToken token = default) { Progress = 0; if (rects == null) { throw new ArgumentNullException($"The {nameof(rects)} cannot be null"); } var sortedRects = imageSorter.SortImages(rects); freeRectanglesList.Clear(); freeRectanglesList.Add(new PPRect(0, 0, width, height)); List <PPRect> packing = new List <PPRect>(sortedRects.Count()); int inputSize = packing.Count; int placedRects = 0; foreach (var rectToPlace in sortedRects) { if (token.IsCancellationRequested) { Progress = 0; return(null); } PPRect?freeRectToUse = freeRectExtractor.ExtractFreeRectangle(freeRectanglesList, rectToPlace); //parametrizable part if (freeRectToUse == null) //unable to pack { Progress = 100; return(null); } var rectRotated = DecideOrientationOfRect(rectToPlace); var freeRects = freeRectangleSplitter.SplitFreeRectangle(freeRectToUse.Value, rectToPlace); //parametrizable part freeRectangleMerger.MergeFreeRectangles(freeRectanglesList, freeRects); //parametrizable part var rectToPlaceOriented = rectOrientationSelector.DetermineAndApplyRectOrientation(rectToPlace); //parametrizable part packing.Add(new PPRect(freeRectToUse.Value.Left, freeRectToUse.Value.Top, freeRectToUse.Value.Left + rectToPlace.Width, freeRectToUse.Value.Top + rectToPlace.Height, rectToPlaceOriented.Image)); freeRectanglePostProcessor?.PostProcess(freeRectanglesList, packing.Last()); Progress = (int)((++placedRects / (double)inputSize) * 100.0); ProgressChange?.Invoke(this, Progress); } return(new PackingResult(width, height, packing)); }
protected void SetProgress(float p) { p = Math.Min(1f, Math.Max(0f, p)); Progress = p; ProgressChange?.Invoke(Progress); }
public void Report(float progress) { Logger.Log <ProgressRepporter>(LoggerLevel.Info, $"{Status}: {(int)(progress * 100)}%"); Progress = progress; ProgressChange?.Invoke(this, Progress); }
/// <summary> /// Permette di esportare tutte le immagini in un unico file ( file sprite ); i dati vengono inviati ad uno stream /// </summary> /// <param name="sw"></param> /// <param name="FormatoOutput"></param> public void Export(StreamWriter sw, FormatoOut FormatoOutput = FormatoOut.jpg) { StateChange?.Invoke(this, State.InWorking); if (ic.IsEmpty) { StateChange?.Invoke(this, State.Finish); return; } //Ottengo dimensione reale di un frame Size OriginalSize = ic.Collection[0].Size; //Ottengo il numero di frame int NumeroFrame = ic.Count; //Calcolo le righe int Righe = (int)Math.Ceiling(NumeroFrame / (float)Colonne); //Calcolo grandezza immagine finale Size FinalSize = new Size(Colonne * OriginalSize.Width, Righe * OriginalSize.Height); Bitmap b = new Bitmap(FinalSize.Width, FinalSize.Height); Graphics g = Graphics.FromImage(b); int r = 0, c = 0; int current = 0; foreach (Image i in ic.Collection) { ProgressChange?.Invoke(this, current++, NumeroFrame); //Calcolo il punto di inserimento del frame nell'immagine grande Point p = new Point(c * OriginalSize.Width, r * OriginalSize.Height); g.DrawImageUnscaled(i, p); c++; if (c >= Colonne) { c = 0; r++; } if (r >= Righe) { break; } } if (FormatoOutput == FormatoOut.jpg) { b.Save(sw.BaseStream, ImageFormat.Jpeg); } else if (FormatoOutput == FormatoOut.png) { b.Save(sw.BaseStream, ImageFormat.Png); } else if (FormatoOutput == FormatoOut.bmp) { b.Save(sw.BaseStream, ImageFormat.Bmp); } g.Dispose(); b.Dispose(); StateChange?.Invoke(this, State.Finish); }
public void Report(double newProgress) { ProgressChange?.Invoke(this, new ProgressEventArgs(newProgress)); }
private void PatchFile(string idxPath, string mulPath, string newIdxPath, string newMulPath, List <Patch> patches) { if (StatusChange != null) { StatusChange(this, new StatusChangeEventArgs(String.Format("Creating temp mul/idx file(s)..."))); } File.Copy(idxPath, newIdxPath, true); File.Copy(mulPath, newMulPath, true); if (StatusChange != null) { StatusChange(this, new StatusChangeEventArgs(String.Format("Applying {0} patches to {1}...", patches.Count, Path.GetFileName(newMulPath)))); } FileInfo idxFileInfo = new FileInfo(newIdxPath); FileIndex index = new FileIndex(Path.GetFileName(idxPath), Path.GetFileName(mulPath), (int)(idxFileInfo.Length / 12)); BinaryWriter idx = new BinaryWriter(new FileStream(newIdxPath, FileMode.Open)); BinaryWriter mul = new BinaryWriter(new FileStream(newMulPath, FileMode.Open)); int oldPercent = 0; for (int p = 0; p < patches.Count; p++) { Patch patch = patches[p]; int a = 0; if (patch.BlockID == 0xEEEE) { a = 4; } /* * int pos; * * if (index[patch.BlockID].length > patch.Length) * pos = index[patch.BlockID].lookup; * else */int pos = Convert.ToInt32(mul.BaseStream.Length); idx.Seek(patch.BlockID * 12, SeekOrigin.Begin); idx.Write(pos); idx.Write(patch.Length); idx.Write(patch.Extra); if (patch.Length >= 0) { mul.Seek(pos, SeekOrigin.Begin); mul.Write(patch.Data, 0, patch.Length); } if (p != 0 && ProgressChange != null) { int percent = (p * 100) / patches.Count; if (percent != oldPercent) { ProgressChange.Invoke(this, new ProgressChangeEventArgs(percent, p, patches.Count)); oldPercent = percent; } } } index.Close(); if (idx != null) { idx.Close(); } if (mul != null) { mul.Close(); } if (StatusChange != null) { StatusChange(this, new StatusChangeEventArgs(String.Format("Moving temp mul/idx file(s)..."))); } if (File.Exists(newIdxPath.Substring(0, newIdxPath.Length - 4))) { File.Delete(newIdxPath.Substring(0, newIdxPath.Length - 4)); } File.Move(newIdxPath, newIdxPath.Substring(0, newIdxPath.Length - 4)); if (File.Exists(newMulPath.Substring(0, newMulPath.Length - 4))) { File.Delete(newMulPath.Substring(0, newMulPath.Length - 4)); } File.Move(newMulPath, newMulPath.Substring(0, newMulPath.Length - 4)); if (this.StatusChange != null) { this.StatusChange(this, new StatusChangeEventArgs(string.Format("Cleaning up...", new object[0]))); } File.Delete(newIdxPath); File.Delete(newMulPath); #region Meh for now /* * if (StatusChange != null) * StatusChange(this, new StatusChangeEventArgs(String.Format("Creating temp mul/idx file(s)..."))); * * FileInfo info = new FileInfo(idxPath); * FileIndex oldIndex = new FileIndex(Path.GetFileName(idxPath), Path.GetFileName(mulPath), (int)(info.Length / ((long)12))); * * BinaryWriter idx = new BinaryWriter(new FileStream(newIdxPath, FileMode.Create)); * idx.Seek((int)new FileInfo(idxPath).Length, SeekOrigin.Begin); * * BinaryWriter mul = new BinaryWriter(new FileStream(newMulPath, FileMode.Create)); * mul.Seek((int)new FileInfo(mulPath).Length, SeekOrigin.Begin); * * idx.Seek(0, SeekOrigin.Begin); * mul.Seek(0, SeekOrigin.Begin); * * if (StatusChange != null) * StatusChange(this, new StatusChangeEventArgs(String.Format("Applying {0} patches to {1}...", patches.Count, Path.GetFileName(newMulPath)))); * * int patchIndex = 0; * int oldPercent = 0; * * int offset = 0; * * for (int i = 0; i < oldIndex.IndexCount; i++) * { * if (patchIndex < patches.Count && patches[patchIndex].BlockID == i)//Write the patch * { * if (StatusChange != null) * StatusChange(this, new StatusChangeEventArgs(String.Format("Applying patch id: {0}...", i))); * * Patch patch = patches[patchIndex]; * * idx.Write((int)mul.BaseStream.Position); * idx.Write(patch.Length); * idx.Write(patch.Extra); * * if (patch.Length > 0) * mul.Write(patch.Data, 0, patch.Length); * * patchIndex++; * } * else//Write the regular data * { * if (StatusChange != null && (i % 200 == 0)) * StatusChange(this, new StatusChangeEventArgs(String.Format("Writing index: {0}...", i))); * * idx.Write((int)mul.BaseStream.Position); * idx.Write(oldIndex[i].length); * idx.Write(oldIndex[i].extra); * * if (oldIndex[i].length > 0) * { * BinaryReader reader = new BinaryReader(oldIndex.Seek(i)); * mul.Write(reader.ReadBytes(oldIndex[i].length), 0, oldIndex[i].length); * } * } * * if (i != 0 && ProgressChange != null) * { * int percent = (i * 100) / oldIndex.IndexCount; * * if (percent != oldPercent) * { * ProgressChange(this, new ProgressChangeEventArgs(percent, i, oldIndex.IndexCount)); * oldPercent = percent; * } * } * } * * //Patches out of idx range? Is this possible? * if (patchIndex < patches.Count - 1) * { * if (StatusChange != null) * StatusChange(this, new StatusChangeEventArgs(String.Format("Applying left over patches..."))); * * int count = (patches.Count - 1) - patchIndex; * int i = 0; * while (i < count) * { * if (StatusChange != null) * StatusChange(this, new StatusChangeEventArgs(String.Format("Applying patch id: {0}...", i))); * * Patch patch = patches[patchIndex]; * * idx.Write((int)mul.BaseStream.Position); * idx.Write(patch.Length); * idx.Write(patch.Extra); * * if (patch.Length >= 0) * mul.Write(patch.Data, 0, patch.Length); * * if (i != 0 && ProgressChange != null) * { * int percent = (i * 100) / count; * * if (percent != oldPercent) * { * ProgressChange(this, new ProgressChangeEventArgs(percent, i, count)); * oldPercent = percent; * } * } * * patchIndex++; * i++; * } * } * * oldIndex.Close(); * * if (idx != null) * idx.Close(); * if (mul != null) * mul.Close(); * * if (StatusChange != null) * StatusChange(this, new StatusChangeEventArgs(String.Format("Moving temp mul/idx file(s)..."))); * * if (File.Exists(newIdxPath.Substring(0, newIdxPath.Length - 4))) * File.Delete(newIdxPath.Substring(0, newIdxPath.Length - 4)); * * File.Move(newIdxPath, newIdxPath.Substring(0, newIdxPath.Length - 4)); * * if (File.Exists(newMulPath.Substring(0, newMulPath.Length - 4))) * File.Delete(newMulPath.Substring(0, newMulPath.Length - 4)); * * File.Move(newMulPath, newMulPath.Substring(0, newMulPath.Length - 4)); * * if (this.StatusChange != null) * this.StatusChange(this, new StatusChangeEventArgs(string.Format("Cleaning up...", new object[0]))); * * File.Delete(newIdxPath); * File.Delete(newMulPath);*/ #endregion }
/// <inheritdoc /> public PackingResult PlaceRects(int width, int height, IEnumerable <PPRect> rects, CancellationToken token = default) { Progress = 0; if (width < 0 || height < 0) { throw new ArgumentOutOfRangeException($"The {nameof(width)} and {nameof(height)} should be non-negative"); } var sortedInput = sorter.SortImages(rects); int inputSize = rects.Count(); int placedRects = 0; int actualWidth = 0; int actualHeight = 0; RectComparer rectComparer = new RectComparer(); PointComparer ptComparer = new PointComparer(); SortedSet <PPRect> currentPacking = new SortedSet <PPRect>(rectComparer); SortedDictionary <SKPointI, int> pointsToTry = new SortedDictionary <SKPointI, int>(ptComparer) { { new SKPointI(0, 0), -1 } //the current packing is empty, so only point to try is point [0,0] }; SKPointI[] pointsToAdd = new SKPointI[2]; foreach (var x in sortedInput) { if (token.IsCancellationRequested) { Progress = 0; return(null); } SKPointI?pointToRemove = null; foreach (var ptToTry in pointsToTry) { PPRect tested = new PPRect(ptToTry.Key.X, ptToTry.Key.Y, ptToTry.Key.X + x.Width, ptToTry.Key.Y + x.Height); var possibleIntersections = currentPacking.AsEnumerable(); //have to test everything if (ptToTry.Key.X + x.Width <= width && ptToTry.Key.Y + x.Height <= height && !Intersects(tested, possibleIntersections)) //safe to pack here { if (ptToTry.Key.X + x.Width > actualWidth) { actualWidth = ptToTry.Key.X + x.Width; } if (ptToTry.Key.Y + x.Height > actualHeight) { actualHeight = ptToTry.Key.Y + x.Height; } int improved = 0; if (TryImprove(ref tested, currentPacking, 0)) //Try to position it further to the top / left { improved++; } //Add it to the packing tested.Image = x.Image; currentPacking.Add(tested); if (improved == 0) { pointToRemove = ptToTry.Key; } pointsToAdd[0] = new SKPointI(ptToTry.Key.X + x.Width, ptToTry.Key.Y); pointsToAdd[1] = new SKPointI(ptToTry.Key.X, ptToTry.Key.Y + x.Height); break; } } if (pointToRemove != null) { pointsToTry.Remove(pointToRemove.Value); pointsToTry[pointsToAdd[0]] = -1; pointsToTry[pointsToAdd[1]] = -1; Progress = (int)((++placedRects / (double)inputSize) * 100.0); ProgressChange?.Invoke(this, Progress); } else { Progress = 100; return(null); //we cannot pack it anywhere } } //var result = new PackingResult(width, height, currentPacking.Select(x => (x.Value, x.Key))); // probably better to return result with actual width & height instead of those needed //actual height can be lower than height specified, width also BUT THIS IS NOT DESIRED, BECAUSE THIS CAN BE CALLED FROM FIXEDSIZE..? OR chhange size in FixedSize.. var result = new PackingResult(actualWidth, actualHeight, currentPacking); return(result); }