public void MoveRange(int startIndex, int count, int newStartIndex) { PropList temp = new PropList(); for (int i = 0; i < count; i++) { temp.Add(this._colors.GetKey(startIndex), this._colors.GetByIndex(startIndex)); this._colors.RemoveAt(startIndex); } if (newStartIndex > startIndex) { newStartIndex -= count; } for (int i = 0; i < count; i++) { this._colors.Insert(newStartIndex, temp.GetKey(i), temp.GetByIndex(i)); } }
public static void TreePack(Size textureSize, string[] filenames, string outputFilename) { System.Drawing.Image[] images = new Image[filenames.Length]; // for (int i=0; i<filenames.Length; i++) // { // files[i] = new System.IO.FileInfo(filenames[i]); // images[i] = System.Drawing.Bitmap.FromFile(filenames[i]); // } // ERectangle[] rects; // EPoint[] offsets; // Bitmap bmp = TreePack(images, out rects, out offsets); // bmp.Save(outputFilename); EPoint[] offsets = new EPoint[filenames.Length]; System.IO.FileInfo[] files = new System.IO.FileInfo[filenames.Length]; PropList originalOrder = new PropList(); for (int i = 0; i < filenames.Length; i++) { files[i] = new System.IO.FileInfo(filenames[i]); images[i] = System.Drawing.Bitmap.FromFile(filenames[i]); EPoint pntMid = new EPoint(images[i].Width, images[i].Height) / 2; EPoint pnt = new EPoint(); images[i] = Endogine.BitmapHelpers.BitmapHelper.TrimWhitespace((Bitmap)images[i], out pnt); offsets[i] = pntMid - pnt + new EPoint(1, 1); originalOrder.Add(filenames[i], images[i]); } Image[] unpacked = null; int numPixelsMinimum; Size maxWnH, minWnH; GetImagesStatistics(images, out numPixelsMinimum, out maxWnH, out minWnH); if (textureSize.Width == 0 || textureSize.Height == 0) { int side = (int)Math.Sqrt(numPixelsMinimum); int asdas = (int)Math.Ceiling(Math.Log(side, 2)); textureSize = new Size(side, side); } if (numPixelsMinimum >= textureSize.Width * textureSize.Height) { throw new Exception("Not enough space to pack in"); } images = Endogine.BitmapHelpers.TexturePacking.SortImagesBySize(images); Random rnd = new Random(); int nNumTries = 1; for (int i = 0; i < nNumTries; i++) { //Irritating, but since we can't find index of an item in a standard array...: ArrayList aImagesNewOrder = new ArrayList(); foreach (Image image in images) { aImagesNewOrder.Add(image); } EPoint[] locsInTexture = null; Bitmap bmp = Endogine.BitmapHelpers.TexturePacking.TreePack(textureSize, images, out unpacked, out locsInTexture); int areaExcluded = Endogine.BitmapHelpers.TexturePacking.GetTotalArea(unpacked); if (unpacked.Length > 0) { throw new Exception("Couldn't fit all images. Total pixels excluded = " + areaExcluded.ToString() + " (side = " + ((int)Math.Sqrt(areaExcluded)).ToString() + ")"); } ArrayList aUnpacked = new ArrayList(); foreach (Image image in unpacked) { aUnpacked.Add(image); } int areaUnused = 0; foreach (Image image in images) { if (!aUnpacked.Contains(image)) { areaUnused += image.Size.Width * image.Size.Height; } } if (areaUnused > textureSize.Width * textureSize.Height / 2) { //TODO: we could maybe make the texture at least half as big } Node infoNode = new Node(); infoNode = infoNode.CreateChild("Files"); //TODO: go by the list of images that was actually used! for (int orgIndex = 0; orgIndex < originalOrder.Count; orgIndex++) { Image image = (Image)originalOrder.GetByIndex(orgIndex); if (aUnpacked.Contains(image)) { continue; } int newIndex = aImagesNewOrder.IndexOf(image); //create the file entry (File, Rect, Offset) ERectangle rctInTexture = new ERectangle( locsInTexture[newIndex].X, locsInTexture[newIndex].Y, image.Width, image.Height); Node frameNode = infoNode.CreateChild("File"); //remove extension from filename: frameNode.Value = files[orgIndex].Name.Substring(0, files[orgIndex].Name.LastIndexOf(files[orgIndex].Extension)); //frameNode.Value = files[orgIndex].Name; Node subNode = frameNode.CreateChild("Rect"); subNode.Value = rctInTexture.ToString(); subNode = frameNode.CreateChild("Offset"); subNode.Value = offsets[orgIndex].ToString(); } System.Xml.XmlDocument doc = infoNode.RootNode.CreateXmlDocument(); string sOut = null; if (nNumTries > 1) { sOut = outputFilename + areaExcluded.ToString() + "-" + i.ToString(); } else { sOut = outputFilename; } doc.Save(sOut + ".xml"); bmp.Save(sOut + ".png"); //randomize order to see if we get better results: ArrayList aImages = new ArrayList(); for (int j = 0; j < images.Length; j++) { aImages.Add(images[j]); } Image[] randomOrder = new Image[images.Length]; for (int j = images.Length - 1; j >= 0; j--) { int pos = 0; if (j > 0) { pos = Math.Min(rnd.Next(j), j - 1); } randomOrder[j] = (Image)aImages[pos]; aImages.RemoveAt(pos); } images = randomOrder; } }
public static void TreePack(Size textureSize, string[] filenames, string outputFilename) { System.Drawing.Image[] images = new Image[filenames.Length]; // for (int i=0; i<filenames.Length; i++) // { // files[i] = new System.IO.FileInfo(filenames[i]); // images[i] = System.Drawing.Bitmap.FromFile(filenames[i]); // } // ERectangle[] rects; // EPoint[] offsets; // Bitmap bmp = TreePack(images, out rects, out offsets); // bmp.Save(outputFilename); EPoint[] offsets = new EPoint[filenames.Length]; System.IO.FileInfo[] files = new System.IO.FileInfo[filenames.Length]; PropList originalOrder = new PropList(); for (int i=0; i<filenames.Length; i++) { files[i] = new System.IO.FileInfo(filenames[i]); images[i] = System.Drawing.Bitmap.FromFile(filenames[i]); EPoint pntMid = new EPoint(images[i].Width, images[i].Height)/2; EPoint pnt = new EPoint(); images[i] = Endogine.BitmapHelpers.BitmapHelper.TrimWhitespace((Bitmap)images[i], out pnt); offsets[i] = pntMid - pnt + new EPoint(1,1); originalOrder.Add(filenames[i], images[i]); } Image[] unpacked = null; int numPixelsMinimum; Size maxWnH, minWnH; GetImagesStatistics(images, out numPixelsMinimum, out maxWnH, out minWnH); if (textureSize.Width == 0 || textureSize.Height == 0) { int side = (int)Math.Sqrt(numPixelsMinimum); int asdas = (int)Math.Ceiling(Math.Log(side, 2)); textureSize = new Size(side,side); } if (numPixelsMinimum >= textureSize.Width*textureSize.Height) throw new Exception("Not enough space to pack in"); images = Endogine.BitmapHelpers.TexturePacking.SortImagesBySize(images); Random rnd = new Random(); int nNumTries = 1; for (int i=0; i<nNumTries; i++) { //Irritating, but since we can't find index of an item in a standard array...: ArrayList aImagesNewOrder = new ArrayList(); foreach (Image image in images) aImagesNewOrder.Add(image); EPoint[] locsInTexture = null; Bitmap bmp = Endogine.BitmapHelpers.TexturePacking.TreePack(textureSize, images, out unpacked, out locsInTexture); int areaExcluded = Endogine.BitmapHelpers.TexturePacking.GetTotalArea(unpacked); if (unpacked.Length > 0) throw new Exception("Couldn't fit all images. Total pixels excluded = "+areaExcluded.ToString() + " (side = "+((int)Math.Sqrt(areaExcluded)).ToString()+")"); ArrayList aUnpacked = new ArrayList(); foreach (Image image in unpacked) aUnpacked.Add(image); int areaUnused = 0; foreach (Image image in images) { if (!aUnpacked.Contains(image)) areaUnused+=image.Size.Width*image.Size.Height; } if (areaUnused > textureSize.Width*textureSize.Height/2) { //TODO: we could maybe make the texture at least half as big } Node infoNode = new Node(); infoNode = infoNode.CreateChild("Files"); //TODO: go by the list of images that was actually used! for (int orgIndex = 0; orgIndex<originalOrder.Count; orgIndex++) { Image image = (Image)originalOrder.GetByIndex(orgIndex); if (aUnpacked.Contains(image)) continue; int newIndex = aImagesNewOrder.IndexOf(image); //create the file entry (File, Rect, Offset) ERectangle rctInTexture = new ERectangle( locsInTexture[newIndex].X, locsInTexture[newIndex].Y, image.Width, image.Height); Node frameNode = infoNode.CreateChild("File"); //remove extension from filename: frameNode.Value = files[orgIndex].Name.Substring(0,files[orgIndex].Name.LastIndexOf(files[orgIndex].Extension)); //frameNode.Value = files[orgIndex].Name; Node subNode = frameNode.CreateChild("Rect"); subNode.Value = rctInTexture.ToString(); subNode = frameNode.CreateChild("Offset"); subNode.Value = offsets[orgIndex].ToString(); } System.Xml.XmlDocument doc = infoNode.RootNode.CreateXmlDocument(); string sOut = null; if (nNumTries > 1) sOut = outputFilename+areaExcluded.ToString()+"-"+i.ToString(); else sOut = outputFilename; doc.Save(sOut+".xml"); bmp.Save(sOut+".png"); //randomize order to see if we get better results: ArrayList aImages = new ArrayList(); for (int j=0; j<images.Length;j++) aImages.Add(images[j]); Image[] randomOrder = new Image[images.Length]; for (int j=images.Length-1;j>=0;j--) { int pos = 0; if (j > 0) pos = Math.Min(rnd.Next(j), j-1); randomOrder[j] = (Image)aImages[pos]; aImages.RemoveAt(pos); } images = randomOrder; } }