Mus*_*sis 30
如果该示例中的代码适合您,您可以通过使用大量加速(按数量级)加速Bitmap.LockBits
,这将返回一个BitmapData
允许通过指针访问位图像素数据的对象.Web和StackOverflow上有大量示例,展示了如何使用LockBits.
Bitmap.SetPixel()
并且Bitmap.GetPixel()
是人类已知的最慢的方法,它们都利用了Color
人类已知的最慢的阶级.它们应该被命名Bitmap.GetPixelAndByGodYoullBeSorryYouDid()
并Bitmap.SetPixelWhileGettingCoffee
作为对不谨慎的开发人员的警告.
更新: 如果您要修改该示例中的代码,请注意此块:
System.Drawing.Bitmap TempBitmap = Image;
System.Drawing.Bitmap NewBitmap = new System.Drawing.Bitmap(TempBitmap.Width,
TempBitmap.Height);
System.Drawing.Graphics NewGraphics =
System.Drawing.Graphics.FromImage(NewBitmap);
NewGraphics.DrawImage(TempBitmap, new System.Drawing.Rectangle(0, 0,
TempBitmap.Width, TempBitmap.Height),
new System.Drawing.Rectangle(0, 0, TempBitmap.Width, TempBitmap.Height),
System.Drawing.GraphicsUnit.Pixel);
NewGraphics.Dispose();
Run Code Online (Sandbox Code Playgroud)
可以替换为:
Bitmap NewBitmap = (Bitmap)Image.Clone();
Run Code Online (Sandbox Code Playgroud)
更新2: 这是AdjustContrast方法的LockBits版本(还有一些其他的速度改进):
public static Bitmap AdjustContrast(Bitmap Image, float Value)
{
Value = (100.0f + Value) / 100.0f;
Value *= Value;
Bitmap NewBitmap = (Bitmap)Image.Clone();
BitmapData data = NewBitmap.LockBits(
new Rectangle(0, 0, NewBitmap.Width, NewBitmap.Height),
ImageLockMode.ReadWrite,
NewBitmap.PixelFormat);
int Height = NewBitmap.Height;
int Width = NewBitmap.Width;
unsafe
{
for (int y = 0; y < Height; ++y)
{
byte* row = (byte*)data.Scan0 + (y * data.Stride);
int columnOffset = 0;
for (int x = 0; x < Width; ++x)
{
byte B = row[columnOffset];
byte G = row[columnOffset + 1];
byte R = row[columnOffset + 2];
float Red = R / 255.0f;
float Green = G / 255.0f;
float Blue = B / 255.0f;
Red = (((Red - 0.5f) * Value) + 0.5f) * 255.0f;
Green = (((Green - 0.5f) * Value) + 0.5f) * 255.0f;
Blue = (((Blue - 0.5f) * Value) + 0.5f) * 255.0f;
int iR = (int)Red;
iR = iR > 255 ? 255 : iR;
iR = iR < 0 ? 0 : iR;
int iG = (int)Green;
iG = iG > 255 ? 255 : iG;
iG = iG < 0 ? 0 : iG;
int iB = (int)Blue;
iB = iB > 255 ? 255 : iB;
iB = iB < 0 ? 0 : iB;
row[columnOffset] = (byte)iB;
row[columnOffset + 1] = (byte)iG;
row[columnOffset + 2] = (byte)iR;
columnOffset += 4;
}
}
}
NewBitmap.UnlockBits(data);
return NewBitmap;
}
Run Code Online (Sandbox Code Playgroud)
注意:此代码using System.Drawing.Imaging;
在您的类中使用'using语句,并且它要求allow unsafe code
检查项目的选项(在项目的Build Properties选项卡上).
GetPixel和SetPixel对于逐像素操作来说如此缓慢的原因之一是方法调用本身的开销开始成为一个重要因素.通常,我的代码示例将被视为重构的候选者,因为您可以编写自己的使用现有BitmapData对象的SetPixel和GetPixel方法,但相对于方法开销,函数内部的数学处理时间将非常短.每次通话.这就是为什么我也删除Clamp
了原始方法中的调用.
另一种加快速度的方法是简单地使其成为"破坏性"功能,并修改传递的Bitmap参数,而不是制作副本并返回修改后的副本.
归档时间: |
|
查看次数: |
31371 次 |
最近记录: |