|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
完全不一样的。.net其实我也说不太清,.net可以把他理解为跟J2EE相对的工具。c++主要做系统相关的开发你要学.net的话就应该学C#。(其实微软在.NET平台上也考虑了给C++留一个地位。在图片处置过程当中,我们常常必要对图片逐像素举行处置,好比为了使图片某一直量的色彩加深大概减淡,大概为了使图象变更成口角色彩,这个时分我们必要掏出每一个点上的像素举行盘算,再赋值到图象指定的地位。在.Net中,官方供应了Image.GetPixel(intx,inty)的办法供开辟职员猎取指定地位的像素,同时供应了Image.SetPixel(intx,inty,Colorcolor)的办法来给指定地位的像素赋值。可是这个办法功能很差,假定存在一张1024*768的图片,逐像素操纵并予以缓存的话亦最少必要1027*768次GetPixel和SetPixel,处置速率将慢到没法忍耐。因而本计划将利用对内存间接读取和赋值的体例来进步图片处置的速率。
这里起首要先容一个类System.Drawing.Imaging.BitmapData,间接实例化这个类没有效处,我们必要将一个Bitmap锁定到内存中,来猎取一个BitmapData的实例。办法以下:
利用Bitmap.LockBits(Rectanglerect,ImageLockModeflags,PixelFormatformat)大概它的另外一个重载Bitmap.LockBits(Rectanglerect,ImageLockModeflags,PixelFormatformat,BitmapDatabitmapData)来将图象数据锁定到内存中,以此来猎取一个与指定图片相干联的BitmapData实例。
在BitmapData中有一个主要的属性Scan0,它是一个指针,指向了图片数据地点内存的第一个地位。利用内存跟踪,将Scan0的值填上天址中,能够看到内存的分派情形(Format32bppArgb色彩深度):
这些值与图片像素的对应干系是如许的:
如今我们可使用System.Runtime.InteropServices.Marshal.WriteByte(IntPtrptr,byteval)的办法来变动指定地位的像素值了,修正后只需再挪用一次Bitmap.UnlockBits(BitmapDatabitmapdata)来解锁内存就能够了,比方:
以下为援用的内容:
privatevoidLockUnlockBitsExample(PaintEventArgse)
{
Bitmapbmp=newBitmap("c:fakePhoto.jpg");
Rectanglerect=newRectangle(0,0,bmp.Width,bmp.Height);
System.Drawing.Imaging.BitmapDatabmpData=
bmp.LockBits(rect,System.Drawing.Imaging.ImageLockMode.ReadWrite,
bmp.PixelFormat);
IntPtrptr=bmpData.Scan0;
intbytes=bmp.Width*bmp.Height*3;
byte[]rgbValues=newbyte[bytes];
for(intcounter=0;counter<rgbValues.Length;counter+=3)
{
Marshal.WriteByte(ptr,counter,255);
}
bmp.UnlockBits(bmpData);
e.Graphics.DrawImage(bmp,0,0);
}
此示例将图片上一切像素的Red向量设置为255。运转此实例能够看到图片变色了。
每次挪用System.Runtime.InteropServices.Marshal.WriteByte(IntPtrptr,byteval)的办法其实不便利,因而我们机关一个ColorBgra类用来贮存这4个色彩向量,它的次要代码是如许的(参考自Paint.Net供应的源码):
以下为援用的内容:
[StructLayout(LayoutKind.Explicit)]
publicstructColorBgra
{
[FieldOffset(0)]
publicbyteB;
[FieldOffset(1)]
publicbyteG;
[FieldOffset(2)]
publicbyteR;
[FieldOffset(3)]
publicbyteA;
///<summary>
///LetsyouchangeB,G,R,andAatthesametime.
///</summary>
[FieldOffset(0)]
publicuintBgra;
publicoverridestringToString()
{
return"B:"+B+",G:"+G+",R:"+R+",A:"+A;
}
}
利用这个类在声明为unsafe的高低文中就能够经由过程盘算偏移量的举措寻址找到指定地位像素的地点(指针),比方在Format32bppArgb色彩深度的图片中能够如许盘算:
以下为援用的内容:
publicunsafeColorBgra*GetPointAddress(intx,inty)
{
returny*4+x;
}
将盘算前往的指针赋给ColorBgra*。以后利用以下办法:
以下为援用的内容:
color->B=i;
color->G=i;
color->R=i;
color->A=i;
间接把值写进内存中,完成对图片像素的疾速操纵。
我感觉可以顶到50楼,出乎意料的是大家居然纷纷写出自己的博文,还被编辑做成了专题,置于首页头条。 |
|