我的程序中需要一个把图像灰度化的功能,我利用网上提供的算法自己做了一个,不过速度非常慢,处理一个2560 X 1920像素的jpg图像大约需要25秒,因为对速度不满,我在网上又找了一个图像处理控件(估计是C++做的),利用这个控件处理同样的图像只需要不到1秒钟,差距实在太大了,我想请问是不是C#确实存在这个问题(处理图像速度非常慢),还是因为我的算法有问题?
算法如下:
Bitmap bm = image;for(int y=0;y<bm.Height;y++)
{
for(int x=0;x<bm.Width;x++)
{
Color c = bm.GetPixel(x,y);
int luma = (int)(c.R*0.3 + c.G*0.59+ c.B*0.11);
bm.SetPixel(x,y,Color.FromArgb(luma,luma,luma));
}
}
算法如下:
Bitmap bm = image;for(int y=0;y<bm.Height;y++)
{
for(int x=0;x<bm.Width;x++)
{
Color c = bm.GetPixel(x,y);
int luma = (int)(c.R*0.3 + c.G*0.59+ c.B*0.11);
bm.SetPixel(x,y,Color.FromArgb(luma,luma,luma));
}
}
解决方案 »
- C#分别对sqlserver,oracle执行存储过程,返回参数中包含有记录集,如何显示记录集?
- 为什么Visual Studio中的字体不能设置?
- 推荐一个好工具
- socket莫名其妙的异常
- 无法将类型“int”隐式转换为“bool”
- 一个AD操作的path问题,高手帮忙!
- 一个帐号只能一个人登陆除了框架外还有别的办法吗?
- 请教高手: 不同的两个应用程序,可否用同一个连接池,连接数据库?
- 高手帮忙!关于datetime要怎么解决!
- 请问如何进行数字和字符之间的转化
- c#连sybase
- 无法将类型“IBatisNet.DataMapper.ISqlMapper”隐式转换为“IBatisNet.DataMapper.SqlMapper”。
特别是在图像处理,和大型计算方面
{
// 基本数据
int width = source.Width;
int height = source.Height;
Rectangle rect = new Rectangle(0, 0, width, height);
PixelFormat format = source.PixelFormat;
// 图象结果
Bitmap result = new Bitmap(width, height, format);
// 图像数据
BitmapData sourceData = source.LockBits(rect, ImageLockMode.ReadOnly, format);
BitmapData resultData = result.LockBits(rect, ImageLockMode.WriteOnly, format);
// 处理图像数据
unsafe
{
byte* sourcePtr = (byte*)(sourceData.Scan0);
byte* resultPtr = (byte*)(resultData.Scan0); for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
// 计算明度
byte min = sourcePtr[0]; byte max = sourcePtr[1];
if (min > max) { min = sourcePtr[1]; max = sourcePtr[0]; }
if (max < sourcePtr[2]) { max = sourcePtr[2]; }
if (min > sourcePtr[2]) { min = sourcePtr[2]; }
float light = ((float)min + (float)max) * 0.5f;
// 处理数据
resultPtr[0] = (byte)(sourcePtr[0] * light);
resultPtr[1] = (byte)(sourcePtr[1] * light);
resultPtr[2] = (byte)(sourcePtr[2] * light);
// 更新指针
sourcePtr += 4; // 包含Alpha通道所以为4 否则用3
resultPtr += 4;
}
sourcePtr += sourceData.Stride - width * 4;
resultPtr += sourceData.Stride - width * 4;
}
}
// 解锁
source.UnlockBits(sourceData);
result.UnlockBits(resultData);
// 返回结果
return result;
}
/// <returns>图象</returns>
public Bitmap ColorGray()
{
// 基本数据
int width = this._source.Width;
int height = this._source.Height;
Rectangle rect = new Rectangle(0, 0, width, height);
PixelFormat format = this._source.PixelFormat;
// 图象结果
Bitmap result = new Bitmap(width, height, format);
// 图像数据
BitmapData sourceData = this._source.LockBits(rect, ImageLockMode.ReadOnly, format);
BitmapData resultData = result.LockBits(rect, ImageLockMode.WriteOnly, format);
// 处理图像数据
unsafe
{
byte* sourcePtr = (byte*)(sourceData.Scan0);
byte* resultPtr = (byte*)(resultData.Scan0); for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
// 计算明度
byte luma = (byte)(sourcePtr[2] * 0.3 + sourcePtr[1] * 0.59 + sourcePtr[0] * 0.11);
// 处理数据
resultPtr[0] = luma;
resultPtr[1] = luma;
resultPtr[2] = luma;
resultPtr[3] = sourcePtr[3];
// 更新指针
sourcePtr += 4;
resultPtr += 4;
}
sourcePtr += sourceData.Stride - width * 4;
resultPtr += sourceData.Stride - width * 4;
}
}
// 解锁
this._source.UnlockBits(sourceData);
result.UnlockBits(resultData);
// 返回结果
return result;
}
{
for (int j = 0; j < width; j++)
{
// 计算明度
byte luma = (byte)(((int)sourcePtr[2] * 77 + (int)sourcePtr[1] * 151 + (int)sourcePtr[0] * 28) >> 8);
// 处理数据
resultPtr[0] = luma;
resultPtr[1] = luma;
resultPtr[2] = luma;
resultPtr[3] = sourcePtr[3];
// 更新指针
sourcePtr += 4;
resultPtr += 4;
}
}
IntPtr iPtr = tempBitmapData.Scan0;
int iStride = tempBitmapData.Stride;
int byteslength = iStride * img.Height;
byte[] inputbyte = new byte[byteslength];
System.Runtime.InteropServices.Marshal.Copy(iPtr, inputbyte, 0, byteslength);
for (int i = 0; i < byteslength; i += 3)
{
byte temp = (int)(inputbyte[i]*0.3+inputbyte[i + 1];*0.59+inputbyte[i + 2]*0.11);
inputbyte[i] = temp
inputbyte[i + 1] = temp
inputbyte[i + 2] = temp;
}
System.Runtime.InteropServices.Marshal.Copy(inputbyte, 0, iPtr, byteslength);
img.UnlockBits(tempBitmapData);
这个应该快!
{
unsafe
{
int w = srcImage.Width;
int h = srcImage.Height;
Rectangle Rect = new Rectangle(0, 0, w, h); BitmapData dat = srcImage.LockBits(Rect, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
byte[] buffers = new byte[w * h];
byte* srcp = (byte*)dat.Scan0.ToPointer();
int ofs = dat.Stride - 3 * dat.Width;
for (int i = 0; i < h; i++)
{
for (int j = 0; j < w; j++)
{
buffers[i * w + j] = (byte)(((*srcp++) + (*srcp++) + (*srcp++)) / 3);
}
srcp += ofs;
}
srcImage.UnlockBits(dat);
return buffers;
}
} public static byte[] GetRGBBuffers(Bitmap srcImage)
{
unsafe
{
int w = srcImage.Width;
int h = srcImage.Height;
Rectangle Rect = new Rectangle(0, 0, w, h); BitmapData dat = srcImage.LockBits(Rect, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
byte[] buffers = new byte[w * h * 3];
byte* srcp = (byte*)dat.Scan0.ToPointer();
int ofs = dat.Stride - 3 * dat.Width;
int index = 0;
for (int i = 0; i < h; i++)
{
for (int j = 0; j < w; j++)
{
buffers[index ++] = *srcp++;
buffers[index ++] = *srcp++;
buffers[index ++] = *srcp++;
}
srcp += ofs;
}
srcImage.UnlockBits(dat);
return buffers;
}
} public static Bitmap GetRGBBitmap(byte[] buffers, int w, int h)
{
unsafe
{
byte b;
Bitmap tbmp = new Bitmap(w, h);
Rectangle Rect = new Rectangle(0, 0, w, h);
BitmapData dat = tbmp.LockBits(Rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
byte* p = (byte*)dat.Scan0.ToPointer();
int ofs = dat.Stride - 3 * dat.Width; int index = 0;
for (int i = 0; i < h; i++)
{
for (int j = 0; j < w; j++)
{
*(p++) = buffers[index ++];
*(p++) = buffers[index ++];
*(p++) = buffers[index ++];
}
p += ofs;
}
tbmp.UnlockBits(dat);
return tbmp;
}
}