Generate Thumbnail

Wave collapse art

Concept Imagine each image as a collection of small boxes arranged in different positions. Each image has four sides, and our goal is to determine how these images can connect to one another based on the configuration of these sides. Let’s take the example of an image: ...

July 20, 2024 · 6 min · 1130 words · PrashantUnity
Generate Thumbnail

Cover art in SkiaSharp

Creating Cover Images with SkiaSharp Cover on this website is generated using SkiaSharp Only Requirements Visual Studio Code (VS Code) Polyglot Notebook Extension A little bit of experience in C# For Basic/Installation please visit Basic Setup Code Install SkiaSharp 1 #r "nuget:SkiaSharp" Import SkiaSharp Library 1 using SkiaSharp; Code To Generate Cover Or Thumbnail 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 int width = 640; int height = 220; int marginY = -10; int marginX = -10; string Numbering ="1"; string mainText ="SKIA SHARP"; string subText = "Generate Thumbnail | Polyglot Notebook"; string backGroundColor ="#003366"; string textColor = "#ffffff"; string boderColor = "#ffffff"; SKBitmap bmp = new(width, height); SKCanvas canvas = new(bmp); canvas.Clear(SKColor.Parse(backGroundColor)); using (var paint = new SKPaint()) { paint.TextSize = width/ 10.0f; paint.IsAntialias = true; paint.Color = SKColor.Parse(textColor); paint.IsStroke = false; paint.StrokeWidth = 3; paint.TextAlign = SKTextAlign.Center; canvas.DrawText(mainText, width / 2f, height / 2f, paint); paint.TextSize = width/ 25.0f; paint.TextAlign = SKTextAlign.Right; canvas.DrawText(subText, width+marginX, height+marginY, paint); paint.TextSize = width/ 20.0f; canvas.DrawText(Numbering, (width/ 20.0f)*Numbering.Length,(width/ 20.0f)*1.25f, paint); paint.IsStroke = true; paint.TextAlign = SKTextAlign.Center; paint.Color = SKColor.Parse(textColor); } SKFileWStream fs = new("cover.jpg"); bmp.Encode(fs, SKEncodedImageFormat.Jpeg, quality: 50); bmp.Display();

June 14, 2024 · 2 min · 215 words · PrashantUnity
Generate Thumbnail

Hex grid in SkiaSharp

Concept A hexagon consists of six vertices. Given one vertex coordinate, we can find all other vertices as the angle between two edges is 120 degrees. Consider a starting point (x, y) and the width of an edge b. The right neighbor points will be (x + b, y). The right neighbor of the right neighbor will be (x + b + b * Cos(60), y + b * Sin(60)) and so on. Example ...

August 3, 2024 · 3 min · 634 words · PrashantUnity
Generate Thumbnail

Trig tables in SkiaSharp

Trigonometry Table Generation Trignonometry Table Code used to Generate Above Table 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 int width = 1500; int height = 750; int step = 60; SKBitmap bmp = new(width, height); SKCanvas canvas = new(bmp); canvas.Clear(SKColor.Parse("#fff")); SKPaint paint = new() { IsAntialias = true, StrokeWidth = 4, Color = SKColor.Parse("#003366"), Style = SKPaintStyle.Stroke }; paint.TextSize = 48f; string backGroundColor ="#fff"; canvas.Clear(SKColor.Parse(backGroundColor)); paint.Style = SKPaintStyle.Fill; string trignometricTable = "Trigonometry Table"; string root = "\u221A"; string theta ="\u03B8"; string degree ="\u00B0"; string inf ="\u221E"; var ls = new List<List<string>>(); ls.Add(["",$"0{degree}",$"30{degree}",$"45{degree}",$"60{degree}",$"90{degree}"]); ls.Add([$"Sin{theta}",$"0",$"1/2",$"1/{root}2",$"({root}3)/2",$"1",]); ls.Add([$"Cos{theta}",$"1",$"({root}3)/2",$"1/{root}2",$"1/2",$"0",]); ls.Add([$"Tan{theta}",$"0",$"1/{root}3",$"1",$"{root}3",$"{inf}",]); ls.Add([$"Cosec{theta}",$"{inf}",$"2",$"{root}2",$"2/{root}3",$"1",]); ls.Add([$"Sec{theta}",$"1",$"2/{root}3",$"{root}2",$"2",$"{inf}",]); ls.Add([$"Cot{theta}",$"{inf}",$"{root}3",$"1",$"1/{root}3",$"0",]); float shifx =150; float shify =120; float verticalMax = 600 + shify; float horizontalMax = 1200 + shifx; for(var i=shify; i<height; i+=100) { canvas.DrawLine(shifx,i,horizontalMax,i,paint); } for(var i=shifx; i<width; i+=200) { canvas.DrawLine(i,shify,i,verticalMax,paint); } paint.TextAlign = SKTextAlign.Center; canvas.DrawText(trignometricTable,width/2,100,paint); float y =200; foreach(var i in ls) { float x =shifx+100; foreach(var j in i) { canvas.DrawText(j,x,y,paint); x+=200; } y+=100; } bmp.Display(); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 int width = 1500; int height = 750; int step = 60; SKBitmap bmp = new(width, height); SKCanvas canvas = new(bmp); canvas.Clear(SKColor.Parse("#fff")); SKPaint paint = new() { IsAntialias = true, StrokeWidth = 4, Color = SKColor.Parse("#003366"), Style = SKPaintStyle.Stroke }; paint.TextSize = 48f; string backGroundColor ="#fff"; canvas.Clear(SKColor.Parse(backGroundColor)); paint.Style = SKPaintStyle.Stroke; var skPath = new SKPath(); float diagonal = 600; float rX = 150; float rXX = rX + diagonal*MathF.Sqrt(3)/2; float rY = 150; float rYY = rY +diagonal/2; SKPoint[] rt = [new SKPoint(rX,rY),new SKPoint(rX,rYY),new SKPoint(rXX,rYY)]; float aX = width/2; float aY = 300; canvas.DrawText("1",rX-30,(rY+rYY)/2 ,paint); canvas.DrawText("2",(rX+rXX)/2,(rY+rYY)/2 -10 ,paint); canvas.DrawText("\u221A3",(rX+rXX)*1/2.5f,rYY +50 ,paint); var skpath = new SKPath(); skpath.AddPoly(rt); canvas.DrawPath(skpath,paint); bmp.Display();

August 3, 2024 · 2 min · 370 words · PrashantUnity
Generate Thumbnail

Images on a Skia canvas

Requirements VS Code with Polyglot Notebook .Net Installed Open VS Code create new File Image.ipynb Import SkiaSharp Library Open Image.ipynb File select .Net Interactive as Kernel Create cell inside File 1 2 3 #r "nuget:SkiaSharp" using SkiaSharp; using System.IO; Image Drawer Function Create New Cell and Paste below code 1 2 3 4 5 6 7 8 9 10 11 void DrawImage(string path, SKCanvas canvas, float x = 0, float y = 0) { using (var inputStream = File.OpenRead(path)) { using (var inputBitmap = SKBitmap.Decode(inputStream)) { var imageInfo = new SKImageInfo(inputBitmap.Width, inputBitmap.Height); canvas.DrawBitmap(inputBitmap, x , y); } } } Skia SHarp Setup 1 2 3 4 5 6 7 8 9 10 11 12 int width = 1280; int height = 640; SKBitmap bmp = new(width, height); SKCanvas canvas = new(bmp); canvas.Clear(SKColor.Parse("#fff")); SKPaint paint = new() { Color = SKColors.White.WithAlpha(100), IsAntialias = true, StrokeWidth = 3, ColorF = SKColor.Parse("#003366") }; Uses of Function Created earlier for Importing Image 1 2 3 4 5 6 7 8 DrawImage("image.png", canvas,10, 10); // For saving the image as a file using (SKFileWStream fs = new("image.jpg")) { bmp.Encode(fs, SKEncodedImageFormat.Jpeg, quality: 50); } bmp.Display() That all needed to use image in SkiaSharp

July 20, 2024 · 1 min · 197 words · PrashantUnity
Generate Thumbnail

Triangle illusions

Setup 1 2 #r "nuget:SkiaSharp" using SkiaSharp; Triangle class 1 2 3 4 5 6 public class Triangle { public SKPoint A {get;set;} public SKPoint B {get;set;} public SKPoint C {get;set;} } Triangle Point Helper 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 List<Triangle> GetTrianglePoints(int count=10 ,float factor =0.25f,int baseLength=600) { float length= baseLength; var a = new SKPoint((float)Math.Cos(Math.PI/3)*length,0); var b = new SKPoint(0,(float)Math.Sin(Math.PI/3)*length); var c = new SKPoint(length,(float)Math.Sin(Math.PI/3)*length); if(factor>1 || factor<0) factor=0.5f; float m= count*factor; float n= count-m; var ls = new List<Triangle>(); ls.Add(new Triangle() { A=a,B=b,C=c }); for(var i=0; i<count;i++) { var aa = new SKPoint((m*a.X + n*b.X)/count , (m*a.Y + n*b.Y)/count ); var bb = new SKPoint((m*b.X + n*c.X)/count , (m*b.Y + n*c.Y)/count ); var cc = new SKPoint((m*c.X + n*a.X)/count , (m*c.Y + n*a.Y)/count ); var temp = new Triangle() { A = aa, B = bb, C = cc }; ls.Add(temp); a=aa; b=bb; c=cc; } return ls; } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 // Create an image and fill it blue int width = 1200; int height = 700; int step =50; SKBitmap bmp = new(width, height); SKCanvas canvas = new(bmp); canvas.Clear(SKColor.Parse("#fff")); Random rand = new(); SKPaint paint = new() { Color = SKColors.White.WithAlpha(100), IsAntialias = true , StrokeWidth = 2, ColorF = SKColor.Parse("#003366") }; foreach(var item in GetTrianglePoints(10,.2f,700)) { //paint.ColorF = listOfColor[rand.Next(0,listOfColor.Count)]; canvas.DrawLine(item.A,item.B,paint); canvas.DrawLine(item.B,item.C,paint); canvas.DrawLine(item.C,item.A,paint); } SKFileWStream fs = new("triangleillusion.jpg"); bmp.Encode(fs, SKEncodedImageFormat.Jpeg, quality: 50); bmp.Display();

June 23, 2024 · 2 min · 283 words · PrashantUnity
Generate Thumbnail

Basic shapes

Setup 1 2 #r "nuget:SkiaSharp" using SkiaSharp; Circle 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 int width = 1200; int height = 250; SKBitmap bmp = new(width, height); SKCanvas canvas = new(bmp); canvas.Clear(SKColor.Parse("#fff")); Random rand = new(0); SKPaint paint = new() { Color = SKColors.White.WithAlpha(100), IsAntialias = true , StrokeWidth = 4, ColorF = SKColor.Parse("#003366"), Style = SKPaintStyle.Stroke }; canvas.DrawCircle(110,110,100,paint); // hollow Circle paint.Style = SKPaintStyle.StrokeAndFill; canvas.DrawCircle(410,110,100,paint); // Follow Circle bmp.Display(); Line 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 int width = 1200; int height = 20; SKBitmap bmp = new(width, height); SKCanvas canvas = new(bmp); canvas.Clear(SKColor.Parse("#fff")); Random rand = new(0); SKPaint paint = new() { Color = SKColors.White.WithAlpha(100), IsAntialias = true , StrokeWidth = 4, ColorF = SKColor.Parse("#003366") }; SKPoint pointOne = new (0,10); SKPoint pointTwo = new (width,10); canvas.DrawLine(pointOne,pointTwo,paint); bmp.Display(); ...

June 22, 2024 · 3 min · 600 words · PrashantUnity
Generate Thumbnail

Multishape patterns

Setup 1 2 #r "nuget:SkiaSharp" using SkiaSharp; Color Sets 1 2 3 4 5 6 7 8 9 10 11 12 var listOfColor = new List<SKColor> { SKColor.Parse("#86B6F6"), SKColor.Parse("#176B87"), SKColor.Parse("#00A9FF"), SKColor.Parse("#FF90BC"), SKColor.Parse("#8ACDD7"), SKColor.Parse("#F2AFEF"), SKColor.Parse("#C499F3"), SKColor.Parse("#33186B"), }; Generate point on circumference of circle of different radius 1 2 3 4 5 6 7 8 9 List<SKPoint> CirclePoints(int n,float radius=3,float x=0, float y=0 ) { float degree = (float)(2*Math.PI/n); return Enumerable .Range(1,n) .Select(i=>degree*i) .Select(i=>(new SKPoint(x+ radius *(float)Math.Cos(i), y+ radius *(float)Math.Sin(i)))) .ToList(); } Section formulae Classic Geometric Formula To Calculate division point on line 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 List<(SKPoint,SKPoint)> SectionFormulae(int times, List<SKPoint> points , float factor =0.25f) { var ls = new List<(SKPoint,SKPoint)>(); float m= times*factor; float n= times-m; for(var i=0; i<times;i++) { var templs = new List<SKPoint>(); for(var j=0;j<points.Count;j++) { if(j==points.Count-1) { var x = (m*points[j].X + n*points[0].X)/times; var y = (m*points[j].Y + n*points[0].Y)/times; templs.Add(new SKPoint(x,y)); } else { var x = (m*points[j].X + n*points[j+1].X)/times; var y = (m*points[j].Y + n*points[j+1].Y)/times; templs.Add(new SKPoint(x,y)); } } points = templs; for(var j=0;j<points.Count;j++) { if(j==points.Count-1) { ls.Add((points[j],points[0])); } else { ls.Add((points[j],points[j+1])); } } } return ls; } Granullar Function for more Control Over Shapes 1 2 3 4 public List<(SKPoint,SKPoint)> GetShape(int n=3, int times=6 ,float factor =0.25f,int baseLength=600,int centerX =0,int centerY=0) { return SectionFormulae(times,CirclePoints(n,baseLength,x:centerX,y:centerY),factor); } Skiasharp Codde to Use All above Function and Generate Shapes 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 // Create an image and fill it blue int width = 2000; int height = 2000; int step =50; SKBitmap bmp = new(width, height); SKCanvas canvas = new(bmp); canvas.Clear(SKColor.Parse("#fff")); Random rand = new(); SKPaint paint = new() { Color = SKColors.White.WithAlpha(100), IsAntialias = true , StrokeWidth = 2, ColorF = SKColor.Parse("#003366") }; int seperation=4; for(var i=3;i<=15;i+=3) { paint.Color=listOfColor[rand.Next(0,listOfColor.Count)]; foreach(var item in GetShape(n:i,times:25, factor:0.08f, baseLength:seperation* i*i,centerX:width/2,centerY:height/2)) { canvas.DrawLine(item.Item1,item.Item2,paint); } } // Save the image to disk SKFileWStream fs = new("multishape.jpg"); bmp.Encode(fs, SKEncodedImageFormat.Jpeg, quality: 100); bmp.Display();

June 21, 2024 · 2 min · 375 words · PrashantUnity
Generate Thumbnail

Mosaic in SkiaSharp

Setup 1 2 #r "nuget:SkiaSharp" using SkiaSharp; Mosaic Generation Code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 // Create an image and fill it blue int width = 1920; int height = 700; int step =50; SKBitmap bmp = new(width, height); SKCanvas canvas = new(bmp); canvas.Clear(SKColor.Parse("#fff")); Random rand = new(); SKPaint paint = new() { Color = SKColors.White.WithAlpha(100), IsAntialias = true , StrokeWidth = 2, ColorF = SKColor.Parse("#003366") }; for(var i=0; i<height;i+=step) { for(var j=0; j<width;j+=step) { if(rand.Next(0,100)>50) paint.ColorF =SKColor.Parse("#003366"); else paint.Color =SKColor.Parse("#000f"); canvas.DrawRect(i,j,step,step,paint); } } SKFileWStream fs = new("mosaic.jpg"); bmp.Encode(fs, SKEncodedImageFormat.Jpeg, quality: 50); bmp.Display();

June 20, 2024 · 1 min · 121 words · PrashantUnity
Generate Thumbnail

Mazes in SkiaSharp

Setup 1 2 #r "nuget:SkiaSharp" using SkiaSharp; Maze Algorithm 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 public class MazeAlgorithm { Random random = new Random(); public int[,] GenerateMaze(int rows, int cols) { int[,] maze = new int[rows, cols]; // Initialize maze with walls for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { maze[i, j] = 1; } } // Set starting point maze[1, 1] = 0; DFS(maze, 1, 1); return maze; } void DFS(int[,] maze, int row, int col) { int[] directions = { 1, 2, 3, 4 }; Shuffle(directions); foreach (int dir in directions) { int[] dRow = { 0, 0, 1, -1 }; int[] dCol = { 1, -1, 0, 0 }; int newRow = row + 2 * dRow[dir - 1]; int newCol = col + 2 * dCol[dir - 1]; if (newRow > 0 && newRow < maze.GetLength(0) - 1 && newCol > 0 && newCol < maze.GetLength(1) - 1 && maze[newRow, newCol] == 1) { maze[row + dRow[dir - 1], col + dCol[dir - 1]] = 0; maze[newRow, newCol] = 0; DFS(maze, newRow, newCol); } } } void Shuffle(int[] array) { int n = array.Length; for (int i = 0; i < n; i++) { int r = i + random.Next(n - i); int temp = array[r]; array[r] = array[i]; array[i] = temp; } } } Skia Sharp To Utilise maze Algorithm and Generate Maze Image 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 // Create an image and fill it blue int width = 1920; int height = 1080; int step =50; SKBitmap bmp = new(width, height); SKCanvas canvas = new(bmp); canvas.Clear(SKColor.Parse("#fff")); Random rand = new(); SKPaint paint = new() { Color = SKColors.White.WithAlpha(100), IsAntialias = true , StrokeWidth = 2, ColorF = SKColor.Parse("#003366") }; int m= width/step, n=height/step; var ls = (new MazeAlgorithm()).GenerateMaze(m,n); ls[0,1]=0; for(var i=0; i<m;i++) { for(var j=0; j<n;j++) { paint.ColorF=(ls[i,j]==0)?SKColor.Parse("#ffffff"):SKColor.Parse("#000000"); canvas.DrawRect(i*step,j*step,step,step,paint); } } SKFileWStream fs = new("maze.jpg"); bmp.Encode(fs, SKEncodedImageFormat.Jpeg, quality: 50); bmp.Display();

June 19, 2024 · 2 min · 412 words · PrashantUnity