/// <summary> /// Erstellt ein Bitmap Objekt aus den Tile Daten /// </summary> /// <param name="pal">Palette, die zur Darstellung verwendet werden soll</param> /// <returns>Bitmap Objekt, welches das Tile darstellt</returns> public Bitmap ToBitmap(Palette pal) { var colorentries = new List<Byte>(64); if (_is8Bpp && (!pal.Is256Color())) { throw new Exception("Die angegebene Palette ist nicht im 8bpp Modus."); } foreach (byte b in _data) { if (!_is8Bpp) { var first = (byte) (b & 15); var second = (byte) (b >> 4); colorentries.Add(first); colorentries.Add(second); } else { colorentries.Add(b); } } var output = new Bitmap(8, 8); for (int i = 0; i < colorentries.Count; i++) { int y = i/8; int x = i%8; output.SetPixel(x, y, pal.Entries[colorentries[i]].ToColor()); } return output; }
/// <summary> /// Erstellt ein Bitmap Objekt unter Verwendung von Tileset, Tilemap und Palette /// </summary> /// <param name="set">Tileset, welches die Grafikdaten enthält</param> /// <param name="tileWidth">Breite der Ausgabegrafik in Tiles</param> /// <param name="fillColor">Farbe mit der nicht vorhandene Flächen gefüllt werden</param> /// <param name="drawingPalette">Palette, die zur Darstellung verwendet werden soll</param> /// <returns></returns> public Bitmap ToBitmap(Tileset set, int tileWidth, Color fillColor, Palette drawingPalette) { int tileHeight = Entries.Count/tileWidth; var output = new Bitmap(tileWidth*8, tileHeight*8); System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(output); for (int y = 0; y < tileHeight; ++y) { for (int x = 0; x < tileWidth; ++x) { int index = (y*tileWidth) + x; if (index > Entries.Count) { g.FillRectangle(new SolidBrush(fillColor), x*8, y*8, 8, 8); continue; } g.DrawImage(set.GetTileFromIndex(Entries[index].TileNumber).ToBitmap(drawingPalette), new Point(x*8, y*8)); } } g.Dispose(); return output; }
/// <summary> /// Erstellt ein Bitmap aus dem einzelnen Tilemap Eintrag /// </summary> /// <param name="drawingSet">Das zu verwendende Tileset</param> /// <param name="drawingPalette">Die zur Darstellung verwendete Palette</param> /// <returns>Bitmap, welches den Eintrag darstellt</returns> public Bitmap ToBitmap(Tileset drawingSet, Palette drawingPalette) { if (drawingSet.GetTileCount() < TileNumber) throw new Exception(String.Format("Das angegebene Tileset enthält Tile {0} nicht", TileNumber)); Bitmap output = drawingSet.GetTileFromIndex(TileNumber).ToBitmap(drawingPalette); if (HorizontalMirror) { output.RotateFlip(RotateFlipType.RotateNoneFlipX); } if (VerticalMirror) { output.RotateFlip(RotateFlipType.RotateNoneFlipY); } return output; }
/// <summary> /// Erstellt aus dem Bitmap img ein Tileset, eine Tilemap und eine Palette, die je nach Bedarf indiziert wird /// </summary> /// <param name="img">Eingabebitmap im PNG Format</param> /// <param name="pal">Ausgabe Palette</param> /// <param name="map">Ausgabe Tilemap</param> /// <param name="paletteMap">Gibt den Palettenindex an, welcher bei der Tilemaperstellung verwendet wird</param> /// <param name="is8Bpp">Wenn true: Erstellt ein 8bpp Tileset / Palette</param> /// <param name="isEncoded">Gibt an ob die Grafik komprimiert werden soll</param> /// <returns>Fertiges Tileset Objekt</returns> public static Tileset CreateIndexedTilesetMap(Bitmap img, out Palette pal, out Tilemap map, byte paletteMap = 0, bool is8Bpp = false, bool isEncoded = false) { if (img.PixelFormat == PixelFormat.Format4bppIndexed || img.PixelFormat == PixelFormat.Format8bppIndexed) { return Tileset.FromBitmap(img, isEncoded, out pal, out map, paletteMap); } var colors = new List<Color>(); var indexes = new List<byte>(); var coordinates = new Dictionary<Point, byte>(); Bitmap indexedBitmap = is8Bpp ? new Bitmap(img.Width, img.Height, PixelFormat.Format8bppIndexed) : new Bitmap(img.Width, img.Height, PixelFormat.Format4bppIndexed); for (int y = 0; y < img.Height; ++y) { for (int x = 0; x < img.Width; ++x) { Color c = img.GetPixel(x, y); if (!colors.Contains(c)) { colors.Add(c); coordinates.Add(new Point(x, y), (byte) (colors.Count - 1)); indexes.Add((byte) (colors.Count - 1)); } else { coordinates.Add(new Point(x, y), (byte) colors.IndexOf(c)); indexes.Add((byte) colors.IndexOf(c)); } } } int ccount = 16; if (is8Bpp) { ccount = 256; } if (colors.Count > ccount) { throw new ArgumentException( String.Format("Fehler beim indizieren des Bildes, es hat mehr als {0} Farben", ccount)); } while (colors.Count < ccount) { colors.Add(Color.Magenta); } ColorPalette ipal = indexedBitmap.Palette; for (int i = 0; i < ipal.Entries.Count(); ++i) { ipal.Entries[i] = colors[i]; } indexedBitmap.Palette = ipal; if (!is8Bpp) { BitmapData data = indexedBitmap.LockBits( new Rectangle(new Point(0, 0), new Size(img.Width, img.Height)), ImageLockMode.ReadWrite, PixelFormat.Format4bppIndexed); var bytes = new byte[data.Stride*data.Height]; Marshal.Copy(data.Scan0, bytes, 0, bytes.Length); for (int i = 0; i < bytes.Length; i++) { var b2 = (byte) (indexes[i*2] << 4); byte b1 = indexes[(i*2) + 1]; bytes[i] = (byte) (b1 | b2); } Marshal.Copy(bytes, 0, data.Scan0, bytes.Length); indexedBitmap.UnlockBits(data); } else { BitmapData data = indexedBitmap.LockBits( new Rectangle(new Point(0, 0), new Size(img.Width, img.Height)), ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed); var bytes = new byte[data.Stride*data.Height]; Marshal.Copy(data.Scan0, bytes, 0, bytes.Length); for (int i = 0; i < bytes.Length; ++i) { bytes[i] = indexes[i]; } Marshal.Copy(bytes, 0, data.Scan0, bytes.Length); indexedBitmap.UnlockBits(data); } pal = new Palette(colors.Select(col => new PaletteEntry(col.R, col.G, col.B)).ToArray()); Palette p; return Tileset.FromBitmap(indexedBitmap, isEncoded, out p, out map); }