我试图创建一个简单的程序,用给定的图像执行一些简单的操作。 出于某种原因,它仅适用于第一次(启动应用程序时):
//伪代码
Bitmap im=Bitmap.FromFile("D:\\x.BMP");
Color [,] ColorArray=new [im.Width,im.Height];
private override voide OnPaint(EventArgs e)
{
for(int X=0;X<im.Width;X++)
{
for(int Y=0;Y<im.Height;Y++)
{
ColorArray[X,Y]=im.GetPixel[X,Y];
}
}
for(int X=0;X<im.Width;X++)
{
for(int Y=0;Y<im.Height;Y++)
{
Color c=ColorArray[X,Y];
...
//some code that adds 100 to R,G,B
im.SetPixel(X,Y,c);
}
}
e.Graphics.DrawImage(im);
}
答案 0 :(得分:0)
<强> [编辑] 强>
我修改了示例代码。对于以前的版本,可能很难看到从一次迭代到下一次迭代的差异(特别是我用于测试的bmp)。这个允许您通过按Num Pad上的1,2或3逐渐更改颜色。正如其他人所提到的,SetPixel / GetPixel很慢,因此每个KeyUp事件确实需要一些时间才能运行。
这对我来说很好。
创建一个新的Windows窗体项目。删除此代码。确保您有“x.bmp”可用。每次在数字键盘上按1,2或3(您可能需要打开Num Lock)时,位图的颜色会略有变化:
public partial class Form1 : Form
{
Bitmap bm;
Color [,] colors;
public Form1()
{
bm = (Bitmap)Bitmap.FromFile("x.bmp");
colors = new Color[bm.Width, bm.Height];
InitializeComponent();
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawImage(bm,new Point(0,0));
}
private void Form1_KeyUp(object sender, KeyEventArgs e)
{
//Change the colors a little bit on each KeyUp.
//On NumPad1, change red.
//On NumPad2, change green.
//On NumPad3, change blue.
//Mod with 256 to ensure a value between 0 and 255.
int rInc = 0;
int gInc = 0;
int bInc = 0;
switch (e.KeyCode)
{
case Keys.NumPad1:
rInc = 20;
break;
case Keys.NumPad2:
gInc = 20;
break;
case Keys.NumPad3:
bInc = 20;
break;
default:
break;
}
for (int x = 0; x < bm.Width; x++)
{
for (int y = 0; y < bm.Height; y++)
{
colors[x, y] = bm.GetPixel(x, y);
}
}
for (int x = 0; x < bm.Width; x++)
{
for (int y = 0; y < bm.Height; y++)
{
Color c = colors[x, y];
int r = (c.R + rInc) % 256;
int g = (c.G + gInc) % 256;
int b = (c.B + bInc) % 256;
c = Color.FromArgb(255, r, g, b);
bm.SetPixel(x, y, c);
}
}
Invalidate();
}
}
它并不是非常复杂,但是它使用与您的伪代码非常匹配的实际代码执行的操作。
答案 1 :(得分:0)
您可以在循环像素时提高性能,排列循环以在内循环中以行顺序(x坐标)访问像素。这最符合图像内存布局,因此它将提高CPU缓存性能
for ( y = 0, y < bm.Height; y++)
{
...
for ( x = 0, x < bm.Width; x++)
{
...
}
}