{"id":2412,"date":"2019-06-19T19:24:19","date_gmt":"2019-06-19T18:24:19","guid":{"rendered":"https:\/\/ridgesolutions.ie\/?p=2412"},"modified":"2019-06-20T10:27:19","modified_gmt":"2019-06-20T09:27:19","slug":"a-faster-alternative-to-the-slow-getpixel-and-setpixel-for-net-bitmaps","status":"publish","type":"post","link":"https:\/\/www.ridgesolutions.ie\/index.php\/2019\/06\/19\/a-faster-alternative-to-the-slow-getpixel-and-setpixel-for-net-bitmaps\/","title":{"rendered":"A faster alternative to the very slow GetPixel() and SetPixel() for .Net System.Drawing.Bitmap"},"content":{"rendered":"<p>Anybody who works with images often have probably come across .Net Bitmaps (System.Drawing.Bitmap) with their staggeringly slow GetPixel() and SetPixel() methods.  Now, if you are going to work directly with images then you&#8217;re probably in the wrong place if you are using C# and .Net.  However, sometimes you may want to do a small amount image analysis or manipulation from within .Net without the pain of having to pull in any other image libraries &#8211; but you find that GetPixel() and SetPixel() are just way too slow to use!<\/p>\n<p>Now there is a faster way to access or manipulate the pixel data stored in a .Net Bitmap, that is to lock it (using LockBits()) and then directly access the raw image data in memory &#8211; you unlock it when you&#8217;re finished.  This method is a lot faster than using Get\/SetPixel() but is quite complicated to implement and it&#8217;s very messy to look at!<\/p>\n<p>To get around this problem, and to avoid littering my code with gibberish I have written a bitmap wrapper class that wraps a bitmap, locks it, and provides it&#8217;s own GetPixel() and SetPixel() functions with which the original bitmap&#8217;s image data can be accessed.  Using this class you can get fast access to a bitmap while using the familiar Get\/SetPixel() paradigm &#8211; in this way it should act as a fairly easy drop in replacement for accessing the Bitmap objects directly.<\/p>\n<p>The class is called BmpPixelSnoop and it is used like this:<\/p>\n<pre>\r\n\/\/ Calculate a simple sum over all of the pixels\r\n\/\/ in the snooped bitmap. bitmap is a valid Bitmap object\r\n\r\nlong snoopSum = 0;\r\n\r\n\/\/ Create a BmpPixelSnoop wrapper for bitmap\r\nusing (var snoop = new BmpPixelSnoop(bitmap))\r\n{\r\n    for (int j = 0; j != snoop.Height; j++)\r\n    {\r\n        for (int i = 0; i != snoop.Width; i++)\r\n        {\r\n            \/\/ We call GetPixel() on snoop rather\r\n            \/\/ than bitmap as it's much faster!\r\n            var col = snoop.GetPixel(i, j);\r\n\r\n            snoopSum += col.R +\r\n                        col.G +\r\n                        col.B;\r\n        }\r\n    }\r\n}\r\n<\/pre>\n<p>First a BmpPixelSnoop object is created to wrap the bitmap, GetPixel() and SetPixel() can then be called on it.  When the BmpPixelSnoop object is destroyed (on leaving the using() block) the original bitmap will be unlocked.  It is important to note, that while the bitmap is being snooped the original bitmap object cannot be accessed as it&#8217;s locked!  Currently BmpPixelSnoop only works for bitmaps with a Pixel Format of PixelFormat.Format32bppArgb which is the default format for Bitmaps (if you don&#8217;t specify an alternative when creating them).<\/p>\n<p>So for a little extra complication you get easy &#038; fast access to the bitmap data &#8211; but how much faster than the native Get\/SetPixel() is it?  My (non scientific) tests seem to indicate that it&#8217;s about 10 times faster, which is fast enough for simple imaging tasks.  It is still quite inefficient however, this is a result of wanting to provide the same  Get\/SetPixel() interface as System.Drawing.Bitmap &#8211; for example, GetPixel() always returns all of the pixel data even if you just want to access the red component and hence is slower than it needs to be in this case.  I may add extra accessor methods in the future to cater for other usage patterns and greater efficiency.<\/p>\n<p>The code can be found in the git-hub repo: <a href=\"https:\/\/github.com\/kgodden\/DotNetPixelSnoop\">https:\/\/github.com\/kgodden\/DotNetPixelSnoop<\/a>.<\/p>\n<p>The class is defined in <strong>BmpPixelSnoop.cs<\/strong>, there is also some test code to check correctness and performance in Program.cs.<\/p>\n<p>Here is the code:<\/p>\n<pre>\r\n\/\/   Copyright 2019 Kevin Godden\r\n\/\/\r\n\/\/   Licensed under the Apache License, Version 2.0 (the \"License\");\r\n\/\/   you may not use this file except in compliance with the License.\r\n\/\/   You may obtain a copy of the License at\r\n\/\/\r\n\/\/       http:\/\/www.apache.org\/licenses\/LICENSE-2.0\r\n\/\/\r\n\/\/   Unless required by applicable law or agreed to in writing, software\r\n\/\/   distributed under the License is distributed on an \"AS IS\" BASIS,\r\n\/\/   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n\/\/   See the License for the specific language governing permissions and\r\n\/\/   limitations under the License.\r\n\r\nusing System;\r\nusing System.Drawing;\r\nusing System.Drawing.Imaging;\r\n\r\n\/\/\/ <summary>\r\n\/\/\/ Wraps a System.Drawing.Bitmap and provides faster\r\n\/\/\/ GetPixel() and SetPixel() functions for pixel access.\r\n\/\/\/ \r\n\/\/\/ NB While the snoop object is in scope the wrapped\r\n\/\/\/ bitmap object is locked and cannot be used \r\n\/\/\/ as normal.  Once you have finished snooping\r\n\/\/\/ on a bitmap object, dispose of the snooper to\r\n\/\/\/ unlock the bitmap and gain normal access to \r\n\/\/\/ it again, it is best to employ the 'using' keyword\r\n\/\/\/ to effectivly manage the snooper's scope as follows:\r\n\/\/\/ \r\n\/\/\/ \r\n\/\/\/ using (var snoop = new BmpPixelSnoop(myBitmap))\r\n\/\/\/ { \r\n\/\/\/ \r\n\/\/\/     \/\/ Snoop away!\r\n\/\/\/     var pixel = snoop.GetPixel(0, 0);\r\n\/\/\/     \r\n\/\/\/ } \/\/ Snoop goes out of scope here and bitmap is unlocked\r\n\/\/\/ \r\n\/\/\/ This class is marked as 'unsafe' so to use it in your project\r\n\/\/\/ you must have the 'Allow unsafe code' setting checked in the\r\n\/\/\/ project settings.\r\n\/\/\/ \r\n\/\/\/ <\/summary>\r\nunsafe class BmpPixelSnoop : IDisposable\r\n{\r\n    \/\/ A reference to the bitmap to be wrapped\r\n    private readonly Bitmap wrappedBitmap;\r\n\r\n    \/\/ The bitmap's data (once it has been locked)\r\n    private BitmapData data = null;\r\n\r\n    \/\/ Pointer to the first pixel\r\n    private readonly byte* scan0;\r\n\r\n    \/\/ Number of bytes per pixel\r\n    private readonly int depth;\r\n\r\n    \/\/ Number of bytes in an image row\r\n    private readonly int stride;\r\n\r\n    \/\/ The bitmap's width\r\n    private readonly int width;\r\n\r\n    \/\/ The bitmap's height\r\n    private readonly int height;\r\n\r\n    \/\/\/ <summary>\r\n    \/\/\/ Constructs a BmpPixelSnoop object, the bitmap\r\n    \/\/\/ object to be wraped is passed as a parameter.\r\n    \/\/\/ <\/summary>\r\n    \/\/\/ <param name=\"bitmap\">The bitmap to snoop<\/param>\r\n    public BmpPixelSnoop(Bitmap bitmap)\r\n    {\r\n        wrappedBitmap = bitmap ?? throw new ArgumentException(\"Bitmap parameter cannot be null\", \"bitmap\");\r\n\r\n        \/\/ Currently works only for: PixelFormat.Format32bppArgb\r\n        if (wrappedBitmap.PixelFormat != PixelFormat.Format32bppArgb)\r\n            throw new System.ArgumentException(\"Only PixelFormat.Format32bppArgb is supported\", \"bitmap\");\r\n\r\n        \/\/ Record the width & height\r\n        width = wrappedBitmap.Width;\r\n        height = wrappedBitmap.Height;\r\n\r\n        \/\/ So now we need to lock the bitmap so that we can gain access\r\n        \/\/ to it's raw pixel data.  It will be unlocked when this snoop is \r\n        \/\/ disposed.\r\n        var rect = new Rectangle(0, 0, wrappedBitmap.Width, wrappedBitmap.Height);\r\n\r\n        try\r\n        {\r\n            data = wrappedBitmap.LockBits(rect, ImageLockMode.ReadWrite, wrappedBitmap.PixelFormat);\r\n        }\r\n        catch (Exception ex)\r\n        {\r\n            throw new System.InvalidOperationException(\"Could not lock bitmap, is it already being snooped somewhere else?\", ex);\r\n        }\r\n\r\n        \/\/ Calculate number of bytes per pixel\r\n        depth = Bitmap.GetPixelFormatSize(data.PixelFormat) \/ 8; \/\/ bits per channel\r\n\r\n        \/\/ Get pointer to first pixel\r\n        scan0 = (byte*)data.Scan0.ToPointer();\r\n\r\n        \/\/ Get the number of bytes in an image row\r\n        \/\/ this will be used when determining a pixel's\r\n        \/\/ memory address.\r\n        stride = data.Stride;\r\n    }\r\n\r\n    \/\/\/ <summary>\r\n    \/\/\/ Disposes BmpPixelSnoop object\r\n    \/\/\/ <\/summary>\r\n    public void Dispose()\r\n    {\r\n        Dispose(true);\r\n        GC.SuppressFinalize(this);\r\n    }\r\n\r\n     \/\/\/ <summary>\r\n    \/\/\/ Disposes BmpPixelSnoop object, we unlock\r\n    \/\/\/ the wrapped bitmap.\r\n    \/\/\/ <\/summary>\r\n    protected virtual void Dispose(bool disposing)\r\n    {\r\n        if (disposing)\r\n        {\r\n            if (wrappedBitmap != null)\r\n                wrappedBitmap.UnlockBits(data);\r\n        }\r\n        \/\/ free native resources if there are any.\r\n    }\r\n\r\n    \/\/\/ <summary>\r\n    \/\/\/ Calculate the pointer to a pixel at (x, x)\r\n    \/\/\/ <\/summary>\r\n    \/\/\/ <param name=\"x\">The pixel's x coordinate<\/param>\r\n    \/\/\/ <param name=\"y\">The pixel's y coordinate<\/param>\r\n    \/\/\/ <returns>A byte* pointer to the pixel's data<\/returns>\r\n    private byte* PixelPointer(int x, int y)\r\n    {\r\n        return scan0 + y * stride + x * depth;\r\n    }\r\n\r\n    \/\/\/ <summary>\r\n    \/\/\/ Snoop's implemetation of GetPixel() which is similar to\r\n    \/\/\/ Bitmap's GetPixel() but should be faster.\r\n    \/\/\/ <\/summary>\r\n    \/\/\/ <param name=\"x\">The pixel's x coordinate<\/param>\r\n    \/\/\/ <param name=\"y\">The pixel's y coordinate<\/param>\r\n    \/\/\/ <returns>The pixel's colour<\/returns>\r\n    public System.Drawing.Color GetPixel(int x, int y)\r\n    {\r\n        \/\/ Better do the 'decent thing' and bounds check x & y\r\n        if (x < 0 || y < 0 || x >= width || y >= width)\r\n            throw new ArgumentException(\"x or y coordinate is out of range\");\r\n\r\n        int a, r, g, b;\r\n\r\n        \/\/ Get a pointer to this pixel\r\n        byte* p = PixelPointer(x, y);\r\n\r\n        \/\/ Pull out its colour data\r\n        b = *p++;\r\n        g = *p++;\r\n        r = *p++;\r\n        a = *p;\r\n\r\n        \/\/ And return a color value for it (this is quite slow\r\n        \/\/ but allows us to look like Bitmap.GetPixel())\r\n        return System.Drawing.Color.FromArgb(a, r, g, b);\r\n    }\r\n\r\n    \/\/\/ <summary>\r\n    \/\/\/ Sets the passed colour to the pixel at (x, y)\r\n    \/\/\/ <\/summary>\r\n    \/\/\/ <param name=\"x\">The pixel's x coordinate<\/param>\r\n    \/\/\/ <param name=\"y\">The pixel's y coordinate<\/param>\r\n    \/\/\/ <param name=\"col\">The value to be assigned to the pixel<\/param>\r\n    public void SetPixel(int x, int y, System.Drawing.Color col)\r\n    {\r\n        \/\/ Better do the 'decent thing' and bounds check x & y\r\n        if (x < 0 || y < 0 || x >= width || y >= width)\r\n            throw new ArgumentException(\"x or y coordinate is out of range\");\r\n\r\n        \/\/ Get a pointer to this pixel\r\n        byte* p = PixelPointer(x, y);\r\n\r\n        \/\/ Set the data\r\n        *p++ = col.B;\r\n        *p++ = col.G;\r\n        *p++ = col.R;\r\n        *p = col.A;\r\n    }\r\n\r\n    \/\/\/ <summary>\r\n    \/\/\/ The bitmap's width\r\n    \/\/\/ <\/summary>\r\n    public int Width { get { return width; } }\r\n\r\n    \/\/ The bitmap's height\r\n    public int Height { get { return height; } }\r\n}\r\n\r\n<\/pre>\n<p>Here is some sample output from the colsone based test program, showing relative times:<\/p>\n<pre>\r\nTesting GetPixel()\r\nGetPixel() OK\r\nTesting SetPixel()\r\nSetPixel() OK\r\nTesting GetPixel() Speed\r\nBitmap.GetPixel() took 759ms, BmpPixelSnoop.GetPixel() took 67ms\r\nTesting SetPixel() Speed\r\nBitmap.SetPixel() took 907ms, BmpPixelSnoop.SetPixel() took 72ms\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Anybody who works with images often have probably come across .Net Bitmaps (System.Drawing.Bitmap) with their staggeringly slow GetPixel() and SetPixel() methods. Now, if you are going to work directly with images then you&#8217;re probably in the wrong place if you are using C# and .Net. However, sometimes you may want to do a small amount [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-2412","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.0.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"Anybody who works with images often have probably come across .Net Bitmaps (System.Drawing.Bitmap) with their staggeringly slow GetPixel() and SetPixel() methods. Now, if you are going to work directly with images then you&#039;re probably in the wrong place if you are using C# and .Net. However, sometimes you may want to do a small amount\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"admin\"\/>\n\t<meta name=\"google-site-verification\" content=\"Kyj52YLp6GOPA44PVBffo9fjW8rgWHYYRF0ZYjfy6ss\" \/>\n\t<link rel=\"canonical\" href=\"https:\/\/www.ridgesolutions.ie\/index.php\/2019\/06\/19\/a-faster-alternative-to-the-slow-getpixel-and-setpixel-for-net-bitmaps\/\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.0.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"Systems and Embedded Software Engineering, Ireland. | Some thoughts of a busy Computer Engineer\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"A faster alternative to the very slow GetPixel() and SetPixel() for .Net System.Drawing.Bitmap\" \/>\n\t\t<meta property=\"og:description\" content=\"Anybody who works with images often have probably come across .Net Bitmaps (System.Drawing.Bitmap) with their staggeringly slow GetPixel() and SetPixel() methods. Now, if you are going to work directly with images then you&#039;re probably in the wrong place if you are using C# and .Net. However, sometimes you may want to do a small amount\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/www.ridgesolutions.ie\/index.php\/2019\/06\/19\/a-faster-alternative-to-the-slow-getpixel-and-setpixel-for-net-bitmaps\/\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-06-19T18:24:19+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-06-20T09:27:19+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary\" \/>\n\t\t<meta name=\"twitter:title\" content=\"A faster alternative to the very slow GetPixel() and SetPixel() for .Net System.Drawing.Bitmap\" \/>\n\t\t<meta name=\"twitter:description\" content=\"Anybody who works with images often have probably come across .Net Bitmaps (System.Drawing.Bitmap) with their staggeringly slow GetPixel() and SetPixel() methods. Now, if you are going to work directly with images then you&#039;re probably in the wrong place if you are using C# and .Net. However, sometimes you may want to do a small amount\" \/>\n\t\t<script type=\"application\/ld+json\" class=\"aioseo-schema\">\n\t\t\t{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.ridgesolutions.ie\\\/index.php\\\/2019\\\/06\\\/19\\\/a-faster-alternative-to-the-slow-getpixel-and-setpixel-for-net-bitmaps\\\/#article\",\"name\":\"A faster alternative to the very slow GetPixel() and SetPixel() for .Net System.Drawing.Bitmap\",\"headline\":\"A faster alternative to the very slow GetPixel() and SetPixel() for .Net System.Drawing.Bitmap\",\"author\":{\"@id\":\"https:\\\/\\\/www.ridgesolutions.ie\\\/index.php\\\/author\\\/admin\\\/#author\"},\"publisher\":{\"@id\":\"https:\\\/\\\/www.ridgesolutions.ie\\\/#organization\"},\"image\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/www.ridgesolutions.ie\\\/wp-content\\\/uploads\\\/2013\\\/09\\\/ridge_logo1.jpg\",\"@id\":\"https:\\\/\\\/www.ridgesolutions.ie\\\/#articleImage\",\"width\":400,\"height\":81},\"datePublished\":\"2019-06-19T19:24:19+00:00\",\"dateModified\":\"2019-06-20T10:27:19+00:00\",\"inLanguage\":\"en-US\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.ridgesolutions.ie\\\/index.php\\\/2019\\\/06\\\/19\\\/a-faster-alternative-to-the-slow-getpixel-and-setpixel-for-net-bitmaps\\\/#webpage\"},\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.ridgesolutions.ie\\\/index.php\\\/2019\\\/06\\\/19\\\/a-faster-alternative-to-the-slow-getpixel-and-setpixel-for-net-bitmaps\\\/#webpage\"},\"articleSection\":\"Uncategorized\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.ridgesolutions.ie\\\/index.php\\\/2019\\\/06\\\/19\\\/a-faster-alternative-to-the-slow-getpixel-and-setpixel-for-net-bitmaps\\\/#breadcrumblist\",\"itemListElement\":[{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.ridgesolutions.ie#listItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.ridgesolutions.ie\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.ridgesolutions.ie\\\/index.php\\\/category\\\/uncategorized\\\/#listItem\",\"name\":\"Uncategorized\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.ridgesolutions.ie\\\/index.php\\\/category\\\/uncategorized\\\/#listItem\",\"position\":2,\"name\":\"Uncategorized\",\"item\":\"https:\\\/\\\/www.ridgesolutions.ie\\\/index.php\\\/category\\\/uncategorized\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.ridgesolutions.ie\\\/index.php\\\/2019\\\/06\\\/19\\\/a-faster-alternative-to-the-slow-getpixel-and-setpixel-for-net-bitmaps\\\/#listItem\",\"name\":\"A faster alternative to the very slow GetPixel() and SetPixel() for .Net System.Drawing.Bitmap\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.ridgesolutions.ie#listItem\",\"name\":\"Home\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.ridgesolutions.ie\\\/index.php\\\/2019\\\/06\\\/19\\\/a-faster-alternative-to-the-slow-getpixel-and-setpixel-for-net-bitmaps\\\/#listItem\",\"position\":3,\"name\":\"A faster alternative to the very slow GetPixel() and SetPixel() for .Net System.Drawing.Bitmap\",\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.ridgesolutions.ie\\\/index.php\\\/category\\\/uncategorized\\\/#listItem\",\"name\":\"Uncategorized\"}}]},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.ridgesolutions.ie\\\/#organization\",\"name\":\"Ridge Solutions, Software Development and Software Engineering, Ireland.\",\"description\":\"Some thoughts of a busy Computer Engineer\",\"url\":\"https:\\\/\\\/www.ridgesolutions.ie\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/www.ridgesolutions.ie\\\/wp-content\\\/uploads\\\/2013\\\/09\\\/ridge_logo1.jpg\",\"@id\":\"https:\\\/\\\/www.ridgesolutions.ie\\\/index.php\\\/2019\\\/06\\\/19\\\/a-faster-alternative-to-the-slow-getpixel-and-setpixel-for-net-bitmaps\\\/#organizationLogo\",\"width\":400,\"height\":81},\"image\":{\"@id\":\"https:\\\/\\\/www.ridgesolutions.ie\\\/index.php\\\/2019\\\/06\\\/19\\\/a-faster-alternative-to-the-slow-getpixel-and-setpixel-for-net-bitmaps\\\/#organizationLogo\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.ridgesolutions.ie\\\/index.php\\\/author\\\/admin\\\/#author\",\"url\":\"https:\\\/\\\/www.ridgesolutions.ie\\\/index.php\\\/author\\\/admin\\\/\",\"name\":\"admin\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\\\/\\\/www.ridgesolutions.ie\\\/index.php\\\/2019\\\/06\\\/19\\\/a-faster-alternative-to-the-slow-getpixel-and-setpixel-for-net-bitmaps\\\/#authorImage\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/0bcb44e82b647e8707b506ed8100bbeb7e4c9a889f1e6fdd152fce740e3ac9fa?s=96&d=mm&r=g\",\"width\":96,\"height\":96,\"caption\":\"admin\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.ridgesolutions.ie\\\/index.php\\\/2019\\\/06\\\/19\\\/a-faster-alternative-to-the-slow-getpixel-and-setpixel-for-net-bitmaps\\\/#webpage\",\"url\":\"https:\\\/\\\/www.ridgesolutions.ie\\\/index.php\\\/2019\\\/06\\\/19\\\/a-faster-alternative-to-the-slow-getpixel-and-setpixel-for-net-bitmaps\\\/\",\"name\":\"A faster alternative to the very slow GetPixel() and SetPixel() for .Net System.Drawing.Bitmap\",\"description\":\"Anybody who works with images often have probably come across .Net Bitmaps (System.Drawing.Bitmap) with their staggeringly slow GetPixel() and SetPixel() methods. Now, if you are going to work directly with images then you're probably in the wrong place if you are using C# and .Net. However, sometimes you may want to do a small amount\",\"inLanguage\":\"en-US\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.ridgesolutions.ie\\\/#website\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.ridgesolutions.ie\\\/index.php\\\/2019\\\/06\\\/19\\\/a-faster-alternative-to-the-slow-getpixel-and-setpixel-for-net-bitmaps\\\/#breadcrumblist\"},\"author\":{\"@id\":\"https:\\\/\\\/www.ridgesolutions.ie\\\/index.php\\\/author\\\/admin\\\/#author\"},\"creator\":{\"@id\":\"https:\\\/\\\/www.ridgesolutions.ie\\\/index.php\\\/author\\\/admin\\\/#author\"},\"datePublished\":\"2019-06-19T19:24:19+00:00\",\"dateModified\":\"2019-06-20T10:27:19+00:00\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.ridgesolutions.ie\\\/#website\",\"url\":\"https:\\\/\\\/www.ridgesolutions.ie\\\/\",\"name\":\"Ridge Solutions, Software Development and Software Engineering, Ireland.\",\"description\":\"Some thoughts of a busy Computer Engineer\",\"inLanguage\":\"en-US\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.ridgesolutions.ie\\\/#organization\"}}]}\n\t\t<\/script>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"A faster alternative to the very slow GetPixel() and SetPixel() for .Net System.Drawing.Bitmap","description":"Anybody who works with images often have probably come across .Net Bitmaps (System.Drawing.Bitmap) with their staggeringly slow GetPixel() and SetPixel() methods. Now, if you are going to work directly with images then you're probably in the wrong place if you are using C# and .Net. However, sometimes you may want to do a small amount","canonical_url":"https:\/\/www.ridgesolutions.ie\/index.php\/2019\/06\/19\/a-faster-alternative-to-the-slow-getpixel-and-setpixel-for-net-bitmaps\/","robots":"max-image-preview:large","keywords":"","webmasterTools":{"google-site-verification":"Kyj52YLp6GOPA44PVBffo9fjW8rgWHYYRF0ZYjfy6ss","miscellaneous":""},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.ridgesolutions.ie\/index.php\/2019\/06\/19\/a-faster-alternative-to-the-slow-getpixel-and-setpixel-for-net-bitmaps\/#article","name":"A faster alternative to the very slow GetPixel() and SetPixel() for .Net System.Drawing.Bitmap","headline":"A faster alternative to the very slow GetPixel() and SetPixel() for .Net System.Drawing.Bitmap","author":{"@id":"https:\/\/www.ridgesolutions.ie\/index.php\/author\/admin\/#author"},"publisher":{"@id":"https:\/\/www.ridgesolutions.ie\/#organization"},"image":{"@type":"ImageObject","url":"https:\/\/www.ridgesolutions.ie\/wp-content\/uploads\/2013\/09\/ridge_logo1.jpg","@id":"https:\/\/www.ridgesolutions.ie\/#articleImage","width":400,"height":81},"datePublished":"2019-06-19T19:24:19+00:00","dateModified":"2019-06-20T10:27:19+00:00","inLanguage":"en-US","mainEntityOfPage":{"@id":"https:\/\/www.ridgesolutions.ie\/index.php\/2019\/06\/19\/a-faster-alternative-to-the-slow-getpixel-and-setpixel-for-net-bitmaps\/#webpage"},"isPartOf":{"@id":"https:\/\/www.ridgesolutions.ie\/index.php\/2019\/06\/19\/a-faster-alternative-to-the-slow-getpixel-and-setpixel-for-net-bitmaps\/#webpage"},"articleSection":"Uncategorized"},{"@type":"BreadcrumbList","@id":"https:\/\/www.ridgesolutions.ie\/index.php\/2019\/06\/19\/a-faster-alternative-to-the-slow-getpixel-and-setpixel-for-net-bitmaps\/#breadcrumblist","itemListElement":[{"@type":"ListItem","@id":"https:\/\/www.ridgesolutions.ie#listItem","position":1,"name":"Home","item":"https:\/\/www.ridgesolutions.ie","nextItem":{"@type":"ListItem","@id":"https:\/\/www.ridgesolutions.ie\/index.php\/category\/uncategorized\/#listItem","name":"Uncategorized"}},{"@type":"ListItem","@id":"https:\/\/www.ridgesolutions.ie\/index.php\/category\/uncategorized\/#listItem","position":2,"name":"Uncategorized","item":"https:\/\/www.ridgesolutions.ie\/index.php\/category\/uncategorized\/","nextItem":{"@type":"ListItem","@id":"https:\/\/www.ridgesolutions.ie\/index.php\/2019\/06\/19\/a-faster-alternative-to-the-slow-getpixel-and-setpixel-for-net-bitmaps\/#listItem","name":"A faster alternative to the very slow GetPixel() and SetPixel() for .Net System.Drawing.Bitmap"},"previousItem":{"@type":"ListItem","@id":"https:\/\/www.ridgesolutions.ie#listItem","name":"Home"}},{"@type":"ListItem","@id":"https:\/\/www.ridgesolutions.ie\/index.php\/2019\/06\/19\/a-faster-alternative-to-the-slow-getpixel-and-setpixel-for-net-bitmaps\/#listItem","position":3,"name":"A faster alternative to the very slow GetPixel() and SetPixel() for .Net System.Drawing.Bitmap","previousItem":{"@type":"ListItem","@id":"https:\/\/www.ridgesolutions.ie\/index.php\/category\/uncategorized\/#listItem","name":"Uncategorized"}}]},{"@type":"Organization","@id":"https:\/\/www.ridgesolutions.ie\/#organization","name":"Ridge Solutions, Software Development and Software Engineering, Ireland.","description":"Some thoughts of a busy Computer Engineer","url":"https:\/\/www.ridgesolutions.ie\/","logo":{"@type":"ImageObject","url":"https:\/\/www.ridgesolutions.ie\/wp-content\/uploads\/2013\/09\/ridge_logo1.jpg","@id":"https:\/\/www.ridgesolutions.ie\/index.php\/2019\/06\/19\/a-faster-alternative-to-the-slow-getpixel-and-setpixel-for-net-bitmaps\/#organizationLogo","width":400,"height":81},"image":{"@id":"https:\/\/www.ridgesolutions.ie\/index.php\/2019\/06\/19\/a-faster-alternative-to-the-slow-getpixel-and-setpixel-for-net-bitmaps\/#organizationLogo"}},{"@type":"Person","@id":"https:\/\/www.ridgesolutions.ie\/index.php\/author\/admin\/#author","url":"https:\/\/www.ridgesolutions.ie\/index.php\/author\/admin\/","name":"admin","image":{"@type":"ImageObject","@id":"https:\/\/www.ridgesolutions.ie\/index.php\/2019\/06\/19\/a-faster-alternative-to-the-slow-getpixel-and-setpixel-for-net-bitmaps\/#authorImage","url":"https:\/\/secure.gravatar.com\/avatar\/0bcb44e82b647e8707b506ed8100bbeb7e4c9a889f1e6fdd152fce740e3ac9fa?s=96&d=mm&r=g","width":96,"height":96,"caption":"admin"}},{"@type":"WebPage","@id":"https:\/\/www.ridgesolutions.ie\/index.php\/2019\/06\/19\/a-faster-alternative-to-the-slow-getpixel-and-setpixel-for-net-bitmaps\/#webpage","url":"https:\/\/www.ridgesolutions.ie\/index.php\/2019\/06\/19\/a-faster-alternative-to-the-slow-getpixel-and-setpixel-for-net-bitmaps\/","name":"A faster alternative to the very slow GetPixel() and SetPixel() for .Net System.Drawing.Bitmap","description":"Anybody who works with images often have probably come across .Net Bitmaps (System.Drawing.Bitmap) with their staggeringly slow GetPixel() and SetPixel() methods. Now, if you are going to work directly with images then you're probably in the wrong place if you are using C# and .Net. However, sometimes you may want to do a small amount","inLanguage":"en-US","isPartOf":{"@id":"https:\/\/www.ridgesolutions.ie\/#website"},"breadcrumb":{"@id":"https:\/\/www.ridgesolutions.ie\/index.php\/2019\/06\/19\/a-faster-alternative-to-the-slow-getpixel-and-setpixel-for-net-bitmaps\/#breadcrumblist"},"author":{"@id":"https:\/\/www.ridgesolutions.ie\/index.php\/author\/admin\/#author"},"creator":{"@id":"https:\/\/www.ridgesolutions.ie\/index.php\/author\/admin\/#author"},"datePublished":"2019-06-19T19:24:19+00:00","dateModified":"2019-06-20T10:27:19+00:00"},{"@type":"WebSite","@id":"https:\/\/www.ridgesolutions.ie\/#website","url":"https:\/\/www.ridgesolutions.ie\/","name":"Ridge Solutions, Software Development and Software Engineering, Ireland.","description":"Some thoughts of a busy Computer Engineer","inLanguage":"en-US","publisher":{"@id":"https:\/\/www.ridgesolutions.ie\/#organization"}}]},"og:locale":"en_US","og:site_name":"Systems and Embedded Software Engineering, Ireland. | Some thoughts of a busy Computer Engineer","og:type":"article","og:title":"A faster alternative to the very slow GetPixel() and SetPixel() for .Net System.Drawing.Bitmap","og:description":"Anybody who works with images often have probably come across .Net Bitmaps (System.Drawing.Bitmap) with their staggeringly slow GetPixel() and SetPixel() methods. Now, if you are going to work directly with images then you're probably in the wrong place if you are using C# and .Net. However, sometimes you may want to do a small amount","og:url":"https:\/\/www.ridgesolutions.ie\/index.php\/2019\/06\/19\/a-faster-alternative-to-the-slow-getpixel-and-setpixel-for-net-bitmaps\/","article:published_time":"2019-06-19T18:24:19+00:00","article:modified_time":"2019-06-20T09:27:19+00:00","twitter:card":"summary","twitter:title":"A faster alternative to the very slow GetPixel() and SetPixel() for .Net System.Drawing.Bitmap","twitter:description":"Anybody who works with images often have probably come across .Net Bitmaps (System.Drawing.Bitmap) with their staggeringly slow GetPixel() and SetPixel() methods. Now, if you are going to work directly with images then you're probably in the wrong place if you are using C# and .Net. However, sometimes you may want to do a small amount"},"aioseo_meta_data":{"post_id":"2412","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"Article","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"breadcrumb_settings":null,"limit_modified_date":false,"ai":null,"created":"2021-09-13 14:48:47","updated":"2025-07-15 23:22:44","seo_analyzer_scan_date":null,"focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"aioseo_breadcrumb":"<div class=\"aioseo-breadcrumbs\"><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.ridgesolutions.ie\" title=\"Home\">Home<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.ridgesolutions.ie\/index.php\/category\/uncategorized\/\" title=\"Uncategorized\">Uncategorized<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\tA faster alternative to the very slow GetPixel() and SetPixel() for .Net System.Drawing.Bitmap\n\t\t<\/span><\/div>","aioseo_breadcrumb_json":[{"label":"Home","link":"https:\/\/www.ridgesolutions.ie"},{"label":"Uncategorized","link":"https:\/\/www.ridgesolutions.ie\/index.php\/category\/uncategorized\/"},{"label":"A faster alternative to the very slow GetPixel() and SetPixel() for .Net System.Drawing.Bitmap","link":"https:\/\/www.ridgesolutions.ie\/index.php\/2019\/06\/19\/a-faster-alternative-to-the-slow-getpixel-and-setpixel-for-net-bitmaps\/"}],"_links":{"self":[{"href":"https:\/\/www.ridgesolutions.ie\/index.php\/wp-json\/wp\/v2\/posts\/2412","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.ridgesolutions.ie\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.ridgesolutions.ie\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.ridgesolutions.ie\/index.php\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/www.ridgesolutions.ie\/index.php\/wp-json\/wp\/v2\/comments?post=2412"}],"version-history":[{"count":0,"href":"https:\/\/www.ridgesolutions.ie\/index.php\/wp-json\/wp\/v2\/posts\/2412\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.ridgesolutions.ie\/index.php\/wp-json\/wp\/v2\/media?parent=2412"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.ridgesolutions.ie\/index.php\/wp-json\/wp\/v2\/categories?post=2412"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.ridgesolutions.ie\/index.php\/wp-json\/wp\/v2\/tags?post=2412"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}