Skip to main content
4 of 4
Commonmark migration

C#, Winform

Edit Changing the way you fill the coordinates array you can have different patterns - see below

Do you like this kind of pattern?

LandScape

Abstract

Bonus:

Scream Scream Scrambled

Random swap exactly one time all pixels in upper half with all pixels in lower half. Repeat the same procedure for unscrambling (bonus).

Code

Scramble.cs

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Windows.Forms; using System.Drawing.Imaging; using System.IO; namespace Palette { public partial class Scramble : Form { public Scramble() { InitializeComponent(); } public struct Coord { public int x, y; } private void Work(Bitmap srcb, Bitmap outb) { int w = srcb.Width, h = srcb.Height; Coord[] coord = new Coord[w * h]; FastBitmap fsb = new FastBitmap(srcb); FastBitmap fob = new FastBitmap(outb); fsb.LockImage(); fob.LockImage(); ulong seed = 0; int numpix = 0; for (int y = 0; y < h; y++) for (int x = 0; x < w; numpix++, x++) { coord[numpix].x = x; coord[numpix].y = y; uint color = fsb.GetPixel(x, y); seed += color; fob.SetPixel(x, y, color); } fsb.UnlockImage(); fob.UnlockImage(); pbOutput.Refresh(); Application.DoEvents(); int half = numpix / 2; int limit = half; XorShift rng = new XorShift(seed); progressBar.Visible = true; progressBar.Maximum = limit; fob.LockImage(); while (limit > 0) { int p = (int)(rng.next() % (uint)limit); int q = (int)(rng.next() % (uint)limit); uint color = fob.GetPixel(coord[p].x, coord[p].y); fob.SetPixel(coord[p].x, coord[p].y, fob.GetPixel(coord[half+q].x, coord[half+q].y)); fob.SetPixel(coord[half+q].x, coord[half+q].y, color); limit--; if (p < limit) { coord[p]=coord[limit]; } if (q < limit) { coord[half+q]=coord[half+limit]; } if ((limit & 0xfff) == 0) { progressBar.Value = limit; fob.UnlockImage(); pbOutput.Refresh(); fob.LockImage(); } } fob.UnlockImage(); pbOutput.Refresh(); progressBar.Visible = false; } void DupImage(PictureBox s, PictureBox d) { if (d.Image != null) d.Image.Dispose(); d.Image = new Bitmap(s.Image.Width, s.Image.Height); } void GetImagePB(PictureBox pb, string file) { Bitmap bms = new Bitmap(file, false); Bitmap bmp = bms.Clone(new Rectangle(0, 0, bms.Width, bms.Height), PixelFormat.Format32bppArgb); bms.Dispose(); if (pb.Image != null) pb.Image.Dispose(); pb.Image = bmp; } private void btnOpen_Click(object sender, EventArgs e) { OpenFileDialog openFileDialog = new OpenFileDialog(); openFileDialog.InitialDirectory = "c:\\temp\\"; openFileDialog.Filter = "Image Files(*.BMP;*.JPG;*.PNG)|*.BMP;*.JPG;*.PNG|All files (*.*)|*.*"; openFileDialog.FilterIndex = 1; openFileDialog.RestoreDirectory = true; if (openFileDialog.ShowDialog() == DialogResult.OK) { try { string file = openFileDialog.FileName; GetImagePB(pbInput, file); pbInput.Tag = file; DupImage(pbInput, pbOutput); Work(pbInput.Image as Bitmap, pbOutput.Image as Bitmap); file = Path.GetDirectoryName(file) + Path.DirectorySeparatorChar + Path.GetFileNameWithoutExtension(file) + ".scr.png"; pbOutput.Image.Save(file); } catch (Exception ex) { MessageBox.Show("Error: Could not read file from disk. Original error: " + ex.Message); } } } } //Adapted from Visual C# Kicks - http://www.vcskicks.com/ unsafe public class FastBitmap { private Bitmap workingBitmap = null; private int width = 0; private BitmapData bitmapData = null; private Byte* pBase = null; public FastBitmap(Bitmap inputBitmap) { workingBitmap = inputBitmap; } public BitmapData LockImage() { Rectangle bounds = new Rectangle(Point.Empty, workingBitmap.Size); width = (int)(bounds.Width * 4 + 3) & ~3; //Lock Image bitmapData = workingBitmap.LockBits(bounds, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); pBase = (Byte*)bitmapData.Scan0.ToPointer(); return bitmapData; } private uint* pixelData = null; public uint GetPixel(int x, int y) { pixelData = (uint*)(pBase + y * width + x * 4); return *pixelData; } public uint GetNextPixel() { return *++pixelData; } public void GetPixelArray(int x, int y, uint[] Values, int offset, int count) { pixelData = (uint*)(pBase + y * width + x * 4); while (count-- > 0) { Values[offset++] = *pixelData++; } } public void SetPixel(int x, int y, uint color) { pixelData = (uint*)(pBase + y * width + x * 4); *pixelData = color; } public void SetNextPixel(uint color) { *++pixelData = color; } public void UnlockImage() { workingBitmap.UnlockBits(bitmapData); bitmapData = null; pBase = null; } } public class XorShift { private ulong x; /* The state must be seeded with a nonzero value. */ public XorShift(ulong seed) { x = seed; } public ulong next() { x ^= x >> 12; // a x ^= x << 25; // b x ^= x >> 27; // c return x * 2685821657736338717L; } } } 

Scramble.designer.cs

namespace Palette { partial class Scramble { private System.ComponentModel.IContainer components = null; protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } private void InitializeComponent() { this.panel = new System.Windows.Forms.FlowLayoutPanel(); this.pbInput = new System.Windows.Forms.PictureBox(); this.pbOutput = new System.Windows.Forms.PictureBox(); this.progressBar = new System.Windows.Forms.ProgressBar(); this.btnOpen = new System.Windows.Forms.Button(); this.panel.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.pbInput)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.pbOutput)).BeginInit(); this.SuspendLayout(); // // panel // this.panel.AutoScroll = true; this.panel.AutoSize = true; this.panel.Controls.Add(this.pbInput); this.panel.Controls.Add(this.pbOutput); this.panel.Dock = System.Windows.Forms.DockStyle.Top; this.panel.Location = new System.Drawing.Point(0, 0); this.panel.Name = "panel"; this.panel.Size = new System.Drawing.Size(748, 306); this.panel.TabIndex = 3; // // pbInput // this.pbInput.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; this.pbInput.Location = new System.Drawing.Point(3, 3); this.pbInput.MinimumSize = new System.Drawing.Size(100, 100); this.pbInput.Name = "pbInput"; this.pbInput.Size = new System.Drawing.Size(100, 300); this.pbInput.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize; this.pbInput.TabIndex = 3; this.pbInput.TabStop = false; // // pbOutput // this.pbOutput.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; this.pbOutput.Location = new System.Drawing.Point(109, 3); this.pbOutput.MinimumSize = new System.Drawing.Size(100, 100); this.pbOutput.Name = "pbOutput"; this.pbOutput.Size = new System.Drawing.Size(100, 300); this.pbOutput.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize; this.pbOutput.TabIndex = 4; this.pbOutput.TabStop = false; // // progressBar // this.progressBar.Dock = System.Windows.Forms.DockStyle.Bottom; this.progressBar.Location = new System.Drawing.Point(0, 465); this.progressBar.Name = "progressBar"; this.progressBar.Size = new System.Drawing.Size(748, 16); this.progressBar.TabIndex = 5; // // btnOpen // this.btnOpen.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.btnOpen.Location = new System.Drawing.Point(12, 429); this.btnOpen.Name = "btnOpen"; this.btnOpen.Size = new System.Drawing.Size(53, 30); this.btnOpen.TabIndex = 6; this.btnOpen.Text = "Start"; this.btnOpen.UseVisualStyleBackColor = true; this.btnOpen.Click += new System.EventHandler(this.btnOpen_Click); // // Scramble // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.BackColor = System.Drawing.SystemColors.ControlDark; this.ClientSize = new System.Drawing.Size(748, 481); this.Controls.Add(this.btnOpen); this.Controls.Add(this.progressBar); this.Controls.Add(this.panel); this.Name = "Scramble"; this.Text = "Form1"; this.panel.ResumeLayout(false); this.panel.PerformLayout(); ((System.ComponentModel.ISupportInitialize)(this.pbInput)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.pbOutput)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); } private System.Windows.Forms.FlowLayoutPanel panel; private System.Windows.Forms.PictureBox pbOutput; private System.Windows.Forms.ProgressBar progressBar; private System.Windows.Forms.PictureBox pbInput; private System.Windows.Forms.Button btnOpen; } } 

Program.cs

using System; using System.Collections.Generic; using System.Windows.Forms; namespace Palette { static class Program { [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Scramble()); } } } 

Check 'Unsafe code' in project property to compile.

Complex pattern

Scramble

Change the first part of work function, up to Application.DoEvents:

 int w = srcb.Width, h = srcb.Height; string Msg = "Scramble"; Graphics gr = Graphics.FromImage(outb); Font f = new Font("Arial", 100, FontStyle.Bold); var size = gr.MeasureString(Msg, f); f = new Font("Arial", w / size.Width * 110, FontStyle.Bold); size = gr.MeasureString(Msg, f); gr.DrawString(Msg, f, new SolidBrush(Color.White), (w - size.Width) / 2, (h - size.Height) / 2); gr.Dispose(); Coord[] coord = new Coord[w * h]; FastBitmap fsb = new FastBitmap(srcb); FastBitmap fob = new FastBitmap(outb); fsb.LockImage(); fob.LockImage(); ulong seed = 1; int numpix = h * w; int c1 = 0, c2 = numpix; int y2 = h / 2; int p2 = numpix/2; for (int p = 0; p < p2; p++) { for (int s = 1; s > -2; s -= 2) { int y = (p2+s*p) / w; int x = (p2+s*p) % w; uint d = fob.GetPixel(x, y); if (d != 0) { c2--; coord[c2].x = x; coord[c2].y = y; } else { coord[c1].x = x; coord[c1].y = y; c1++; } fob.SetPixel(x, y, fsb.GetPixel(x, y)); } } fsb.UnlockImage(); fob.UnlockImage(); pbOutput.Refresh(); Application.DoEvents(); 
edc65
  • 32.3k
  • 3
  • 37
  • 90