Reptillian Posted January 7, 2022 Share Posted January 7, 2022 (edited) This plugin basically generates Hitomezashi Stitch. Code is based on the spreadsheet found in this place - https://aperiodical.com/2020/12/mobile-numbers-hitomezashi-stitching/ The plugin itself is very simple, and speaks for itself. No instruction or clarification needed other than it's under Texture. Download Link : Hitomezashi.zip Preview: Source Code: Spoiler // Name: Hitomezashi Stitch // Submenu: Texture // Author: Reptorian // Title: Hitomezashi Stitch // Version: 1 // Desc: Generates pattern based on Hitomezashi algorithm. // Keywords: Hitomezashi, Pattern // URL: https://forums.getpaint.net/profile/85868-reptillian/ // Help: #region UICode IntSliderControl pixel_size = 20; // [1,100] Pixel Size DoubleSliderControl init_border_size = 10; // [0,100] Border Size (%) ColorWheelControl color_a = ColorBgra.FromBgr(0, 0, 0); // [PrimaryColor] Color A ColorWheelControl color_b = ColorBgra.FromBgr(255, 255, 255); // [SecondaryColor] Color B ColorWheelControl border_color = ColorBgra.FromBgr(169, 169, 169); // [DarkGray] {!init_border_size} Border Color ReseedButtonControl seed = 0; // Reseed #endregion int length_w,length_h,enlarged_w,enlarged_h,old_pixel_size; bool initialized,rebuild; Random myRandomA,myRandomB; Random Init = new Random(); int new_seed; int[] vx; int[] vy; int[,] surface; List<(int,int)> Equilavance = new List<(int,int)>{(0,0)}; void PreRender(Surface dst, Surface src) { if (!initialized){ length_w=(int)(Math.Ceiling(((double)(src.Width)/pixel_size))); length_h=(int)(Math.Ceiling(((double)(src.Height)/pixel_size))); enlarged_w = length_w * pixel_size; enlarged_h = length_h * pixel_size; enlarged_w = ( enlarged_w - src.Width ) / 2; enlarged_h = ( enlarged_h - src.Height ) / 2; myRandomA = new Random(Init.Next()); myRandomB = new Random(Init.Next()); vx = new int[length_w]; vy = new int[length_h]; surface = new int[length_w,length_h]; surface[0,0]=0; old_pixel_size=pixel_size; Equilavance.Clear(); } if (old_pixel_size != pixel_size){ length_w=(int)(Math.Ceiling(((double)(src.Width)/pixel_size))); length_h=(int)(Math.Ceiling(((double)(src.Height)/pixel_size))); enlarged_w = length_w * pixel_size; enlarged_h = length_h * pixel_size; enlarged_w = ( enlarged_w - src.Width ) / 2; enlarged_h = ( enlarged_h - src.Height ) / 2; myRandomA = new Random(Init.Next()); myRandomB = new Random(Init.Next()); vx = new int[length_w]; vy = new int[length_h]; surface = new int[length_w,length_h]; surface[0,0]=0; rebuild = true; old_pixel_size = pixel_size; } if (!initialized||rebuild||(new_seed != seed)){ myRandomA = new Random(Init.Next()); myRandomB = new Random(Init.Next()); for (int x = 0 ; x < length_w ; x++){ vx[x]=myRandomA.Next()%2; } for (int y = 0 ; y < length_h ; y++){ vy[y]=myRandomB.Next()%2; } for (int y = 1 ; y < length_h ; y++){ surface[0,y]=(surface[0,y-1]+vy[y-1])%2; } for(int y = 0 ; y < length_h ; y++){ for (int x = 1 ; x < length_w ; x++){ surface[x,y]=(vx[x-1]+surface[x-1,y]+y+2)%2; } } } new_seed=seed; initialized = true; rebuild = false; } // Here is the main multi-threaded render function // The dst canvas is broken up into rectangles and // your job is to write to each pixel of that rectangle void Render(Surface dst, Surface src, Rectangle rect) { int val; int border_size=(int)((double)(pixel_size*init_border_size/100)); if (border_size==pixel_size){border_size--;} bool use_border=border_size>0; double border_base=(double)(border_size)/2; int start_border=(int)(Math.Ceiling((double)(border_size))); int end_border=pixel_size-(int)(Math.Floor((double)(border_size))); int lx,ly; int mx=length_w-1; int my=length_h-1; int off_xl,off_xr,off_yt,off_yb,px,py; // Step through each row of the current rectangle for (int y = rect.Top; y < rect.Bottom; y++) { if (IsCancelRequested) return; // Step through each pixel on the current row of the rectangle for (int x = rect.Left; x < rect.Right; x++) { lx=((x+enlarged_w)/pixel_size)%length_w; ly=((y+enlarged_h)/pixel_size)%length_h; val = surface[lx,ly]; if (val==1){dst[x,y] = color_a;} else{ dst[x,y] = color_b;} if (use_border){ px=(x+enlarged_w)%pixel_size; py=(y+enlarged_h)%pixel_size; off_xl=surface[Math.Min(Math.Max(0,lx-1),mx),ly]; off_xr=surface[Math.Min(Math.Max(0,lx+1),mx),ly]; off_yt=surface[lx,Math.Min(Math.Max(0,ly+1),my)]; off_yb=surface[lx,Math.Min(Math.Max(0,ly-1),my)]; if (val != off_xl){ if(px<start_border){dst[x,y]=border_color;continue;} } if (val != off_xr){ if(px>end_border){dst[x,y]=border_color;continue;} } if (val != off_yb){ if(py<start_border){dst[x,y]=border_color;continue;} } if (val != off_yt){ if(py>end_border){dst[x,y]=border_color;continue;} } } } } } EDIT as of 1/8/2022 - Added Border Option EDIT as of 1/9/2022 - Optimization by adding "continue;". Edited January 9, 2022 by Reptillian 1 1 Quote G'MIC Filter Developer I am away from this forum for undetermined amount of time: If you really need anything related to my PDN plugin or my G'MIC filter within G'MIC plugin, then you can contact me via Paint.NET discord, and mention me. Link to comment Share on other sites More sharing options...
Reptillian Posted January 9, 2022 Author Share Posted January 9, 2022 (edited) New update, I added border option. I will admit that my solution for this isn't really the best. But it'll do with the limitations I have. This is what I created: Edited January 9, 2022 by Reptillian 3 Quote G'MIC Filter Developer I am away from this forum for undetermined amount of time: If you really need anything related to my PDN plugin or my G'MIC filter within G'MIC plugin, then you can contact me via Paint.NET discord, and mention me. Link to comment Share on other sites More sharing options...
lynxster4 Posted January 9, 2022 Share Posted January 9, 2022 Very cool plugin @Reptillian! The border option really helps. Thank you for this plugin...much appreciated! 💖 with border with your emboss/relief+ plugin and convolutions. Actually looks like stitching! 1 Quote My Art Gallery | My Shape Packs | ShapeMaker Mini Tut | Air Bubble Stained Glass Chrome Text with Reflections | Porcelain Text w/ Variegated Coloring | Realistic Knit PatternOpalescent Stained Glass | Frosted Snowman Cookie | Leather Texture | Plastic Text | Silk Embroidery Visit my Personal Website "Never, ever lose your sense of humor - you'll live longer" Link to comment Share on other sites More sharing options...
Pixey Posted January 9, 2022 Share Posted January 9, 2022 This is a really cool pattern @Reptillian 👍 thank you. It makes a neat cover for my phone 😁 1 Quote How I made Jennifer & Halle in Paint.net My Gallery | My Deviant Art "Rescuing one animal may not change the world, but for that animal their world is changed forever!" anon. Link to comment Share on other sites More sharing options...
Ladybug Posted January 9, 2022 Share Posted January 9, 2022 Love this plugin @Reptillian. Thanks for sharing it. I created an image with just the plugin and then on the second one applied the Galaxy Transformation plugin for a different look. Enjoying that plugin in too 1 Quote Click HERE to see my Pictorium of images I have worked on. You were once wild here. Don't let them tame you. ~ Isadora Duncan Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.