/// <summary> /// Creates an animated surface that looks like static. /// </summary> /// <param name="width">The width of the surface.</param> /// <param name="height">The height of the surface.</param> /// <param name="frames">How many frames the animation should have.</param> /// <param name="blankChance">Chance a character will be blank. Characters are between index 48-158. Chance is evaluated versus <see cref="System.Random.NextDouble"/>.</param> /// <returns>An animation.</returns> public static AnimatedSurface CreateStatic(int width, int height, int frames, double blankChance) { var animation = new AnimatedSurface("default", width, height, Global.FontDefault); var editor = new SurfaceEditor(new BasicSurface(1, 1, Global.FontDefault)); for (int f = 0; f < frames; f++) { var frame = animation.CreateFrame(); editor.TextSurface = frame; for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { int character = Global.Random.Next(48, 168); if (Global.Random.NextDouble() <= blankChance) { character = 32; } editor.SetGlyph(x, y, character); editor.SetForeground(x, y, Color.White * (float)(Global.Random.NextDouble() * (1.0d - 0.5d) + 0.5d)); } } } animation.AnimationDuration = 1; animation.Repeat = true; animation.Start(); return(animation); }
public static GameObject CreateFromGlyph(int glyph, Color color = new Color()) { if (color == new Color()) { color = Color.White; } var animation = new AnimatedSurface("anim", 1, 1); var editor = new SurfaceEditor(animation.CreateFrame()); editor.SetGlyph(0, 0, glyph, color); return(new GameObject(animation)); }
public override void Draw(ISurface surface, Rectangle area) { if (Item is Color || Item is Tuple <Color, Color, string> ) { var editor = new SurfaceEditor(surface); string value = new string(' ', area.Width - 2); Cell cellLook = new Cell(); _currentAppearance.CopyAppearanceTo(cellLook); if (Item is Color) { cellLook.Background = (Color)Item; editor.Print(area.Left + 1, area.Top, value, cellLook); } else { cellLook.Foreground = ((Tuple <Color, Color, string>)Item).Item2; cellLook.Background = ((Tuple <Color, Color, string>)Item).Item1; value = ((Tuple <Color, Color, string>)Item).Item3.Align(HorizontalAlignment.Left, area.Width - 2); editor.Print(area.Left + 1, area.Top, value, cellLook); } editor.Print(area.Left, area.Top, " ", _currentAppearance); editor.Print(area.Left + area.Width - 1, area.Top, " ", _currentAppearance); if (IsSelected) { editor.SetGlyph(area.Left, area.Top, 16); editor.SetGlyph(area.Left + area.Width - 1, area.Top, 17); } IsDirty = false; } else { base.Draw(surface, area); } }
public static GameObject CreateBlinkingFromGlyph(int glyph, float duration, Color color = new Color()) { if (color == new Color()) { color = Color.White; } var animation = new AnimatedSurface("anim", 1, 1); var editor = new SurfaceEditor(animation.CreateFrame()); editor.SetGlyph(0, 0, glyph, color); animation.CreateFrame(); //empty frame animation.AnimationDuration = duration; animation.Repeat = true; animation.Start(); return(new GameObject(animation)); }
public static BasicSurface ToSurface(this Texture2D image, SadConsole.Font font, bool blockMode = false) { int imageWidth = image.Width; int imageHeight = image.Height; Color[] pixels = new Color[imageWidth * imageHeight]; image.GetData <Color>(pixels); BasicSurface surface = new BasicSurface(imageWidth / font.Size.X, imageHeight / font.Size.Y, font); SurfaceEditor editor = new SurfaceEditor(surface); global::System.Threading.Tasks.Parallel.For(0, imageHeight / surface.Font.Size.Y, (h) => //for (int h = 0; h < imageHeight / surface.Font.Size.Y; h++) { int startY = (h * surface.Font.Size.Y); //System.Threading.Tasks.Parallel.For(0, imageWidth / surface.Font.Size.X, (w) => for (int w = 0; w < imageWidth / surface.Font.Size.X; w++) { int startX = (w * surface.Font.Size.X); float allR = 0; float allG = 0; float allB = 0; for (int y = 0; y < surface.Font.Size.Y; y++) { for (int x = 0; x < surface.Font.Size.X; x++) { int cY = y + startY; int cX = x + startX; Color color = pixels[cY * imageWidth + cX]; allR += color.R; allG += color.G; allB += color.B; } } byte sr = (byte)(allR / (surface.Font.Size.X * surface.Font.Size.Y)); byte sg = (byte)(allG / (surface.Font.Size.X * surface.Font.Size.Y)); byte sb = (byte)(allB / (surface.Font.Size.X * surface.Font.Size.Y)); var newColor = new Color(sr, sg, sb); float sbri = newColor.GetBrightness() * 255; if (blockMode) { if (sbri > 204) { editor.SetGlyph(w, h, 219, newColor); //█ } else if (sbri > 152) { editor.SetGlyph(w, h, 178, newColor); //▓ } else if (sbri > 100) { editor.SetGlyph(w, h, 177, newColor); //▒ } else if (sbri > 48) { editor.SetGlyph(w, h, 176, newColor); //░ } } else { if (sbri > 230) { editor.SetGlyph(w, h, (int)'#', newColor); } else if (sbri > 207) { editor.SetGlyph(w, h, (int)'&', newColor); } else if (sbri > 184) { editor.SetGlyph(w, h, (int)'$', newColor); } else if (sbri > 161) { editor.SetGlyph(w, h, (int)'X', newColor); } else if (sbri > 138) { editor.SetGlyph(w, h, (int)'x', newColor); } else if (sbri > 115) { editor.SetGlyph(w, h, (int)'=', newColor); } else if (sbri > 92) { editor.SetGlyph(w, h, (int)'+', newColor); } else if (sbri > 69) { editor.SetGlyph(w, h, (int)';', newColor); } else if (sbri > 46) { editor.SetGlyph(w, h, (int)':', newColor); } else if (sbri > 23) { editor.SetGlyph(w, h, (int)'.', newColor); } } } } ); return(surface); }
/// <summary> /// Returns a surface with the specified image rendered to it as characters. /// </summary> /// <param name="image">The image to render.</param> /// <returns>The surface.</returns> public BasicSurface GetSurface(Texture2D image) { editor.Clear(); image.GetData <Color>(pixels); System.Threading.Tasks.Parallel.For(0, surface.Width * surface.Height, (i) => //for (int i = 0; i < surface.Width * surface.Height; i++) { int allR = 0; int allG = 0; int allB = 0; int min = i * fontPixels; int max = min + fontPixels; for (int pixel = min; pixel < max; pixel++) { Color color = pixels[indexes[pixel]]; allR += color.R; allG += color.G; allB += color.B; } // print our character byte sr = (byte)(allR / fontPixels); byte sg = (byte)(allG / fontPixels); byte sb = (byte)(allB / fontPixels); var newColor = new Color(sr, sg, sb); float sbri = newColor.GetBrightness() * 255; Point surfacePoint = surface.GetPointFromIndex(i); if (UseBlockMode) { if (sbri > 204) { editor.SetGlyph(surfacePoint.X, surfacePoint.Y, 219, newColor); //█ } else if (sbri > 152) { editor.SetGlyph(surfacePoint.X, surfacePoint.Y, 178, newColor); //▓ } else if (sbri > 100) { editor.SetGlyph(surfacePoint.X, surfacePoint.Y, 177, newColor); //▒ } else if (sbri > 48) { editor.SetGlyph(surfacePoint.X, surfacePoint.Y, 176, newColor); //░ } else { editor.SetGlyph(surfacePoint.X, surfacePoint.Y, 0, Color.Black); } } else { if (sbri > 230) { editor.SetGlyph(surfacePoint.X, surfacePoint.Y, (int)'#', newColor); } else if (sbri > 207) { editor.SetGlyph(surfacePoint.X, surfacePoint.Y, (int)'&', newColor); } else if (sbri > 184) { editor.SetGlyph(surfacePoint.X, surfacePoint.Y, (int)'$', newColor); } else if (sbri > 161) { editor.SetGlyph(surfacePoint.X, surfacePoint.Y, (int)'X', newColor); } else if (sbri > 138) { editor.SetGlyph(surfacePoint.X, surfacePoint.Y, (int)'x', newColor); } else if (sbri > 115) { editor.SetGlyph(surfacePoint.X, surfacePoint.Y, (int)'=', newColor); } else if (sbri > 92) { editor.SetGlyph(surfacePoint.X, surfacePoint.Y, (int)'+', newColor); } else if (sbri > 69) { editor.SetGlyph(surfacePoint.X, surfacePoint.Y, (int)';', newColor); } else if (sbri > 46) { editor.SetGlyph(surfacePoint.X, surfacePoint.Y, (int)':', newColor); } else if (sbri > 23) { editor.SetGlyph(surfacePoint.X, surfacePoint.Y, (int)'.', newColor); } else { editor.SetGlyph(surfacePoint.X, surfacePoint.Y, 0, Color.Black); } } } ); return(surface); }
public unsafe static void ToSurface(this Texture2D image, TextSurface surface, Color[] cachedColorArray, bool blockMode = false) { #if SFML int imageWidth = (int)image.Size.X; int imageHeight = (int)image.Size.Y; Color[] pixels = new Color[imageWidth * imageHeight]; using (var imageData = image.CopyToImage()) { int pixelChanIndex = 0; fixed(byte *pixelChan = imageData.Pixels) { fixed(Color *color = pixels) { for (int i = 0; i < pixels.Length; i++) { color[i].R = pixelChan[pixelChanIndex]; color[i].G = pixelChan[pixelChanIndex + 1]; color[i].B = pixelChan[pixelChanIndex + 2]; color[i].A = pixelChan[pixelChanIndex + 3]; pixelChanIndex += 4; } } } } #elif MONOGAME int imageWidth = image.Width; int imageHeight = image.Height; image.GetData <Color>(cachedColorArray); #endif SurfaceEditor editor = new SurfaceEditor(surface); editor.Clear(); global::System.Threading.Tasks.Parallel.For(0, imageHeight / surface.Font.Size.Y, (h) => //for (int h = 0; h < imageHeight / surface.Font.Size.Y; h++) { int startY = (h * surface.Font.Size.Y); //System.Threading.Tasks.Parallel.For(0, imageWidth / surface.Font.Size.X, (w) => for (int w = 0; w < imageWidth / surface.Font.Size.X; w++) { int startX = (w * surface.Font.Size.X); float allR = 0; float allG = 0; float allB = 0; for (int y = 0; y < surface.Font.Size.Y; y++) { for (int x = 0; x < surface.Font.Size.X; x++) { int cY = y + startY; int cX = x + startX; Color color = cachedColorArray[cY * imageWidth + cX]; allR += color.R; allG += color.G; allB += color.B; } } byte sr = (byte)(allR / (surface.Font.Size.X * surface.Font.Size.Y)); byte sg = (byte)(allG / (surface.Font.Size.X * surface.Font.Size.Y)); byte sb = (byte)(allB / (surface.Font.Size.X * surface.Font.Size.Y)); var newColor = new Color(sr, sg, sb); float sbri = newColor.GetBrightness() * 255; if (blockMode) { if (sbri > 204) { editor.SetGlyph(w, h, 219, newColor); //█ } else if (sbri > 152) { editor.SetGlyph(w, h, 178, newColor); //▓ } else if (sbri > 100) { editor.SetGlyph(w, h, 177, newColor); //▒ } else if (sbri > 48) { editor.SetGlyph(w, h, 176, newColor); //░ } } else { if (sbri > 230) { editor.SetGlyph(w, h, (int)'#', newColor); } else if (sbri > 207) { editor.SetGlyph(w, h, (int)'&', newColor); } else if (sbri > 184) { editor.SetGlyph(w, h, (int)'$', newColor); } else if (sbri > 161) { editor.SetGlyph(w, h, (int)'X', newColor); } else if (sbri > 138) { editor.SetGlyph(w, h, (int)'x', newColor); } else if (sbri > 115) { editor.SetGlyph(w, h, (int)'=', newColor); } else if (sbri > 92) { editor.SetGlyph(w, h, (int)'+', newColor); } else if (sbri > 69) { editor.SetGlyph(w, h, (int)';', newColor); } else if (sbri > 46) { editor.SetGlyph(w, h, (int)':', newColor); } else if (sbri > 23) { editor.SetGlyph(w, h, (int)'.', newColor); } } } } ); }
/// <summary> /// Returns a surface with the specified image rendered to it as characters. /// </summary> /// <param name="image">The image to render.</param> /// <returns>The surface.</returns> public TextSurface GetSurface(Texture2D image) { editor.Clear(); #if SFML using (var imageData = image.CopyToImage()) { using (var memStream = new global::System.IO.MemoryStream()) { var binForm = new global::System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); memStream.Write(imageData.Pixels, 0, imageData.Pixels.Length); memStream.Seek(0, global::System.IO.SeekOrigin.Begin); pixels = (Color[])binForm.Deserialize(memStream); } } #elif MONOGAME image.GetData <Color>(pixels); #endif System.Threading.Tasks.Parallel.For(0, surface.Width * surface.Height, (i) => //for (int i = 0; i < surface.Width * surface.Height; i++) { int allR = 0; int allG = 0; int allB = 0; int min = i * fontPixels; int max = min + fontPixels; for (int pixel = min; pixel < max; pixel++) { Color color = pixels[indexes[pixel]]; allR += color.R; allG += color.G; allB += color.B; } // print our character byte sr = (byte)(allR / fontPixels); byte sg = (byte)(allG / fontPixels); byte sb = (byte)(allB / fontPixels); var newColor = new Color(sr, sg, sb); float sbri = newColor.GetBrightness() * 255; Point surfacePoint = surface.GetPointFromIndex(i); if (UseBlockMode) { if (sbri > 204) { editor.SetGlyph(surfacePoint.X, surfacePoint.Y, 219, newColor); //█ } else if (sbri > 152) { editor.SetGlyph(surfacePoint.X, surfacePoint.Y, 178, newColor); //▓ } else if (sbri > 100) { editor.SetGlyph(surfacePoint.X, surfacePoint.Y, 177, newColor); //▒ } else if (sbri > 48) { editor.SetGlyph(surfacePoint.X, surfacePoint.Y, 176, newColor); //░ } else { editor.SetGlyph(surfacePoint.X, surfacePoint.Y, 0, Color.Black); } } else { if (sbri > 230) { editor.SetGlyph(surfacePoint.X, surfacePoint.Y, (int)'#', newColor); } else if (sbri > 207) { editor.SetGlyph(surfacePoint.X, surfacePoint.Y, (int)'&', newColor); } else if (sbri > 184) { editor.SetGlyph(surfacePoint.X, surfacePoint.Y, (int)'$', newColor); } else if (sbri > 161) { editor.SetGlyph(surfacePoint.X, surfacePoint.Y, (int)'X', newColor); } else if (sbri > 138) { editor.SetGlyph(surfacePoint.X, surfacePoint.Y, (int)'x', newColor); } else if (sbri > 115) { editor.SetGlyph(surfacePoint.X, surfacePoint.Y, (int)'=', newColor); } else if (sbri > 92) { editor.SetGlyph(surfacePoint.X, surfacePoint.Y, (int)'+', newColor); } else if (sbri > 69) { editor.SetGlyph(surfacePoint.X, surfacePoint.Y, (int)';', newColor); } else if (sbri > 46) { editor.SetGlyph(surfacePoint.X, surfacePoint.Y, (int)':', newColor); } else if (sbri > 23) { editor.SetGlyph(surfacePoint.X, surfacePoint.Y, (int)'.', newColor); } else { editor.SetGlyph(surfacePoint.X, surfacePoint.Y, 0, Color.Black); } } } ); return(surface); }