Пример #1
0
        public ImageTexeler(Bitmap img, int paletteMaxNum)
        {
            this.img = img;

            int tx = img.Width / 4;
            int ty = img.Height / 4;

            palettes       = new Color[tx * ty][];
            paletteCounts  = new int[tx * ty];
            paletteNumbers = new int[tx, ty];
            paletteDiffs   = new float[tx * ty, tx *ty];

            int palNum = 0;

            for (int x = 0; x < tx; x++)
            {
                for (int y = 0; y < ty; y++)
                {
                    ImageIndexerFast iif = new ImageIndexerFast(img, x * 4, y * 4);
                    palettes[palNum]      = iif.palette;
                    paletteNumbers[x, y]  = palNum;
                    paletteCounts[palNum] = 1;
                    int similar = calcPaletteDiffs(palNum);

/*                    if (similar != -1)
 *                  {
 *                      paletteCounts[palNum] = 0;
 *                      paletteCounts[similar]++;
 *                      paletteNumbers[x, y] = similar;
 *                  }
 */
                    palNum++;
                }
            }

            while (countUsedPalettes() > paletteMaxNum)
            {
                Console.Out.WriteLine(countUsedPalettes());
                int   besta   = -1;
                int   bestb   = -1;
                float bestDif = float.MaxValue;


                //Find the two most similar palettes
                for (int i = 0; i < palettes.Length; i++)
                {
                    if (paletteCounts[i] == 0)
                    {
                        continue;
                    }
                    for (int j = 0; j < palettes.Length; j++)
                    {
                        if (i == j)
                        {
                            continue;
                        }
                        if (paletteCounts[j] == 0)
                        {
                            continue;
                        }

                        if (paletteDiffs[i, j] < bestDif)
                        {
                            bestDif = paletteDiffs[i, j];
                            besta   = j;
                            bestb   = i;
                        }
                    }
                }

                //Merge the Palettes!!!
                palettes[besta] = palMerge(palettes[besta], palettes[bestb]);
                calcPaletteDiffs(besta);
                paletteCounts[besta] += paletteCounts[bestb];
                paletteCounts[bestb]  = 0;

                for (int x = 0; x < tx; x++)
                {
                    for (int y = 0; y < ty; y++)
                    {
                        if (paletteNumbers[x, y] == bestb)
                        {
                            paletteNumbers[x, y] = besta;
                        }
                    }
                }
            }



            //CREATE THE FINAL PAL
            int currNum = 0;

            finalPalette = new Color[paletteMaxNum * 4];
            int[] newPalNums = new int[palettes.Length];
            for (int i = 0; i < palettes.Length; i++)
            {
                if (paletteCounts[i] != 0)
                {
                    //transparentToTheEnd(palettes[i]);
                    newPalNums[i] = currNum;
                    Array.Copy(palettes[i], 0, finalPalette, currNum * 4, 4);
                    currNum++;
                }
            }

            ByteArrayOutputStream texDat = new ByteArrayOutputStream();
            ByteArrayOutputStream f5Dat  = new ByteArrayOutputStream();

            for (int y = 0; y < ty; y++)
            {
                for (int x = 0; x < tx; x++)
                {
                    //Find out if texel has transparent.

                    bool hasTransparent = false;
                    for (int yy = 0; yy < 4; yy++)
                    {
                        for (int xx = 0; xx < 4; xx++)
                        {
                            Color coll = img.GetPixel(x * 4 + xx, y * 4 + yy);
                            if (coll.A < 128)
                            {
                                hasTransparent = true;
                            }
                        }
                    }

                    //WRITE THE IMAGE DATA
                    for (int yy = 0; yy < 4; yy++)
                    {
                        byte b   = 0;
                        byte pow = 1;
                        for (int xx = 0; xx < 4; xx++)
                        {
                            Color coll = img.GetPixel(x * 4 + xx, y * 4 + yy);
                            byte  col;
                            if (coll.A < 128)
                            {
                                col = 3;
                            }
                            else
                            {
                                col = (byte)ImageIndexer.closest(coll, palettes[paletteNumbers[x, y]]);
                                if (col == 3)
                                {
                                    col = 2;
                                }
                            }
                            b   |= (byte)(pow * col);
                            pow *= 4;
                        }
                        texDat.writeByte(b);
                    }


                    //WRITE THE FORMAT-5 SPECIFIC DATA
                    ushort dat = (ushort)(newPalNums[paletteNumbers[x, y]] * 2);
                    if (!hasTransparent)
                    {
                        dat |= 2 << 14;
                    }
                    f5Dat.writeUShort(dat);
                }
            }

            f5data  = f5Dat.getArray();
            texdata = texDat.getArray();
        }
Пример #2
0
        public ImageTexeler(Bitmap img, int paletteMaxNum)
        {
            this.img = img;

            int tx = img.Width / 4;
            int ty = img.Height / 4;
            palettes = new Color[tx*ty][];
            paletteCounts = new int[tx*ty];
            paletteNumbers = new int[tx, ty];
            paletteDiffs = new float[tx*ty, tx*ty];

            int palNum = 0;
            for(int x = 0; x < tx; x++)
                for (int y = 0; y < ty; y++)
                {
                    ImageIndexerFast iif = new ImageIndexerFast(img, x * 4, y * 4);
                    palettes[palNum] = iif.palette;
                    paletteNumbers[x, y] = palNum;
                    paletteCounts[palNum] = 1;
                    int similar = calcPaletteDiffs(palNum);
            /*                    if (similar != -1)
                    {
                        paletteCounts[palNum] = 0;
                        paletteCounts[similar]++;
                        paletteNumbers[x, y] = similar;
                    }
                    */
                    palNum++;
                }

            while (countUsedPalettes() > paletteMaxNum)
            {
                Console.Out.WriteLine(countUsedPalettes());
                int besta = -1;
                int bestb = -1;
                float bestDif = float.MaxValue;

                //Find the two most similar palettes
                for (int i = 0; i < palettes.Length; i++)
                {
                    if (paletteCounts[i] == 0) continue;
                    for (int j = 0; j < palettes.Length; j++)
                    {
                        if (i == j) continue;
                        if (paletteCounts[j] == 0) continue;

                        if (paletteDiffs[i, j] < bestDif)
                        {
                            bestDif = paletteDiffs[i, j];
                            besta = j;
                            bestb = i;
                        }
                    }
                }

                //Merge the Palettes!!!
                palettes[besta] = palMerge(palettes[besta], palettes[bestb]);
                calcPaletteDiffs(besta);
                paletteCounts[besta] += paletteCounts[bestb];
                paletteCounts[bestb] = 0;

                for (int x = 0; x < tx; x++)
                    for (int y = 0; y < ty; y++)
                        if (paletteNumbers[x, y] == bestb)
                            paletteNumbers[x, y] = besta;
            }

            //CREATE THE FINAL PAL
            int currNum = 0;
            finalPalette = new Color[paletteMaxNum*4];
            int[] newPalNums = new int[palettes.Length];
            for(int i = 0; i < palettes.Length; i++)
            {
                if(paletteCounts[i] != 0)
                {
                    //transparentToTheEnd(palettes[i]);
                    newPalNums[i] = currNum;
                    Array.Copy(palettes[i], 0, finalPalette, currNum*4, 4);
                    currNum++;
                }
            }

            ByteArrayOutputStream texDat = new ByteArrayOutputStream();
            ByteArrayOutputStream f5Dat = new ByteArrayOutputStream();
            for (int y = 0; y < ty; y++)
                for (int x = 0; x < tx; x++)
                {
                    //Find out if texel has transparent.

                    bool hasTransparent = false;
                    for (int yy = 0; yy < 4; yy++)
                        for (int xx = 0; xx < 4; xx++)
                        {
                            Color coll = img.GetPixel(x * 4 + xx, y * 4 + yy);
                            if (coll.A < 128)
                                hasTransparent = true;
                        }

                    //WRITE THE IMAGE DATA
                    for (int yy = 0; yy < 4; yy++)
                    {
                        byte b = 0;
                        byte pow = 1;
                        for (int xx = 0; xx < 4; xx++)
                        {
                            Color coll = img.GetPixel(x*4+xx, y*4+yy);
                            byte col;
                            if (coll.A < 128)
                            {
                                col = 3;
                            }
                            else
                            {
                                col = (byte)ImageIndexer.closest(coll, palettes[paletteNumbers[x, y]]);
                                if (col == 3) col = 2;
                            }
                            b |= (byte)(pow * col);
                            pow *= 4;
                        }
                        texDat.writeByte(b);
                    }

                    //WRITE THE FORMAT-5 SPECIFIC DATA
                    ushort dat = (ushort)(newPalNums[paletteNumbers[x, y]] * 2);
                    if(!hasTransparent)
                        dat |= 2 << 14;
                    f5Dat.writeUShort(dat);
                }

            f5data = f5Dat.getArray();
            texdata = texDat.getArray();
        }