In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article introduces the relevant knowledge of "what are the Bitmap image processing methods of C#". In the operation of actual cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!
Bitmap class
Bitmap object encapsulates a bitmap in GDI+, which is composed of pixel data of graphic image and its attributes. Therefore, Bitmap is an object used to process images defined by pixel data. The main methods and properties of this class are as follows:
1. GetPixel method and SetPixel method: gets and sets the color of a specified pixel of an image.
2. PixelFormat attribute: returns the pixel format of the image.
3. Palette property: gets and sets the color palette used by the image.
4. Height Width property: returns the height and width of the image.
5. LockBits method and UnlockBits method: lock and unlock bitmap pixels in system memory respectively. It is a good way to use LockBits and UnlockBits in pixel-based image processing methods. These two methods enable us to specify the range of pixels to control any part of the bitmap, thus eliminating the need to cycle through the processing of bitmap pixels one by one. After each call to LockBits, UnlockBits should be called.
BitmapData class
The BitmapData object specifies the properties of the bitmap
1. Height attribute: the height of the locked positioning map.
2. Width attribute: the width of the locked positioning map.
3. PixelFormat attribute: the actual pixel format of the data.
4. Scan0 attribute: the first byte address of the locked array, or the first byte address of the image if the whole image is locked.
5. Stride attribute: stride, also known as scan width.
Here to focus on the Stride attribute, what is the difference between this and Width, it can be said that if your picture size, that is, the picture byte is an integer multiple of 4, then Stride and Width are equal, otherwise Stride is an integer multiple greater than the minimum 4 of Width. In the process of processing, Stride must be an integer multiple of 4. This is a pit.
Example 1: there is an one-dimensional pixel lattice array, in which is the gray value of each pixel, knowing the width and height, to convert to bitmap
/ convert pixel matrix to bitmap/// byte [] array / width of picture / / height of picture / bitmap picture public static Bitmap ToGrayBitmap (byte [] rawValues, int width, int height) {Bitmap bmp = new Bitmap (width, height, System.Drawing.Imaging.PixelFormat.Format8bppIndexed); BitmapData bmpData = bmp.LockBits (new System.Drawing.Rectangle (0,0, width, height), ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format8bppIndexed) Get the image parameter / / bmpData.Stride = width; int stride = bmpData.Stride; / / the width of the scan line int offset = stride-width; / / the gap between the display width and the width of the scan line IntPtr iptr = bmpData.Scan0; / / get the memory start position of the bmpData int scanBytes = stride * height / / use the stride width to indicate that this is the size of the memory area. Below, convert the original display size byte array to the actual stored byte array in memory int posScan = 0, posReal = 0; set two position pointers to the source array and the target array byte [] pixelValues = new byte [scanBytes]; / / allocate memory for for the target array (int x = 0; x)
< height; x++) { 下面的循环节是模拟行扫描 for (int y = 0; y < width; y++) { pixelValues[posScan++] = rawValues[posReal++]; } posScan += offset; //行扫描结束,要将目标位置指针移过那段"间隙" } 用Marshal的Copy方法,将刚才得到的内存字节数组复制到BitmapData中 System.Runtime.InteropServices.Marshal.Copy(pixelValues, 0, iptr, scanBytes); bmp.UnlockBits(bmpData); // 解锁内存区域 下面的代码是为了修改生成位图的索引表,从伪彩修改为灰度 ColorPalette tempPalette; using (Bitmap tempBmp = new Bitmap(1, 1, System.Drawing.Imaging.PixelFormat.Format8bppIndexed)) { tempPalette = tempBmp.Palette; } for (int i = 0; i < 256; i++) { tempPalette.Entries[i] = System.Drawing.Color.FromArgb(i, i, i); } bmp.Palette = tempPalette; 算法到此结束,返回结果 return bmp;} 至于24位位图数据其实就是 一个像素点有rgb三个值而已,道理一样。 例2::根据图片得到他的灰度数组 //8位位图得到除去文件头信息的一位灰度数组 BitmapData bmpData = map.LockBits(new System.Drawing.Rectangle(0, 0, map.Width, map.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format8bppIndexed); 获取图像参数 int stride = bmpData.Stride; // 扫描线的宽度 int offset = stride - map.Width; // 显示宽度与扫描线宽度的间隙 IntPtr iptr = bmpData.Scan0; // 获取bmpData的内存起始位置 int scanBytes = stride * map.Height;// 用stride宽度,表示这是内存区域的大小 下面把原始的显示大小字节数组转换为内存中实际存放的字节数组 mapdata = new byte[scanBytes]; //为目标数组分配内存 System.Runtime.InteropServices.Marshal.Copy(iptr, mapdata, 0, scanBytes); //copy内存中数据到数组中 这里对与bitmapdata的操作方式是ReadOnly 下面的三个例子分别基于像素(GetPixel和SetPixel)、基于内存、基于指针这三种方法增强图片对比度。均测试通过 运行时间: 1)基于像素:400-600ms 2)基于内存:17-18ms 3)基于指针:20-23ms 利用LUT,应该可以进一步减少运行时间 // 第一种方法:像素提取法。速度慢 public Bitmap MethodBaseOnPixel(Bitmap bitmap,int degree) { Color curColor; int grayR, grayG, grayB; double Deg = (100.0 + degree) / 100.0; for (int i = 0; i < bitmap.Width; i++) { for (int j = 0; j < bitmap.Height; j++) { curColor = bitmap.GetPixel(i, j); grayR =Convert.ToInt32((((curColor.R / 255.0 - 0.5) * Deg + 0.5)) * 255); grayG = Convert.ToInt32((((curColor.G / 255.0 - 0.5) * Deg + 0.5)) * 255); grayB = Convert.ToInt32((((curColor.B / 255.0 - 0.5) * Deg + 0.5)) * 255); if (grayR < 0) grayR = 0; else if (grayR >GrayR = 255; if (grayB
< 0) grayB = 0; else if (grayB >GrayB = 255; if (grayG
< 0) grayG = 0; else if (grayG >GrayG = 255; bitmap.SetPixel (I, j, Color.FromArgb (grayR, grayG, grayB));}} return bitmap Second method: based on memory public unsafe Bitmap MethodBaseOnMemory (Bitmap bitmap, int degree) {if (bitmap = = null) {return null;} double Deg = (100.0 + degree) / 100.0; int width = bitmap.Width; int height = bitmap.Height Int length = height * 3 * width; byte [] RGB = new byte [length]; BitmapData data = bitmap.LockBits (new Rectangle (0,0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); System.IntPtr Scan0 = data.Scan0; System.Runtime.InteropServices.Marshal.Copy (Scan0, RGB, 0, length); double gray = 0; for (int I = 0; I
< RGB.Length; i += 3) { for (int j = 0; j < 3; j++) { gray = (((RGB[i + j] / 255.0 -0.5) * Deg+0.5)) * 255.0; if (gray >Gray = 255; if (gray
< 0) gray = 0; RGB[i + j] = (byte) gray; } } System.Runtime.InteropServices.Marshal.Copy(RGB, 0, Scan0, length);// 此处Copy是之前Copy的逆操作 bitmap.UnlockBits(data); return bitmap; } }//第三种方法:基于指针 public unsafe Bitmap MethodBaseOnPtr(Bitmap b, int degree) { if (b == null) { return null; } try { double num = 0.0; double num2 = (100.0 + degree) / 100.0; num2 *= num2; int width = b.Width; int height = b.Height; BitmapData bitmapdata = b.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); byte* numPtr = (byte*)bitmapdata.Scan0; int offset = bitmapdata.Stride - (width * 3); for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { for (int k = 0; k < 3; k++) { num = ((((((double)numPtr[k]) / 255.0) - 0.5) * num2) + 0.5) * 255.0; if (num < 0.0) { num = 0.0; } if (num >255.0) {num = 255.0;} numPtr [k] = (byte) num;} numPtr + = 3 } numPtr + = offset;} b.UnlockBits (bitmapdata); return b;} catch {return b This is the end of the content of "what are the Bitmap image processing methods of C#". Thank you for your reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.