C# 三个使用LockBits设置图形颜色
2009-01-21 13:05
603 查看
第1个方法 我们要根据图形边缘的色彩来设置图形的颜色
使用方法
效果
第2个方法 设置全部的颜色
效果
第2个方法 根据坐标设置 相当于漏斗功能.
效果
下面是全部代码
使用方法
Bitmap _Bitmap = new Bitmap(100,100); Graphics _Graphics = Graphics.FromImage(_Bitmap); _Graphics.Clear(Color.Black); _Graphics.DrawString("+", new Font("宋体", 80), Brushes.Yellow, 0, 0); _Graphics.Dispose(); pictureBox1.Image = _Bitmap; pictureBox2.Image = Zgke.MyImage.Paint.SetImageColorBrim(_Bitmap, Color.Black, Color.Red, 20);
效果
第2个方法 设置全部的颜色
Bitmap _Bitmap = new Bitmap(100,100); Graphics _Graphics = Graphics.FromImage(_Bitmap); _Graphics.Clear(Color.Black); _Graphics.DrawString("0", new Font("宋体", 80), Brushes.Yellow, 0, 0); _Graphics.Dispose(); pictureBox1.Image = _Bitmap; pictureBox2.Image = Zgke.MyImage.Paint.SetImageColorAll(_Bitmap, Color.Black, Color.Red, 20);
效果
第2个方法 根据坐标设置 相当于漏斗功能.
Bitmap _Bitmap = new Bitmap(100,100); Graphics _Graphics = Graphics.FromImage(_Bitmap); _Graphics.Clear(Color.Black); _Graphics.DrawString("0", new Font("宋体", 80), Brushes.Yellow, 0, 0); _Graphics.Dispose(); pictureBox1.Image = _Bitmap; pictureBox2.Image = Zgke.MyImage.Paint.SetImageColorPoint(_Bitmap, new Point(0, 0), Color.Blue, 0);
效果
下面是全部代码
using System; using System.Collections.Generic; using System.Drawing; using System.Collections; using System.Data; using System.Text; using System.Drawing.Imaging; using System.Runtime.InteropServices; namespace Zgke.MyImage { /// <summary> /// 色彩简单处理 /// zgke@sina.com /// QQ:116149 /// </summary> public class Paint { #region 色彩处理 /// <summary> /// 设置图形颜色 边缘的色彩更换成新的颜色 /// </summary> /// <param name="p_Image">图片</param> /// <param name="p_OldColor">老的边缘色彩</param> /// <param name="p_NewColor">新的边缘色彩</param> /// <param name="p_Float">溶差</param> /// <returns>清理后的图形</returns> public static Image SetImageColorBrim(Image p_Image, Color p_OldColor, Color p_NewColor, int p_Float) { int _Width = p_Image.Width; int _Height = p_Image.Height; Bitmap _NewBmp = new Bitmap(_Width, _Height, PixelFormat.Format32bppArgb); Graphics _Graphics = Graphics.FromImage(_NewBmp); _Graphics.DrawImage(p_Image, new Rectangle(0, 0, _Width, _Height)); _Graphics.Dispose(); BitmapData _Data = _NewBmp.LockBits(new Rectangle(0, 0, _Width, _Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); _Data.PixelFormat = PixelFormat.Format32bppArgb; int _ByteSize = _Data.Stride * _Height; byte[] _DataBytes = new byte[_ByteSize]; Marshal.Copy(_Data.Scan0, _DataBytes, 0, _ByteSize); int _Index = 0; #region 列 for (int z = 0; z != _Height; z++) { _Index = z * _Data.Stride; for (int i = 0; i != _Width; i++) { Color _Color = Color.FromArgb(_DataBytes[_Index + 3], _DataBytes[_Index + 2], _DataBytes[_Index + 1], _DataBytes[_Index]); if (ScanColor(_Color, p_OldColor, p_Float)) { _DataBytes[_Index + 3] = (byte)p_NewColor.A; _DataBytes[_Index + 2] = (byte)p_NewColor.R; _DataBytes[_Index + 1] = (byte)p_NewColor.G; _DataBytes[_Index] = (byte)p_NewColor.B; _Index += 4; } else { break; } } _Index = (z + 1) * _Data.Stride; for (int i = 0; i != _Width; i++) { Color _Color = Color.FromArgb(_DataBytes[_Index - 1], _DataBytes[_Index - 2], _DataBytes[_Index - 3], _DataBytes[_Index - 4]); if (ScanColor(_Color, p_OldColor, p_Float)) { _DataBytes[_Index - 1] = (byte)p_NewColor.A; _DataBytes[_Index - 2] = (byte)p_NewColor.R; _DataBytes[_Index - 3] = (byte)p_NewColor.G; _DataBytes[_Index - 4] = (byte)p_NewColor.B; _Index -= 4; } else { break; } } } #endregion #region 行 for (int i = 0; i != _Width; i++) { _Index = i * 4; for (int z = 0; z != _Height; z++) { Color _Color = Color.FromArgb(_DataBytes[_Index + 3], _DataBytes[_Index + 2], _DataBytes[_Index + 1], _DataBytes[_Index]); if (ScanColor(_Color, p_OldColor, p_Float)) { _DataBytes[_Index + 3] = (byte)p_NewColor.A; _DataBytes[_Index + 2] = (byte)p_NewColor.R; _DataBytes[_Index + 1] = (byte)p_NewColor.G; _DataBytes[_Index] = (byte)p_NewColor.B; _Index += _Data.Stride; } else { break; } } _Index = (i * 4) + ((_Height - 1) * _Data.Stride); for (int z = 0; z != _Height; z++) { Color _Color = Color.FromArgb(_DataBytes[_Index + 3], _DataBytes[_Index + 2], _DataBytes[_Index + 1], _DataBytes[_Index]); if (ScanColor(_Color, p_OldColor, p_Float)) { _DataBytes[_Index + 3] = (byte)p_NewColor.A; _DataBytes[_Index + 2] = (byte)p_NewColor.R; _DataBytes[_Index + 1] = (byte)p_NewColor.G; _DataBytes[_Index] = (byte)p_NewColor.B; _Index -= _Data.Stride; } else { break; } } } #endregion Marshal.Copy(_DataBytes, 0, _Data.Scan0, _ByteSize); _NewBmp.UnlockBits(_Data); return _NewBmp; } /// <summary> /// 设置图形颜色 所有的色彩更换成新的颜色 /// </summary> /// <param name="p_Image">图片</param> /// <param name="p_OdlColor">老的颜色</param> /// <param name="p_NewColor">新的颜色</param> /// <param name="p_Float">溶差</param> /// <returns>清理后的图形</returns> public static Image SetImageColorAll(Image p_Image, Color p_OdlColor, Color p_NewColor, int p_Float) { int _Width = p_Image.Width; int _Height = p_Image.Height; Bitmap _NewBmp = new Bitmap(_Width, _Height, PixelFormat.Format32bppArgb); Graphics _Graphics = Graphics.FromImage(_NewBmp); _Graphics.DrawImage(p_Image, new Rectangle(0, 0, _Width, _Height)); _Graphics.Dispose(); BitmapData _Data = _NewBmp.LockBits(new Rectangle(0, 0, _Width, _Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); _Data.PixelFormat = PixelFormat.Format32bppArgb; int _ByteSize = _Data.Stride * _Height; byte[] _DataBytes = new byte[_ByteSize]; Marshal.Copy(_Data.Scan0, _DataBytes, 0, _ByteSize); int _WhileCount = _Width * _Height; int _Index = 0; for (int i = 0; i != _WhileCount; i++) { Color _Color = Color.FromArgb(_DataBytes[_Index + 3], _DataBytes[_Index + 2], _DataBytes[_Index + 1], _DataBytes[_Index]); if (ScanColor(_Color, p_OdlColor, p_Float)) { _DataBytes[_Index + 3] = (byte)p_NewColor.A; _DataBytes[_Index + 2] = (byte)p_NewColor.R; _DataBytes[_Index + 1] = (byte)p_NewColor.G; _DataBytes[_Index] = (byte)p_NewColor.B; } _Index += 4; } Marshal.Copy(_DataBytes, 0, _Data.Scan0, _ByteSize); _NewBmp.UnlockBits(_Data); return _NewBmp; } /// <summary> /// 设置图形颜色 坐标的颜色更换成新的色彩 (漏斗) /// </summary> /// <param name="p_Image">新图形</param> /// <param name="p_Point">位置</param> /// <param name="p_NewColor">新的色彩</param> /// <param name="p_Float">溶差</param> /// <returns>清理后的图形</returns> public static Image SetImageColorPoint(Image p_Image, Point p_Point, Color p_NewColor, int p_Float) { int _Width = p_Image.Width; int _Height = p_Image.Height; if (p_Point.X > _Width - 1) return p_Image; if (p_Point.Y > _Height - 1) return p_Image; Bitmap _SS = (Bitmap)p_Image; Color _Scolor = _SS.GetPixel(p_Point.X, p_Point.Y); Bitmap _NewBmp = new Bitmap(_Width, _Height, PixelFormat.Format32bppArgb); Graphics _Graphics = Graphics.FromImage(_NewBmp); _Graphics.DrawImage(p_Image, new Rectangle(0, 0, _Width, _Height)); _Graphics.Dispose(); BitmapData _Data = _NewBmp.LockBits(new Rectangle(0, 0, _Width, _Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); _Data.PixelFormat = PixelFormat.Format32bppArgb; int _ByteSize = _Data.Stride * _Height; byte[] _DataBytes = new byte[_ByteSize]; Marshal.Copy(_Data.Scan0, _DataBytes, 0, _ByteSize); int _Index = (p_Point.Y * _Data.Stride) + (p_Point.X * 4); Color _OldColor = Color.FromArgb(_DataBytes[_Index + 3], _DataBytes[_Index + 2], _DataBytes[_Index + 1], _DataBytes[_Index]); if (_OldColor.Equals(p_NewColor)) return p_Image; Stack<Point> _ColorStack = new Stack<Point>(1000); _ColorStack.Push(p_Point); _DataBytes[_Index + 3] = (byte)p_NewColor.A; _DataBytes[_Index + 2] = (byte)p_NewColor.R; _DataBytes[_Index + 1] = (byte)p_NewColor.G; _DataBytes[_Index] = (byte)p_NewColor.B; do { Point _NewPoint = (Point)_ColorStack.Pop(); if (_NewPoint.X > 0) SetImageColorPoint(_DataBytes, _Data.Stride, _ColorStack, _NewPoint.X - 1, _NewPoint.Y, _OldColor, p_NewColor, p_Float); if (_NewPoint.Y > 0) SetImageColorPoint(_DataBytes, _Data.Stride, _ColorStack, _NewPoint.X, _NewPoint.Y - 1, _OldColor, p_NewColor, p_Float); if (_NewPoint.X < _Width - 1) SetImageColorPoint(_DataBytes, _Data.Stride, _ColorStack, _NewPoint.X + 1, _NewPoint.Y, _OldColor, p_NewColor, p_Float); if (_NewPoint.Y < _Height - 1) SetImageColorPoint(_DataBytes, _Data.Stride, _ColorStack, _NewPoint.X, _NewPoint.Y + 1, _OldColor, p_NewColor, p_Float); } while (_ColorStack.Count > 0); Marshal.Copy(_DataBytes, 0, _Data.Scan0, _ByteSize); _NewBmp.UnlockBits(_Data); return _NewBmp; } /// <summary> /// SetImageColorPoint 循环调用 检查新的坐标是否符合条件 符合条件会写入栈p_ColorStack 并更改颜色 /// </summary> /// <param name="p_DataBytes">数据区</param> /// <param name="p_Stride">行扫描字节数</param> /// <param name="p_ColorStack">需要检查的位置栈</param> /// <param name="p_X">位置X</param> /// <param name="p_Y">位置Y</param> /// <param name="p_OldColor">老色彩</param> /// <param name="p_NewColor">新色彩</param> /// <param name="p_Float">溶差</param> private static void SetImageColorPoint(byte[] p_DataBytes, int p_Stride, Stack<Point> p_ColorStack, int p_X, int p_Y, Color p_OldColor, Color p_NewColor, int p_Float) { int _Index = (p_Y * p_Stride) + (p_X * 4); Color _OldColor = Color.FromArgb(p_DataBytes[_Index + 3], p_DataBytes[_Index + 2], p_DataBytes[_Index + 1], p_DataBytes[_Index]); if (ScanColor(_OldColor, p_OldColor, p_Float)) { p_ColorStack.Push(new Point(p_X, p_Y)); p_DataBytes[_Index + 3] = (byte)p_NewColor.A; p_DataBytes[_Index + 2] = (byte)p_NewColor.R; p_DataBytes[_Index + 1] = (byte)p_NewColor.G; p_DataBytes[_Index] = (byte)p_NewColor.B; } } /// <summary> /// 检查色彩(可以根据这个更改比较方式 /// </summary> /// <param name="p_CurrentlyColor">当前色彩</param> /// <param name="p_CompareColor">比较色彩</param> /// <param name="p_Float">溶差</param> /// <returns></returns> private static bool ScanColor(Color p_CurrentlyColor, Color p_CompareColor, int p_Float) { int _R = p_CurrentlyColor.R; int _G = p_CurrentlyColor.G; int _B = p_CurrentlyColor.B; return (_R <= p_CompareColor.R + p_Float && _R >= p_CompareColor.R - p_Float) && (_G <= p_CompareColor.G + p_Float && _G >= p_CompareColor.G - p_Float) && (_B <= p_CompareColor.B + p_Float && _B >= p_CompareColor.B - p_Float); } #endregion } }
相关文章推荐
- C#的Bitmap.LockBits 使用说明
- Panel设置透明属性 C#中颜色的使用
- 图形的绘制,如何使用自定义画笔(颜色,线宽,线形)。如何为程序中添加选项菜单和选项设置对话框,如何使用标准颜色对话框,如何使用字体对话框,在选项对话框中实现预览功能。实现选项对话框和窗口类中的数据交换。如何改变对话框和控件的背景色,如何改变控件的文本颜色,
- Panel设置透明属性 C#中颜色的使用
- [重点是调透明度]Panel设置透明属性 C#中颜色的使用
- eclipse的入门使用,项目的创建删除,项目的导入导出,eclipse的字体和颜色设置,控制台的字体设置,
- 浅谈c#中使用lock的是与非
- 使用Drawble文件实现圆角,填充颜色,边框等属性的设置(Android)
- 在C#中使用ObjectDBX技术从未打开的AutoCAD图形中获得
- C#中缓存的简单方法及使用Sql设置缓存依赖项
- C#使用WinAPI 修改电源设置,临时禁止笔记本合上盖子时睡眠
- 添加C# ProtoGen List set方法 ,使用反射设置属性的值
- C#学习笔记:设置label(标签)控件的背景颜色为透明
- C#使用Monitor类、Lock和Mutex类进行多线程同步
- C#使用lock锁定静态变量
- qlineedit设置背景颜色(使用QPalette的方法不行,必须使用QSS)
- (一) Graphivz 基本图形使用及属性设置
- 在 C# 中使用设置
- Qt 如何使用 QImage 设置指定的颜色为透明色?
- 使用C#和Excel进行报表开发(七)-设置单元格的显示格式