快意人生
Asp.Net生成BMP图像

利用以下代码可以生成一组随机的数字图片,可用于验证码。。
// 在此处放置用户代码以初始化页面
            Bitmap newBitmap = new Bitmap(36,16,PixelFormat.Format24bppRgb);
            
            
            
//根据上面创建的位图对象创建绘图面
            Graphics g = Graphics.FromImage(newBitmap);
            
            g.Clear(Color.White);

            
            

            
//创建字体对象
            Font textFont = new Font("Times New Roman",10);
            
//创建RectangleF结构指定一个区域
            RectangleF rectangle = new RectangleF(0,0,36,16);
            
//创建随机数对象
            Random rd = new Random();
            
//取得随机数
            int valationNo = 1000 + rd.Next(8999);
            

            
for(int i=0; i<50; i++)
            
{
                
int x = rd.Next(newBitmap.Width);
                
int y = rd.Next(newBitmap.Height);

                newBitmap.SetPixel(x, y, Color.Gray);
            }




            
            
//在上面填充的矩形区域中填充上面生成的随机数
            g.DrawString(valationNo.ToString(), textFont, new SolidBrush(Color.Black), rectangle);
            
            
//把创建的位图保存到指定的路径

            newBitmap.Save(
"d:\\pic\\Img3.bmp", ImageFormat.Bmp);

但是早先的Wap中只支持256色的WBMP的图片格式,于是修改代码

                       Bitmap newBitmap = new Bitmap(36,16,PixelFormat.Format8bppIndexed);
                        
            
            
//根据上面创建的位图对象创建绘图面
            Graphics g = Graphics.FromImage(newBitmap);
            
            g.Clear(Color.White);

            
            

            
//创建字体对象
            Font textFont = new Font("Times New Roman",10);
            
//创建RectangleF结构指定一个区域
            RectangleF rectangle = new RectangleF(0,0,36,16);
            
//创建随机数对象
            Random rd = new Random();
            
//取得随机数
            int valationNo = 1000 + rd.Next(8999);
            

            
for(int i=0; i<50; i++)
            
{
                
int x = rd.Next(newBitmap.Width);
                
int y = rd.Next(newBitmap.Height);

                newBitmap.SetPixel(x, y, Color.Gray);
            }




            
            
//在上面填充的矩形区域中填充上面生成的随机数
            g.DrawString(valationNo.ToString(), textFont, new SolidBrush(Color.Black), rectangle);
            
            
//把创建的位图保存到指定的路径

            newBitmap.Save(
"d:\\pic\\Img3.bmp", ImageFormat.Bmp);

无法从带有索引像素格式的图像创建 Graphics 对象。

说明: 执行当前 Web 请求期间,出现未处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。

异常详细信息: System.Exception: 无法从带有索引像素格式的图像创建 Graphics 对象。

源错误:

行 27: 			
行 28: 			//根据上面创建的位图对象创建绘图面
行 29: 			Graphics g = Graphics.FromImage(newBitmap);
行 30: 			
行 31: 			//Graphics g = Graphics.FromImage(newBitmap);

---------------------------------------
报如上错误,且SetPixel方法也不能用了。

找了半天也没找到解决方法。既然此路不通那就换条路走咯,于是乎找到了一个很好的图片格式转换工具
Graphics Converter Pro for Vector,功能十分强大啊,按最开始的方法生成了9000张图片,然后转换成WBMP
总算是OK了。。。。。




---------------------------------------

其他一些图像处理方法

反相
public static bool Invert(Bitmap b)
{
         BitmapData bmData 
= b.LockBits(new Rectangle(00, b.Width, b.Height), 
         ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); 
int stride = bmData.Stride; 
System.IntPtr Scan0 
= bmData.Scan0; 
unsafe 

byte * p = (byte *)(void *)Scan0;
int nOffset = stride - b.Width*3
int nWidth = b.Width * 3;
for(int y=0;y < b.Height;++y)
         
{
         
for(int x=0; x < nWidth; ++
         
{
p[
0= (byte)(255-p[0]);
++p;
}

+= nOffset;
}

}


b.UnlockBits(bmData);
return true;
}



public static bool Grayscale(Bitmap b)
{
//变成黑白
BitmapData bmData = b.LockBits(new Rectangle(00, b.Width, b.Height), 
ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); 
int stride = bmData.Stride; 
System.IntPtr Scan0 
= bmData.Scan0; 
unsafe
{
byte * p = (byte *)(void *)Scan0;
int nOffset = stride - b.Width*3;
byte red, green, blue;
for(int y=0;y < b.Height;++y)
{
for(int x=0; x < b.Width; ++
{
blue 
= p[0];
green 
= p[1];
red 
= p[2];
p[
0= p[1= p[2= (byte)(.299 * red 
+ .587 * green 
+ .114 * blue);
+= 3;
}

+= nOffset;
}

}

b.UnlockBits(bmData);
return true;
}


亮度
public static bool Brightness(Bitmap b,int nBrightness)
{
BitmapData bmData 
= b.LockBits(new Rectangle(00, b.Width, b.Height), 
ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); 
int stride = bmData.Stride; 
System.IntPtr Scan0 
= bmData.Scan0; 
unsafe 

byte * p = (byte *)(void *)Scan0;
int nOffset = stride - b.Width*3
int nWidth = b.Width * 3;
for(int y=0;y<b.Height;++y)
{
for (int x = 0;  x < nWidth; ++x)
{
int nVal = (int) (p[0+ nBrightness);
if (nVal < 0) nVal = 0;
if (nVal > 255) nVal = 255;
p[
0= (byte)nVal;
++p;
}

+= nOffset;
}

}

b.UnlockBits(bmData);
return true;
}


对比度
public static bool Contrast(Bitmap b,int nContrast)
{
if (nContrast < -100return false;
if (nContrast >  100return false;
double pixel = 0, contrast = (100.0+nContrast)/100.0;
contrast 
*= contrast;
BitmapData bmData 
= b.LockBits(new Rectangle(00, b.Width, b.Height), 
ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); 
int stride = bmData.Stride; 
System.IntPtr Scan0 
= bmData.Scan0; 
unsafe 

byte * p = (byte *)(void *)Scan0;
int nOffset = stride - b.Width*3
int nWidth = b.Width * 3;
for(int y=0;y<b.Height;++y)
{
for (int x = 0;  x < nWidth;++x)
{
         
byte color = p[0];    
pixel 
= color/255.0;
pixel 
-= 0.5;
pixel 
*= contrast;
pixel 
+= 0.5;
pixel 
*= 255;
if (pixel < 0) pixel = 0;
if (pixel > 255) pixel = 255;
p[
0= (byte) pixel;
++p;
}

+= nOffset;
}

}

b.UnlockBits(bmData);
return true;
}



public static bool Gamma(Bitmap b)
{
BitmapData bmData 
= b.LockBits(new Rectangle(00, b.Width, b.Height), 
ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); 
int stride = bmData.Stride; 
System.IntPtr Scan0 
= bmData.Scan0; 

byte [] redGamma = new byte [256];
byte [] greenGamma = new byte [256];
byte [] blueGamma = new byte [256];

for (int i = 0; i < 256++i)
{
redGamma[i] 
= (byte)Math.Min(255, (int)(( 255.0 
      
* Math.Pow(i/255.01.0/5)) + 0.5));//其中1.0/5里的5是红色Gamma值。
greenGamma[i] = (byte)Math.Min(255, (int)(( 255.0 
      
* Math.Pow(i/255.01.0/5)) + 0.5));
blueGamma[i] 
= (byte)Math.Min(255, (int)(( 255.0 
* Math.Pow(i/255.01.0/5)) + 0.5));
}


unsafe 

byte * p = (byte *)(void *)Scan0;
int nOffset = stride - b.Width*3
int nWidth = b.Width * 3;

byte red, green, blue;
for(int y=0;y<b.Height;++y)
{
for (int x = 0;  x < b.Width;++x)
{
blue 
= p[0];
green 
= p[1];
red 
= p[2];

p[
0]=(byte)blueGamma[(int)blue];
p[
1]=(byte)greenGamma[(int)green];
p[
2]=(byte)redGamma[(int)red];
p
+=3;
}

+= nOffset;
}

}


b.UnlockBits(bmData);
return true;
}


通道
public static bool Channel(Bitmap b,char rgb)

BitmapData bmData 
= b.LockBits(new Rectangle(00, b.Width, b.Height), 
ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); 
int stride = bmData.Stride; 
System.IntPtr Scan0 
= bmData.Scan0; 

unsafe 

byte * p = (byte *)(void *)Scan0;
int nOffset = stride - b.Width*3
int nWidth = b.Width * 3;

byte red, green, blue;
for(int y=0;y<b.Height;++y)
{
for (int x = 0;  x < b.Width;++x)
{
switch(rgb)
{
case 'r':
           p[
0]=(byte)0;
p[
1]=(byte)0;
break;
case 'g':
p[
0]=(byte)0;
p[
2]=(byte)0;
break;
case 'b':
p[
2]=(byte)0;
p[
1]=(byte)0;
break;
}

p
+=3;
}

+= nOffset;
}

     }


b.UnlockBits(bmData);

return true;
}



--------------------------------------------------------------------------------------------------------

附:对 ASP.NET 图像的颜色量化(Quantization)进行优化

http://www.microsoft.com/china/MSDN/library/archives/library/DNAspp/html/colorquant.asp
posted on 2006-03-13 16:24  快意人生  阅读(2015)  评论(0)    收藏  举报