/// <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(); }
/// <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); } }