Пример #1
0
        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);
        }
Пример #2
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<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);
        }