public void TestBarelyFittingRectangle() {
      ArevaloRectanglePacker packer = new ArevaloRectanglePacker(128, 128);

      Point placement = packer.Pack(128, 128);

      Assert.AreEqual(new Point(0, 0), placement);
    }
    public void TestTooLargeRectangle() {
      ArevaloRectanglePacker packer = new ArevaloRectanglePacker(128, 128);
      Point placement;

      bool result = packer.TryPack(129, 10, out placement);
      Assert.IsFalse(result);

      result = packer.TryPack(10, 129, out placement);
      Assert.IsFalse(result);
    }
Example #3
0
        private bool TestPackingImages(int testWidth, int testHeight, Dictionary<string, Microsoft.Xna.Framework.Rectangle> testImagePlacement)
        {
            // create the rectangle packer
            ArevaloRectanglePacker rectanglePacker = new ArevaloRectanglePacker(testWidth, testHeight);

            foreach (var image in files)
            {
                // get the bitmap for this file
                Size size = imageSizes[System.IO.Path.GetFileNameWithoutExtension(image)];

                // pack the image
                Point origin;
                if (!rectanglePacker.TryPack(size.Width + padding, size.Height + padding, out origin))
                {
                    return false;
                }

                // add the destination rectangle to our dictionary
                testImagePlacement.Add(System.IO.Path.GetFileNameWithoutExtension(image), new Microsoft.Xna.Framework.Rectangle(origin.X, origin.Y, size.Width + padding, size.Height + padding));
            }

            return true;
        }
Example #4
0
		/// <summary>
		/// Collect information about the images and bin pack them using the chosen algorithm
		/// </summary>
		/// <param name="imagesInfo"></param>
		/// <param name="spriteSize"></param>
		public void GetImagesInfo(out List<SpriteImageItem> imagesInfo, out Size spriteSize, int padding)
		{
			imagesInfo = new List<SpriteImageItem>();

			// calculate initial sprite size to optimize process speed
			//	-> make sure that the widest and the tallest images fit
			//	-> make sure the resulting area is the same as the sum of all images area
			int maxW = 0;
			int maxH = 0;
			//int totalArea = 0;
			foreach (var file in GetFiles())
			{
				var image = Image.FromFile(file.FullName);
				imagesInfo.Add(new SpriteImageItem() { Image = image, Name = file.Name });

				if (image.Width > maxW)
					maxW = image.Width;
				if (image.Height > maxH)
					maxH = image.Height;

				//totalArea = image.Width * image.Height;
			}

			int finalW = 0;
			int finalH = 0;

			//int totalW = (int)Math.Ceiling((decimal)totalArea / 2);
			//int totalH = totalW;

			finalW = maxW;// maxW > totalW ? maxW : totalW;
			finalH = maxH; // maxH > totalH ? maxH : totalH;

			List<SpriteImageItem> unfitImagesInfo = new List<SpriteImageItem>();
			bool finished = false;
			while (!finished)
			{
				// start packing process
				RectanglePacker packer = null;
				switch (this.Options.BinPackingLevel)
				{
					case 1:		// faster and less compless algorithm
						packer = new SimpleRectanglePacker(finalW, finalH);
						break;
					case 2:		// still fast and much better packing algorithm
						packer = new CygonRectanglePacker(finalW, finalH);
						break;
					case 3:		// the best packing algorithm. Addicional processing time might not be noticeable
						packer = new ArevaloRectanglePacker(finalW, finalH);
						break;
					default:	// default
						packer = new CygonRectanglePacker(finalW, finalH);
						break;
				}

				//var usedArea = 0;
				foreach (var iInfo in imagesInfo)
				{
					// Find a place for a rectangle of size 30x20 in the packing area
					Point placement;
                    if (packer.TryPack(iInfo.Image.Width + padding, iInfo.Image.Height + padding, out placement))
					{
						iInfo.Position = placement;
						//usedArea += iInfo.Image.Width * iInfo.Image.Height;
					}
					else
					{
						unfitImagesInfo.Add(iInfo);
					}
				}

				if (unfitImagesInfo.Count == 0)
				{
					finished = true;
				}
				else
				{
					// add the diff between the used area and the remaining images area
					//var extraW = 0;
					//var extraH = 0;
					//foreach (var unfit in unfitImagesInfo)
					//{
					//    extraW += unfit.Image.Width;
					//    extraH += unfit.Image.Height;
					//}

					// after some tests the speed and result are quite the same as adding a few more pixels to the 
					//	sprite final size and run the whole process again
					finalW += 10;
					finalH += 10;

					unfitImagesInfo.Clear();
				}
			}

			spriteSize = new Size(finalW, finalH);
		}
Example #5
0
        private bool TestPackingImages(int testWidth, int testHeight, Lexicon<string, Rectangle> testImagePlacement)
        {
            // create the rectangle packer
            ArevaloRectanglePacker rectanglePacker = new ArevaloRectanglePacker(testWidth, testHeight);

            foreach (var image in files)
            {
                // get the bitmap for this file
                Size size = imageSizes[image.Key][0];

                // pack the image
                Point origin;
                if (!rectanglePacker.TryPack(size.Width + padding, size.Height + padding, out origin))
                {
                    return false;
                }

                // add the destination rectangle to our dictionary
                testImagePlacement.Add(image.Key, new Rectangle(origin.X, origin.Y, size.Width + padding, size.Height + padding));
            }

            return true;
        }
Example #6
0
        //贴图装箱算法
        public static IList<TexturePacket> PacketTexture(GraphicsDevice gdevice,IDictionary<string,Texture2D> sources)
        {
            List<TexturePacket> list = new List<TexturePacket>();

            int packetsize = 512;
            RectanglePacker packer = new ArevaloRectanglePacker(packetsize, packetsize);
            Texture2D tex = new Texture2D(gdevice, packer.PackingAreaWidth, packer.PackingAreaHeight, false, SurfaceFormat.Color);
            Dictionary<string, RectangleF> rects = new Dictionary<string, RectangleF>();
            foreach (var i in sources)
            {
               UInt32[] data=new UInt32[i.Value.Width*i.Value.Height];
               i.Value.GetData<UInt32>(data);
               int twidth = i.Value.Width;
               int theight = i.Value.Height;
                bool bfixx=false;
                bool bfixy = false;
                if((twidth== packetsize/2||twidth==packetsize/4))
                {
                }
                else
                {
                    bfixx=true;
                    twidth+=2;
                }
                if (theight==packetsize/2||theight==packetsize/4)
                {

                }
                else
                {
                    theight += 2;
                    bfixy = true;
                }
                Point pos;

                if (packer.TryPack(twidth, theight, out pos))
                {
                    //right
                }
                else
                {
                    TexturePacket p = new TexturePacket(tex, rects);
                    list.Add(p);
                    packer = new ArevaloRectanglePacker(packetsize, packetsize);
                    tex = new Texture2D(gdevice, packer.PackingAreaWidth, packer.PackingAreaHeight, false, SurfaceFormat.Color);
                    rects = new Dictionary<string, RectangleF>();

                    packer.TryPack(i.Value.Width, i.Value.Height, out pos);
                }
                if (bfixx) pos.X += 1;
                if(bfixy)    pos.Y+=1;

                tex.SetData<UInt32>(0, new Rectangle(pos.X, pos.Y, i.Value.Width, i.Value.Height), data, 0, data.Length);
                rects.Add(i.Key, new RectangleF(
                    (float)(pos.X) / (float)packer.PackingAreaWidth,
                    (float)(pos.Y) / (float)packer.PackingAreaHeight,
                    (float)i.Value.Width / (float)packer.PackingAreaWidth,
                    (float)i.Value.Height / (float)packer.PackingAreaHeight
                    ));
            }
            {
                TexturePacket p = new TexturePacket(tex, rects);
                list.Add(p);
            }
            return list;
        }
 public void TestThrowOnTooLargeRectangle() {
   ArevaloRectanglePacker packer = new ArevaloRectanglePacker(128, 128);
   Assert.Throws<OutOfSpaceException>(
     delegate() { packer.Pack(129, 129); }
   );
 }