Пример #1
0
 public Sprite()
 {
     Frame = new Frame();
     Partition = new RectPartition();
     Difference = false;
 }
Пример #2
0
        public void Read( Stream ins, String PackName )
        {
            if (ins.ReadByte() != (byte)'R' ) return;
            if (ins.ReadByte() != (byte)'B' ) return;
            if (ins.ReadByte() != (byte)'S' ) return;
            if (ins.ReadByte() != (byte)'P' ) return;

            int nSprites = ReadWord( ins );
            ReadDword( ins );
            ReadDword( ins );

            int firstSprite = Sprites.Count;

            //  read header
            for (int i = 0; i < nSprites; i++)
            {
                Sprite sp = new Sprite();
                sp.Width = ReadWord( ins );
                sp.Height = ReadWord( ins );
                sp.ClrFormat = (ColorFormat)ReadWord( ins );
                sp.Frame.x = ReadWord( ins );
                sp.Frame.y = ReadWord( ins );
                sp.Frame.w = ReadWord( ins );
                sp.Frame.h = ReadWord( ins );
                sp.Name    = PackName + i;
                int bFiltered = ReadWord( ins );
                if (bFiltered == 1) sp.Filtered = true; else sp.Filtered = false;
                int nRects = ReadWord( ins );
                sp.PivotX  = (short)ReadWord( ins );
                sp.PivotY  = (short)ReadWord( ins );
                sp.ShiftX  = (short)ReadWord( ins );
                sp.ShiftY  = (short)ReadWord( ins );

                for (int j = 0; j < nRects; j++)
                {
                    Frame rc = new Frame();
                    rc.x = ReadWord( ins );
                    rc.y = ReadWord( ins );
                    rc.w = ReadWord( ins );
                    rc.h = rc.w;
                    ReadWord( ins );
                    sp.Partition.Rects.Add( rc );
                }
                Sprites.Add( sp );
            }

            //  read pixels
            for (int i = firstSprite; i < Sprites.Count; i++)
            {
                Sprite sprite = (Sprite)Sprites[i];
                int nBytes = sprite.GetNumBytes();
                sprite.Bytes = new byte[nBytes];
                ins.Read( sprite.Bytes, 0, nBytes );
            }
        }
Пример #3
0
        bool Subdivide( Bitmap img, Frame rc )
        {
            if (rc.w <= MinQuadSide) return false;
            int hw = rc.w/2;
            int hh = rc.h/2;
            Frame[] subr = new Frame[4];
            int[]  nutl  = new int[4];
            subr[0] = new Frame( rc.x, rc.y, hw, hh );
            subr[1] = new Frame( rc.x + hw, rc.y, hw, hh );
            subr[2] = new Frame( rc.x, rc.y + hh, hw, hh );
            subr[3] = new Frame( rc.x + hw, rc.y + hh, hw, hh );

            int nPUsed = 0;
            for (int i = 0; i < 4; i++)
            {
                nutl[i] = GetUtilization( img, subr[i] );
                nPUsed += nutl[i];
            }

            float used = ((float)nPUsed)/(float)(rc.w*rc.w);
            if (used > SubdivUsedBias) return false;
            for (int i = 0; i < 4; i++)
            {
                if (nutl[i] > 0)
                {
                    Rects.Add( subr[i] );
                }
            }

            return true;
        }
Пример #4
0
        void CreatePartition( Bitmap bmp )
        {
            Partition     = new RectPartition( bmp, Filtered );
            Frame         = Partition.Frame;
            int numBytes  = Partition.GetNumPixels( Filtered )*GetBytesPerPixel( ClrFormat );

            //  get pixels
            Bytes = new byte[numBytes];
            int curByte = 0;
            for (int k = 0; k < Partition.Rects.Count; k++)
            {
                Frame rc = (Frame)Partition.Rects[k];
                int bX, bY, eX, eY;
                if (Filtered)
                {
                    bX = -1;
                    eX = rc.w + 1;
                    bY = -1;
                    eY = rc.h + 1;
                    if (rc.x + eX > Frame.x + Frame.w + 1) eX = Frame.x + Frame.w - rc.x + 1;
                    if (rc.y + eY > Frame.y + Frame.h + 1) eY = Frame.y + Frame.h - rc.y + 1;
                }
                else
                {
                    bX = 0;
                    eX = rc.w;
                    bY = 0;
                    eY = rc.h;
                    if (rc.x + eX > Frame.x + Frame.w) eX = Frame.x + Frame.w - rc.x;
                    if (rc.y + eY > Frame.y + Frame.h) eY = Frame.y + Frame.h - rc.y;
                }

                for (int j = bY; j < eY; j++)
                {
                    for (int i = bX; i < eX; i++)
                    {
                        Color clr = GetPixel( bmp, rc.x + i, rc.y + j );
                        curByte += AddColor( ref Bytes, curByte, clr, ClrFormat );
                    }
                }
            }
        }
Пример #5
0
 void CreateUnfiltered( Bitmap img )
 {
     Frame = TrimBitmap( img );
     int side = GetCoverSide( Frame, 0 );
     CreateUniform( img, side );
     bool bWasDivided = true;
     while (bWasDivided)
     {
         bWasDivided = false;
         for (int i = 0; i < Rects.Count; i++)
         {
             Frame r = (Frame)Rects[i];
             bool bSubd = Subdivide( img, r );
             if (bSubd)
             {
                 bWasDivided = true;
                 Rects.RemoveAt( i );
                 break;
             }
         }
     }
 }
Пример #6
0
 float CreateUniform( Bitmap img, int side )
 {
     Frame rc = TrimBitmap( img );
     int nAllPix = 0;
     int nPix = 0;
     int nx = rc.w/side + 1;
     int ny = rc.h/side + 1;
     Rects.Clear();
     for (int j = 0; j < ny; j++)
     {
         for (int i = 0; i < nx; i++)
         {
             Frame crc = new Frame( rc.x + i*side, rc.y + j*side, side, side );
             nAllPix += side*side;
             int np = GetUtilization( img, crc );
             if (np == 0) continue;
             nPix += np;
             Rects.Add( crc );
         }
     }
     return ((float)nPix)/((float)nAllPix);
 }
Пример #7
0
 void CreateFiltered( Bitmap img )
 {
     Frame = TrimBitmap( img );
     int side = GetCoverSide( Frame, 1 );
     CreateUniform( img, side - 2 );
     while (GetUtilization( img ) < SubdivUsedBias &&
             Rects.Count > 0 &&
             ((Frame)Rects[0]).w > MinQuadSide)
     {
         side /= 2;
         CreateUniform( img, side - 2 );
     }
 }
Пример #8
0
        static int GetCoverSide( Frame rc, int inflate )
        {
            long s = 0;
            if (rc.w > rc.h) s = (long)rc.w; else s = (long)rc.h;

            if (BitOps.IsPow2( s ) && s <= MaxQuadSide && s >= MinQuadSide)
            {
                return (int)s;
            }

            s += inflate*2;
            s = BitOps.NextPow2( s );
            while (s < MinQuadSide) s *= 2;
            while (s > MaxQuadSide) s /= 2;
            return (int)s;
        }
Пример #9
0
 //  trims bitmap deleting transparent border
 //  returns trimmed rectangle
 public static Frame TrimBitmap( Bitmap bmp )
 {
     Frame res = new Frame( 0, 0, bmp.Width, bmp.Height );
     while (IsRowEmpty( bmp, res.y ) && res.y < bmp.Height) { res.y++; res.h--; }
     while (IsRowEmpty( bmp, res.y + res.h - 1 ) && res.h > 0) res.h--;
     while (IsColEmpty( bmp, res.x ) && res.w < bmp.Width) { res.x++; res.w--; }
     while (IsColEmpty( bmp, res.x + res.w - 1 ) && res.w > 0) res.w--;
     return res;
 }
Пример #10
0
 public static byte MaxAlpha( Bitmap bmp, Frame rc )
 {
     int ex = rc.x + rc.w;
     int ey = rc.y + rc.h;
     byte alpha = 0;
     for (int j = rc.y; j < ey; j++)
     {
         for (int i = rc.x; i < ex; i++)
         {
             byte ca = (byte)((bmp.GetPixel( i, j ).ToArgb()&0xFF000000)>>24);
             if (ca > alpha) alpha = ca;
         }
     }
     return alpha;
 }
Пример #11
0
 public static int GetUtilization( Bitmap bmp, Frame rc )
 {
     int ex = rc.x + rc.w;
     int ey = rc.y + rc.h;
     int cFree = 0;
     for (int j = rc.y; j < ey; j++)
     {
         for (int i = rc.x; i < ex; i++)
         {
             byte ca = GetAlpha( i, j, bmp );
             if (ca == 0) cFree++;
         }
     }
     return rc.w*rc.h - cFree;
 }