Exemplo n.º 1
0
        /// <summary>
        /// Generate pixels, palette and update objects in frames.
        /// </summary>
        /// <param name="pixels">Pixels of frames.</param>
        /// <param name="palettes">Palettes of frames.</param>
        private void CreateData(out Pixel[] pixelsLin, out Pixel[] pixelsHori, out Color[][] palettes)
        {
            int tileSize     = 128;
            int fullTileSize = (this.PaletteMode == PaletteMode.Palette16_16) ? tileSize * 2 : tileSize;
            int maxColors    = this.Format.MaxColors();
            int numPalettes  = (maxColors <= 16) ? 16 : 1;

            // Create the ObjData. Quantizate images.
            List <Color[]>    palettesList = new List <Color[]>();
            List <ObjectData> data         = new List <ObjectData>();

            foreach (Tuple <Frame, EmguImage> frame in this.frameData)
            {
                EmguImage frameImg = frame.Item2;
                Obj[]     objects  = frame.Item1.GetObjects();

                foreach (Obj obj in objects)
                {
                    ObjectData objData = new ObjectData();
                    objData.Object = obj;

                    Rectangle area = obj.GetArea();
                    area.Offset(256, 128);
                    objData.Image = frameImg.Copy(area);

                    // Update object
                    objData.Object.Mode        = this.ObjectMode;
                    objData.Object.PaletteMode = this.PaletteMode;

                    // Quantizate
                    this.Quantization.Quantizate(objData.Image);
                    objData.PixelsLineal     = this.Quantization.GetPixels(PixelEncoding.Lineal);
                    objData.PixelsHorizontal = this.Quantization.GetPixels(PixelEncoding.HorizontalTiles);
                    objData.Palette          = this.Quantization.Palette;
                    if (objData.Palette.Length > maxColors)
                    {
                        throw new FormatException(string.Format("The image has more than {0} colors", maxColors));
                    }

                    ManyFixedPaletteQuantization manyFixed = this.Quantization as ManyFixedPaletteQuantization;
                    if (this.OriginalPalettes != null && manyFixed != null)
                    {
                        objData.Object.PaletteIndex = (byte)manyFixed.SelectedPalette;
                    }

                    palettesList.Add(objData.Palette);

                    data.Add(objData);
                }
            }

            // Reduce palettes if necessary
            if (this.OriginalPalettes == null)
            {
                this.Reducer.Clear();
                this.Reducer.MaxColors = maxColors;
                this.Reducer.AddPaletteRange(palettesList.ToArray());
                this.Reducer.Reduce(numPalettes);
                palettes = this.Reducer.ReducedPalettes;

                // Approximate palettes removed
                for (int i = 0; i < data.Count; i++)
                {
                    int paletteIdx = this.Reducer.PaletteApproximation[i];
                    if (paletteIdx >= 0)
                    {
                        // Quantizate again the image with the new palette
                        Color[] newPalette = palettes[paletteIdx];
                        FixedPaletteQuantization quantization = new FixedPaletteQuantization(newPalette);
                        quantization.Quantizate(data[i].Image);

                        // Get the pixel
                        data[i].PixelsLineal     = quantization.GetPixels(PixelEncoding.Lineal);
                        data[i].PixelsHorizontal = quantization.GetPixels(PixelEncoding.HorizontalTiles);
                    }
                    else
                    {
                        paletteIdx = (paletteIdx + 1) * -1;
                    }

                    // Update object
                    data[i].Object.PaletteIndex = (byte)paletteIdx;
                }
            }
            else
            {
                if (this.OriginalPalettes.Length > numPalettes)
                {
                    throw new FormatException("More original palettes than allowed");
                }

                palettes = this.OriginalPalettes;
            }

            List <Pixel> pixelLinList  = new List <Pixel>();
            List <Pixel> pixelHoriList = new List <Pixel>();

            for (int i = 0; i < data.Count; i++)
            {
                // Search the data into the array to ensure there is no duplicated tiles
                int tileNumber = SearchTile(pixelLinList, data[i].PixelsLineal, tileSize);
                data[i].Object.TileNumber = (ushort)tileNumber;

                // Add pixels to the list
                if (tileNumber == -1)
                {
                    data[i].Object.TileNumber = (ushort)(pixelLinList.Count / tileSize);
                    pixelLinList.AddRange(data[i].PixelsLineal);
                    pixelHoriList.AddRange(data[i].PixelsHorizontal);

                    // Pad to tilesize to increment at least one tilenumber next time
                    while (pixelLinList.Count % fullTileSize != 0)
                    {
                        pixelLinList.Add(new Pixel(0, 0, true));
                    }

                    while (pixelHoriList.Count % fullTileSize != 0)
                    {
                        pixelHoriList.Add(new Pixel(0, 0, true));
                    }
                }
            }

            pixelsLin  = pixelLinList.ToArray();
            pixelsHori = pixelHoriList.ToArray();
        }
Exemplo n.º 2
0
        /// <summary>
        /// Import a background image creating and writing a NSCR, NCGR and NCLR files to the streams passed.
        /// </summary>
        /// <param name="imgPath">Image path.</param>
        /// <param name="mapStr">Map stream output.</param>
        /// <param name="imgStr">Image stream output.</param>
        /// <param name="palStr">Pal strream output.</param>
        public void ImportBackground(EmguImage newImg, Stream mapStr, Stream imgStr, Stream palStr)
        {
            if (newImg == null)
            {
                throw new ArgumentNullException();
            }

            int width     = newImg.Width;
            int height    = newImg.Height;
            int maxColors = this.Format.MaxColors();

            Pixel[]    pixels;
            Color[]    palette;
            List <int> mapPalette   = new List <int>();
            bool       is16ColFixed = (Format == ColorFormat.Indexed_4bpp) &&
                                      (PaletteMode == PaletteMode.Palette16_16) && (Quantization is FixedPaletteQuantization);

            if (!is16ColFixed)
            {
                // Quantizate image -> get pixels and palette
                this.Quantization.Quantizate(newImg);
                pixels  = this.Quantization.GetPixels(this.PixelEncoding);
                palette = this.Quantization.Palette;
                if (palette.Length > maxColors)
                {
                    throw new FormatException(string.Format("The image has more than {0} colors", maxColors));
                }
            }
            else
            {
                Console.Write("(16 Color fixed!) ");
                palette = this.Quantization.Palette;
                ManyFixedPaletteQuantization quant = new ManyFixedPaletteQuantization(
                    this.Quantization.Palette.Split(16).ToArray());

                List <Pixel> pixelList = new List <Pixel>();
                for (int y = 0; y < newImg.Height; y += this.TileSize.Height)
                {
                    for (int x = 0; x < newImg.Width; x += this.TileSize.Width)
                    {
                        Rectangle subArea  = new Rectangle(x, y, this.TileSize.Width, this.TileSize.Height);
                        EmguImage subImage = newImg.Copy(subArea);
                        quant.Quantizate(subImage);
                        mapPalette.Add(quant.SelectedPalette);
                        pixelList.AddRange(quant.GetPixels(PixelEncoding.Lineal));
                    }
                }

                pixels = pixelList.ToArray();
            }

            // Create palette format
            Nclr nclr = new Nclr()
            {
                Extended = this.ExtendedPalette
            };

            nclr.SetData(palette, this.Format);

            // Create map from pixels
            Nscr nscr = new Nscr()
            {
                TileSize    = this.TileSize,
                Width       = width,
                Height      = height,
                BgMode      = this.BgMode,
                PaletteMode = this.PaletteMode
            };

            if (!is16ColFixed)
            {
                nscr.PaletteMode = (this.Format == ColorFormat.Indexed_4bpp) ?
                                   PaletteMode.Palette16_16 : PaletteMode.Palette256_1;
                pixels = nscr.CreateMap(pixels);
            }
            else
            {
                nscr.PaletteMode = PaletteMode.Palette16_16;
                pixels           = nscr.CreateMap(pixels, mapPalette.ToArray());
            }

            if (this.PartialImage)
            {
                // As the image won't expand to all the screen,
                // The first tile must be transparent
                int     tilesizeLength = this.TileSize.Width * this.TileSize.Height;
                Pixel[] newPixels      = new Pixel[pixels.Length + tilesizeLength];

                // New transparent pixels
                for (int i = 0; i < tilesizeLength; i++)
                {
                    newPixels[i] = new Pixel(0, 255, true);
                }

                // Image pixels
                Array.Copy(pixels, 0, newPixels, tilesizeLength, pixels.Length);
                pixels = newPixels;

                // Update map info
                MapInfo[] mapInfo = nscr.GetMapInfo();
                for (int i = 0; i < mapInfo.Length; i++)
                {
                    mapInfo[i] = new MapInfo(
                        mapInfo[i].TileIndex + 1,
                        mapInfo[i].PaletteIndex,
                        mapInfo[i].FlipX,
                        mapInfo[i].FlipY);
                }
                nscr.SetMapInfo(mapInfo);
            }


            // Create image format
            Ncgr ncgr = new Ncgr()
            {
                RegDispcnt = this.DispCnt,
                Unknown    = this.UnknownChar
            };

            ncgr.Width  = (pixels.Length > 256) ? 256 : pixels.Length;
            ncgr.Height = (int)Math.Ceiling(pixels.Length / (double)ncgr.Width);
            if (ncgr.Height % this.TileSize.Height != 0)
            {
                ncgr.Height += this.TileSize.Height - (ncgr.Height % this.TileSize.Height);
            }
            ncgr.SetData(pixels, this.PixelEncoding, this.Format, this.TileSize);

            // Write data
            if (palStr != null)
            {
                nclr.Write(palStr);
            }
            if (imgStr != null)
            {
                ncgr.Write(imgStr);
            }
            if (mapStr != null)
            {
                nscr.Write(mapStr);
            }
        }