{"id":261,"date":"2012-01-30T00:09:10","date_gmt":"2012-01-29T18:39:10","guid":{"rendered":"http:\/\/guganeshan.com\/blog\/?p=261"},"modified":"2012-04-10T23:37:56","modified_gmt":"2012-04-10T18:07:56","slug":"stackoverflow-logo-using-csharp-and-gdi","status":"publish","type":"post","link":"https:\/\/guganeshan.com\/blog\/stackoverflow-logo-using-csharp-and-gdi.html","title":{"rendered":"StackOverflow logo using C# and GDI+"},"content":{"rendered":"<p><a href=\"https:\/\/guganeshan.com\/blog\/wp-content\/uploads\/2012\/01\/so-logo.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-full wp-image-269\" title=\"so-logo\" src=\"https:\/\/guganeshan.com\/blog\/wp-content\/uploads\/2012\/01\/so-logo.png\" alt=\"StackOverflow logo\" width=\"103\" height=\"128\" \/><\/a>Discovered the \u201cCode Golf\u201d in StackExchange from the people I follow in twitter (for the #codechallenge hashtag).<\/p>\n<p><a title=\"Generate StackOverflow logo with code - StackExchange\" href=\"http:\/\/codegolf.stackexchange.com\/questions\/4561\/generate-the-stack-overflow-logo\" target=\"_blank\">The question to generate the StackOverflow logo in code<\/a> was particularly interesting to me and naturally I wanted to try generating the logo using C# (GDI+ code). Because nobody had a C# solution listed there, I also put the code there as an answer (Look for the answer titled &#8220;C#\/GDI+&#8221;)<\/p>\n<p>I initially recreated the logo in GDI+ without a for loop (every rectangle had a hardcoded value for its locations and size). Using that approach, its possible to recreate the logo almost identical to the original. But I was not happy with doing it that way.<!--more--><\/p>\n<p>Also because they say \u2192 \u201c<em><strong>The image is not required to be identical to the logo, however it must be recognizable as it<\/strong><\/em>\u201d in the description, I used a for loop to minimize the number of lines written and to just generate a logo that looks like the StackOverflow logo, but not identical.<\/p>\n<p>This is no \u201cingenious\u201d code. I would be really happy to see anyone generating the same logo with GDI+ in a more efficient and accurate manner, using a formula to represent the exact curve that the original logo has (without hard-coding each and every position and size of the overflowing elements)<\/p>\n<p>Here\u2019s the difference between my generated logo and the original StackOverflow logo \u2192<\/p>\n<p><a href=\"https:\/\/guganeshan.com\/blog\/wp-content\/uploads\/2012\/01\/stackoverflow-logo-generated-vs-original.png\"><img loading=\"lazy\" decoding=\"async\" style=\"background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;\" title=\"stackoverflow logo generated vs original\" src=\"https:\/\/guganeshan.com\/blog\/wp-content\/uploads\/2012\/01\/stackoverflow-logo-generated-vs-original_thumb.png\" alt=\"stackoverflow logo generated vs original\" width=\"388\" height=\"300\" border=\"0\" \/><\/a><\/p>\n<p><a title=\"Generate the StackOverflow logo with C# and GDI+ \u2192 source code\" href=\"https:\/\/guganeshan.com\/blog\/wp-content\/uploads\/2012\/01\/StackOverflowLogoCodeChallenge.zip\">Click here to download the code (zip file)<\/a><\/p>\n<p>Here&#8217;s the code listing:<\/p>\n<pre lang=\"csharp\">\r\nusing System.Drawing;\r\nusing System.Drawing.Drawing2D;\r\n\r\nnamespace StackOverflowLogoCodeChallenge\r\n{\r\n    public class SOLogo\r\n    {\r\n        private float _rotateValue;\r\n        private float _xValueForTransformation;\r\n        private float _yValueForTransformation;\r\n\r\n        int _containerWidth;\r\n        int _containerHeight;\r\n        float _lineThickness;\r\n        int _paddingWithinContainer;\r\n        int _elementStartY;\r\n\r\n        public SOLogo(\r\n            float rotateValue,\r\n            float xValueForTransformation,\r\n            float yValueForTransformation)\r\n        {\r\n            \/\/ Values used to position and rotate the overflowing elements.\r\n            _rotateValue = rotateValue;\r\n            _xValueForTransformation  = xValueForTransformation;\r\n            _yValueForTransformation = yValueForTransformation;\r\n        }\r\n\r\n        public void DrawLogo(Graphics g, int startX, int startY)\r\n        {\r\n            \/\/ Backup the current smoothing mode to apply later.\r\n            var SmoothingMoodBackup = g.SmoothingMode;\r\n            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;\r\n\r\n            \/\/ Values for the container box.\r\n            _containerWidth = 94;\r\n            _containerHeight = 61;\r\n            _lineThickness = 11f;\r\n            _paddingWithinContainer = 15;\r\n\r\n            \/\/ Y value of the position where the 1st overflowing element starts.\r\n            _elementStartY = 0;\r\n\r\n            \/\/ Starting point of the 'container':\r\n            \/\/ Top point of the line on the left-> |_|\r\n            Point pointContainerLineStart = new Point(startX, startY);\r\n\r\n            Point pointContainer1stLineEnd =new Point(\r\n                pointContainerLineStart.X,\r\n                pointContainerLineStart.Y); \/\/ Start with the previous\r\n            pointContainer1stLineEnd.Offset(0, _containerHeight); \/\/ Offset \"Y\"\r\n\r\n            Point pointContainer2ndLineEnd = new Point(\r\n                pointContainer1stLineEnd.X,\r\n                pointContainer1stLineEnd.Y); \/\/ Start with the previous\r\n            pointContainer2ndLineEnd.Offset(_containerWidth, 0); \/\/ Offset \"X\"\r\n\r\n            Point pointContainer3rdLineEnd = new Point(\r\n                pointContainer2ndLineEnd.X,\r\n                pointContainer2ndLineEnd.Y); \/\/ Start with the previous\r\n            pointContainer3rdLineEnd.Offset(0, 0 - _containerHeight); \/\/ Offset \"Y\" (negative)\r\n\r\n            GraphicsPath pathOfBox = new GraphicsPath();\r\n            pathOfBox.AddLine(\r\n                pointContainerLineStart,\r\n                pointContainer1stLineEnd); \/\/ Left line. Top to bottom\r\n            pathOfBox.AddLine(\r\n                pointContainer1stLineEnd,\r\n                pointContainer2ndLineEnd); \/\/ Bottom line. Left to right\r\n            pathOfBox.AddLine(\r\n                pointContainer2ndLineEnd,\r\n                pointContainer3rdLineEnd); \/\/ Right line. Bottom to top\r\n\r\n            Pen thickPen = new Pen(Brushes.Gray, _lineThickness);\r\n            Color elementColor = Color.FromKnownColor(KnownColor.Gray);\r\n\r\n            \/\/ Draw the 'container'\r\n            g.DrawPath(thickPen, pathOfBox);\r\n\r\n            \/\/ Increase the size of the pen to draw the elements inside the container\r\n            thickPen.Width = _lineThickness += 3;\r\n            \/\/ \"Y\" - position of the 1st element\r\n            _elementStartY = startY + 38;\r\n\r\n            \/\/ The following section draws the overflowing elements\r\n\r\n            Point pointElement1Left = new Point(\r\n                startX + _paddingWithinContainer,\r\n                _elementStartY);\r\n            Point pointElement1Right = new Point(\r\n                (startX + _containerWidth) - _paddingWithinContainer,\r\n                _elementStartY);\r\n\r\n            \/\/ Six colors of the overflowing elements\r\n            var colors = new Color[] {\r\n                Color.Gray,\r\n                Color.FromArgb(-6911615),\r\n                Color.FromArgb(-4417693),\r\n                Color.FromArgb(-2848227),\r\n                Color.FromArgb(-554957),\r\n                Color.FromArgb(-688847)\r\n            };\r\n\r\n            for (int x = 0; x < 6; x++)\r\n            {\r\n                thickPen.Color = colors[x];\r\n\r\n                pointElement1Left = new Point(\r\n                    startX + _paddingWithinContainer,\r\n                    _elementStartY);\r\n                pointElement1Right = new Point(\r\n                    (startX + _containerWidth) - _paddingWithinContainer,\r\n                    _elementStartY);\r\n\r\n                g.DrawLine(thickPen, pointElement1Left, pointElement1Right);\r\n                g.RotateTransform(_rotateValue);\r\n                g.TranslateTransform(_xValueForTransformation, _yValueForTransformation);\r\n            }\r\n\r\n            pathOfBox.Dispose();\r\n            thickPen.Dispose();\r\n\r\n            \/\/ Restore the smoothing mood that was backed up before we started this method.\r\n            g.SmoothingMode = SmoothingMoodBackup;\r\n        }\r\n    }\r\n}\r\n<\/pre>\n<p>Happy coding.<br \/>\n&nbsp;<\/p>\n<!-- AddThis Advanced Settings generic via filter on the_content --><!-- AddThis Share Buttons generic via filter on the_content -->","protected":false},"excerpt":{"rendered":"<p>Discovered the \u201cCode Golf\u201d in StackExchange from the people I follow in twitter (for the #codechallenge hashtag). The question to generate the StackOverflow logo in code was particularly interesting to me and naturally I wanted to try generating the logo using C# (GDI+ code). Because nobody had a C# solution listed there, I also put [&#8230;]<!-- AddThis Advanced Settings generic via filter on get_the_excerpt --><!-- AddThis Share Buttons generic via filter on get_the_excerpt --><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[57,58,74,56,59,55],"class_list":["post-261","post","type-post","status-publish","format-standard","hentry","category-programming","tag-c","tag-gdi","tag-programming","tag-source-code","tag-stackexchange","tag-stackoverflow"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/guganeshan.com\/blog\/wp-json\/wp\/v2\/posts\/261","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/guganeshan.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/guganeshan.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/guganeshan.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/guganeshan.com\/blog\/wp-json\/wp\/v2\/comments?post=261"}],"version-history":[{"count":12,"href":"https:\/\/guganeshan.com\/blog\/wp-json\/wp\/v2\/posts\/261\/revisions"}],"predecessor-version":[{"id":268,"href":"https:\/\/guganeshan.com\/blog\/wp-json\/wp\/v2\/posts\/261\/revisions\/268"}],"wp:attachment":[{"href":"https:\/\/guganeshan.com\/blog\/wp-json\/wp\/v2\/media?parent=261"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/guganeshan.com\/blog\/wp-json\/wp\/v2\/categories?post=261"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/guganeshan.com\/blog\/wp-json\/wp\/v2\/tags?post=261"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}