private bool TestPackingImages(int testWidth, int testHeight, Dictionary <string, Rect> testImagePlacement) { // System.Diagnostics.Stopwatch st = new System.Diagnostics.Stopwatch(); // st.Start(); // create the Rect packer ArevaloRectanglePacker RectPacker = new ArevaloRectanglePacker(testWidth, testHeight); foreach (var image in filesBMP) { // get the MCBitmap for this file MCSize size = imageSizes[image.Name.ToString()]; // pack the image Vector2 origin; if (!RectPacker.TryPack(size.Width + padding, size.Height + padding, out origin)) { // MechCommanderUnity.MechCommanderUnity.LogMessage("FAlsePAck"); return(false); } if (!testImagePlacement.ContainsKey(image.Name.ToString())) { // add the destination Rect to our dictionary testImagePlacement.Add(image.Name.ToString(), new Rect(origin.x, origin.y, size.Width + padding, size.Height + padding)); } else { // add the destination Rect to our dictionary testImagePlacement.Add(image.Name.ToString() + "_", new Rect(origin.x, origin.y, size.Width + padding, size.Height + padding)); } } // st.Stop(); // MechCommanderUnity.MechCommanderUnity.LogMessage("TestPacking elapsed: ("+filesBMP.Count+") ->" +(st.ElapsedMilliseconds/1000) +"s"); return(true); }
/// <summary> /// Packs a collection of images into a single image. /// </summary> /// <param name="imageFiles">The list of file paths of the images to be combined.</param> /// <param name="requirePowerOfTwo">Whether or not the output image must have a power of two size.</param> /// <param name="requireSquareImage">Whether or not the output image must be a square.</param> /// <param name="maximumWidth">The maximum width of the output image.</param> /// <param name="maximumHeight">The maximum height of the output image.</param> /// <param name="imagePadding">The amount of blank space to insert in between individual images.</param> /// <param name="generateMap">Whether or not to generate the map dictionary.</param> /// <param name="outputImage">The resulting output image.</param> /// <param name="outputMap">The resulting output map of placement Rects for the images.</param> /// <returns>0 if the packing was successful, error code otherwise.</returns> //public int PackImage( // IEnumerable<string> imageFiles, // bool requirePowerOfTwo, // bool requireSquareImage, // int maximumWidth, // int maximumHeight, // int imagePadding, // bool generateMap, // out MCBitmap outputImage, // out Dictionary<string, Rect> outputMap) //{ // files = new List<string>(imageFiles); // requirePow2 = requirePowerOfTwo; // requireSquare = requireSquareImage; // outputWidth = maximumWidth; // outputHeight = maximumHeight; // padding = imagePadding; // outputImage = null; // outputMap = null; // // make sure our dictionaries are cleared before starting // imageSizes.Clear(); // imagePlacement.Clear(); // // get the sizes of all the images // foreach (var image in files) // { // MCBitmap MCBitmap = MCBitmap.FromFile(image) as MCBitmap; // if (MCBitmap == null) // return (int)FailCode.FailedToLoadImage; // imageSizes.Add(image, MCBitmap.Size); // } // // sort our files by file size so we place large sprites first // files.Sort( // (f1, f2) => // { // Size b1 = imageSizes[f1]; // Size b2 = imageSizes[f2]; // int c = -b1.Width.CompareTo(b2.Width); // if (c != 0) // return c; // c = -b1.Height.CompareTo(b2.Height); // if (c != 0) // return c; // return f1.CompareTo(f2); // }); // // try to pack the images // if (!PackImageRects()) // return (int)FailCode.FailedToPackImage; // // make our output image // outputImage = CreateOutputImage(); // if (outputImage == null) // return (int)FailCode.FailedToSaveImage; // if (generateMap) // { // // go through our image placements and replace the width/height found in there with // // each image's actual width/height (since the ones in imagePlacement will have padding) // string[] keys = new string[imagePlacement.Keys.Count]; // imagePlacement.Keys.CopyTo(keys, 0); // foreach (var k in keys) // { // // get the actual size // Size s = imageSizes[k]; // // get the placement Rect // Rect r = imagePlacement[k]; // // set the proper size // r.Width = s.Width; // r.Height = s.Height; // // insert back into the dictionary // imagePlacement[k] = r; // } // // copy the placement dictionary to the output // outputMap = new Dictionary<string, Rect>(); // foreach (var pair in imagePlacement) // { // outputMap.Add(pair.Key, pair.Value); // } // } // // clear our dictionaries just to free up some memory // imageSizes.Clear(); // imagePlacement.Clear(); // return 0; //} /// <summary> /// Packs a collection of images into a single image. /// </summary> /// <param name="imageFiles">The list of file paths of the images to be combined.</param> /// <param name="requirePowerOfTwo">Whether or not the output image must have a power of two size.</param> /// <param name="requireSquareImage">Whether or not the output image must be a square.</param> /// <param name="maximumWidth">The maximum width of the output image.</param> /// <param name="maximumHeight">The maximum height of the output image.</param> /// <param name="imagePadding">The amount of blank space to insert in between individual images.</param> /// <param name="generateMap">Whether or not to generate the map dictionary.</param> /// <param name="outputImage">The resulting output image.</param> /// <param name="outputMap">The resulting output map of placement Rects for the images.</param> /// <returns>0 if the packing was successful, error code otherwise.</returns> public int PackImage( IEnumerable <MCBitmap> imageFiles, bool requirePowerOfTwo, bool requireSquareImage, int maximumWidth, int maximumHeight, int imagePadding, bool orderByImageSize, bool generateMap, out MCBitmap outputImage, out Dictionary <string, Rect> outputMap) { filesBMP = new List <MCBitmap>(imageFiles); requirePow2 = requirePowerOfTwo; requireSquare = requireSquareImage; outputWidth = maximumWidth; outputHeight = maximumHeight; padding = imagePadding; outputImage = null; outputMap = null; // make sure our dictionaries are cleared before starting imageSizes.Clear(); imagePlacement.Clear(); // get the sizes of all the images foreach (var image in filesBMP) { MCBitmap MCBitmap = image; if (MCBitmap == null) { return((int)FailCode.FailedToLoadImage); } if (!imageSizes.ContainsKey(image.Name.ToString())) { imageSizes.Add(image.Name.ToString(), MCBitmap.Size); } else { imageSizes.Add(image.Name.ToString() + "_", MCBitmap.Size); } } if (orderByImageSize) { filesBMP.Sort( (f1, f2) => { var b1 = imageSizes[f1.Name]; var b2 = imageSizes[f2.Name]; int c = -b1.Width.CompareTo(b2.Width); if (c != 0) { return(c); } c = -b1.Height.CompareTo(b2.Height); if (c != 0) { return(c); } return(f1.Name.CompareTo(f2.Name)); }); } // MechCommanderUnity.MechCommanderUnity.LogMessage("Create Atlas - AfterSizes , Number: " + imageSizes.Count +" orig:"+filesBMP.Count); // try to pack the images if (!PackImageRects()) { return((int)FailCode.FailedToPackImage); } // MechCommanderUnity.MechCommanderUnity.LogMessage("Create Atlas - AfterPack"); // make our output image outputImage = CreateOutputImage(); if (outputImage == null) { return((int)FailCode.FailedToSaveImage); } if (generateMap) { // go through our image placements and replace the width/height found in there with // each image's actual width/height (since the ones in imagePlacement will have padding) string[] keys = new string[imagePlacement.Keys.Count]; imagePlacement.Keys.CopyTo(keys, 0); foreach (var k in keys) { // get the actual size MCSize s = imageSizes[k]; // get the placement Rect Rect r = imagePlacement[k]; // set the proper size r.width = s.Width; r.height = s.Height; // insert back into the dictionary imagePlacement[k] = r; } // copy the placement dictionary to the output outputMap = new Dictionary <string, Rect>(); foreach (var pair in imagePlacement) { outputMap.Add(pair.Key, pair.Value); } } // clear our dictionaries just to free up some memory imageSizes.Clear(); imagePlacement.Clear(); return(0); }