/// <summary> /// Returns an instance of System.Drawing.Image which represents visually this CIndexSprite instance. /// A lossless conversion takes place. /// </summary> /// <returns></returns> public Image ToImage() { Bitmap bmp = new Bitmap(1, 1); if (this.Height > 0 && this.Width > 0) { bmp = new Bitmap(this.Width, this.Height, System.Drawing.Imaging.PixelFormat.Format16bppRgb565); bmp.MakeTransparent(); int lc = 0; foreach (Line l in this.Lines) { int sc = 0; int sco = 0; foreach (Segment s in l.Segments) { sco += (int)s.Offset; for (int i = 0; i < s.CKPixelCount; i++) { int x = sco; int y = lc; Color color = CIndexSpriteHelper.GetColorFrom16bit(s.CKPixels[i]); try { bmp.SetPixel(x, y, color); } catch { } sco++; } for (int i = 0; i < s.PixCount; i++) { int x = sco; int y = lc; Color color = CIndexSpriteHelper.GetColorFrom16bit(s.Pixels[i]); try { /* Try Catch reason: * Some segments will overflow the boundaries of the sprite.. * This used to crash the old editor, but a try catch solves it. * I'll investigate the reason later, but there seems to be absolutely no data loss.*/ bmp.SetPixel(x, y, color); } catch { } sco++; } sc++; } lc++; } } return(bmp); }
/// <summary> /// Initializes a new instance of CIndexSprite from the given System.Drawing.Image /// Warning: Lossy conversions take place. /// DarkEden Sprites are 16-bit in color and have no Alpha whereas System.Drawing.Image is 32-bit in color and have 0 to 255 Alpha. /// Colors are approximated. Pixels with zero alpha are ignored and pixels with more than zero alpha are considered opaque. /// </summary> /// <param name="srcimg"></param> public CIndexSprite(Image srcimg) { this.Width = (UInt16)srcimg.Width; this.Height = (UInt16)srcimg.Height; Bitmap srcbmp = new Bitmap(srcimg); this.Lines = new Line[srcimg.Height]; for (int y = 0; y < srcimg.Height; y++) { this.Lines[y] = new Line(); UInt16 llength = 2; List <Segment> lsegs = new List <Segment>(); for (int x = 0; x < srcimg.Width;) { llength += 3; Segment seg = new Segment(); //Temporary ISPK workaround. //seg.CKPixelCount = 0;// //seg.CKPixels = null;// List <UInt16> ckpixels = new List <UInt16>();// List <UInt16> pixels = new List <UInt16>(); ushort offs = 0; while (srcbmp.GetPixel(x, y).A == 0) { x++; if (x >= srcimg.Width) { break; } else { offs += 1; } } seg.Offset = offs; if (x >= srcimg.Width) { llength -= 4; break; } Color c = srcbmp.GetPixel(x, y); while (c.A > 0 && CIndexSpriteHelper.IsChromaKeyColor(c)) { ckpixels.Add(CIndexSpriteHelper.Get16bitFromColor(c)); this.CKPixCount++; x++; if (x >= srcimg.Width) { break; } llength++; c = srcbmp.GetPixel(x, y); } while (c.A > 0 && !CIndexSpriteHelper.IsChromaKeyColor(c)) { pixels.Add(CIndexSpriteHelper.Get16bitFromColor(c)); x++; if (x >= srcimg.Width) { break; } llength++; c = srcbmp.GetPixel(x, y); } seg.CKPixelCount = (UInt16)ckpixels.Count; seg.CKPixels = ckpixels.ToArray(); seg.PixCount = (UInt16)pixels.Count; seg.Pixels = pixels.ToArray(); lsegs.Add(seg); } this.Lines[y].Length = llength; this.Lines[y].SegmentCount = (UInt16)lsegs.Count; this.Lines[y].Segments = lsegs.ToArray(); } this.ByteCount = this.GetBytes().Length; }