Image Binarization
-
I load an image, convert it to bitmapData using the 24bppRGB pixel format, binarize it using a simple routine (shown below) and save it using the Image.Save() method. The image saved however is still 24bppRGB - although all colours have the same value, either 0 or 255 - and shows up as an RGB image in Photoshop. Any ideas on how I can change it to binary, ie a 1bpp format? Code: ------ Bitmap bMap=new Bitmap (iMage); BitmapData bData = bMap.LockBits(new Rectangle(0, 0, bMap.Width, bMap.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); System.IntPtr Scan0 = bData.Scan0; int iStride=bData.Stride; int iht=bMap.Height; int iwd=bMap.Width; int iPix=new int[iht][]; unsafe { byte *p = (byte*)(void*)Scan0; int nOffset = iStride-iwd*3; for(int y=0;y
-
I load an image, convert it to bitmapData using the 24bppRGB pixel format, binarize it using a simple routine (shown below) and save it using the Image.Save() method. The image saved however is still 24bppRGB - although all colours have the same value, either 0 or 255 - and shows up as an RGB image in Photoshop. Any ideas on how I can change it to binary, ie a 1bpp format? Code: ------ Bitmap bMap=new Bitmap (iMage); BitmapData bData = bMap.LockBits(new Rectangle(0, 0, bMap.Width, bMap.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); System.IntPtr Scan0 = bData.Scan0; int iStride=bData.Stride; int iht=bMap.Height; int iwd=bMap.Width; int iPix=new int[iht][]; unsafe { byte *p = (byte*)(void*)Scan0; int nOffset = iStride-iwd*3; for(int y=0;y
You need to convert it to a different format. It won't magically detect how many colours you've used and therefore change itself. There is a Clone method that takes a bit depth, but I think it's buggy. You can create a new image of the required bit depth and copy your old image onto the new. Or you could create a new image to start with of the right bit depth, and set it's values instead of setting values on your existing image. Christian Graus - Microsoft MVP - C++
-
You need to convert it to a different format. It won't magically detect how many colours you've used and therefore change itself. There is a Clone method that takes a bit depth, but I think it's buggy. You can create a new image of the required bit depth and copy your old image onto the new. Or you could create a new image to start with of the right bit depth, and set it's values instead of setting values on your existing image. Christian Graus - Microsoft MVP - C++
Thanks Christian, I found a solution from: http://www.bobpowell.net/onebit.htm Here's what I did: // new bitmap Bitmap bm=new Bitmap(iwd, iht,PixelFormat.Format1bppIndexed); BitmapData bmdn=bm.LockBits(new Rectangle(0,0,bm.Width,bm.Height),ImageLockMode.ReadWrite,PixelFormat.Format1bppIndexed); // variables int iIndex; byte bP, bMask; for(int y=0;y>3); bP=Marshal.ReadByte(bmdn.Scan0,iIndex); bMask=(byte)(0x80>>(x&0x7)); if (ConditionA) bP|=bMask; else bP &=(byte)(bMask^0xff); Marshal.WriteByte(bmdn.Scan0,iIndex,bP); } } bm.UnlockBits(bmdn);
-
Thanks Christian, I found a solution from: http://www.bobpowell.net/onebit.htm Here's what I did: // new bitmap Bitmap bm=new Bitmap(iwd, iht,PixelFormat.Format1bppIndexed); BitmapData bmdn=bm.LockBits(new Rectangle(0,0,bm.Width,bm.Height),ImageLockMode.ReadWrite,PixelFormat.Format1bppIndexed); // variables int iIndex; byte bP, bMask; for(int y=0;y>3); bP=Marshal.ReadByte(bmdn.Scan0,iIndex); bMask=(byte)(0x80>>(x&0x7)); if (ConditionA) bP|=bMask; else bP &=(byte)(bMask^0xff); Marshal.WriteByte(bmdn.Scan0,iIndex,bP); } } bm.UnlockBits(bmdn);
What is ConditionA ? This looks to me like it could be a lot slower than your old code ? Either way, it's what I said to do - create a 1 bpp image to write to. Christian Graus - Microsoft MVP - C++
-
What is ConditionA ? This looks to me like it could be a lot slower than your old code ? Either way, it's what I said to do - create a 1 bpp image to write to. Christian Graus - Microsoft MVP - C++
I have a 2-dimensional integer array of the same width and height of the image, each of whose elements is either 1 or 0. Condition A just checks whether the corresponding element in the array is a 1 or a 0, and sets the pixel accordingly There doesn't seem to be a major drop in the time taken by the overall routine though. Do you have any suggestions? Sarabjit.
-
I have a 2-dimensional integer array of the same width and height of the image, each of whose elements is either 1 or 0. Condition A just checks whether the corresponding element in the array is a 1 or a 0, and sets the pixel accordingly There doesn't seem to be a major drop in the time taken by the overall routine though. Do you have any suggestions? Sarabjit.
If it's just an array lookup, then it probably is fine, I thought it may be missing () and be a function call that did goodness knows what. Christian Graus - Microsoft MVP - C++
-
If it's just an array lookup, then it probably is fine, I thought it may be missing () and be a function call that did goodness knows what. Christian Graus - Microsoft MVP - C++