Getpixel()的问题 [英] problem with Getpixel()
本文介绍了Getpixel()的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
嗨,,,这是我的代码,,,当我调用Gfill ,,,在getpixel方法之后,c的值为0 ,,,我的问题是什么?
,,this is my code,,,when i call Gfill,,,after getpixel method a value of c is 0,,,what is my problem?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace GFill
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
int MouseX, MouseY;
// Color ColorOfPixel(Point P);
private void button1_Click(object sender, EventArgs e)
{
}
private void GFill(int x, int y, int bcolor, int Fcolor)
{
Graphics g = this.CreateGraphics();
Bitmap bmp = new Bitmap(this.Width,this.Height);
bmp.SetPixel(0, 0, Color.Blue);
int c = bmp.GetPixel(x, y).ToArgb();
if ((x >= 0) && (x <= 640) && (y >= 0) && (y <= 480))
{
if ((c != bcolor) && (c != Fcolor))
{
g.DrawImageUnscaled(bmp, x, y);
GFill(x + 1, y, bcolor, Fcolor);
GFill(x, y + 1, bcolor, Fcolor);
GFill(x - 1, y, bcolor, Fcolor);
GFill(x, y - 1, bcolor, Fcolor);
}
}
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
Rectangle rectangle1 = new Rectangle(100, 200, 200, 100);
e.Graphics.DrawRectangle(Pens.Black, rectangle1);
}
private void Form1_MouseClick(object sender, MouseEventArgs e)
{
MouseX = MousePosition.X;
MouseY = MousePosition.Y;
GFill(MouseX, MouseY, this.BackColor.ToArgb(), this.ForeColor.ToArgb());
Application.DoEvents();
}
}
}
推荐答案
你是在每次调用GFill
时创建一个新的位图
,所以你总是在看新创建的位图,而不是表单的实际图像!
在<$ c $中创建一个位图
c> Form1_MouseClick ,将表单的初始图像复制到位图中,并将其传递给GFill
。执行填充操作,然后在GFill
返回后调用g.DrawImageUnscaled(bmp,0,0);
。 br />
旁白:GetPixel
和SetPixel
非常慢。在CodeProject(或谷歌)上搜索,找到更好的方法。
You're creating a newBitmap
in each invocation ofGFill
, so you're always looking at the newly created bitmap, not the actual image of the form!
Create oneBitmap
inForm1_MouseClick
, copy the initial image of the form into the bitmap, and pass it toGFill
. Do the filling operation and then call theg.DrawImageUnscaled(bmp, 0, 0);
afterGFill
returns.
Aside:GetPixel
andSetPixel
are notorously slow. Search here on CodeProject (or with Google) to find better ways of doing this.
private void Form1_MouseClick(object sender, MouseEventArgs e)
{
Graphics g = this.CreateGraphics();
Rectangle rect = this.ClientRectangle;
Bitmap bmp = new Bitmap(rect.Width, rect.Height, g);
//Get form's client area bitmap into bmp
BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
int[] pixels = new int[bmpData.Height * bmpData.Width];
Marshal.Copy(bmpData.Scan0, pixels, 0, pixels.Length);
GFill(Color.Blue.ToArgb(), e.X, e.Y, this.BackColor.ToArgb(), this.ForeColor.ToArgb(), bmp.Width, bmp.Height, pixels);
Marshal.Copy(pixels, 0, bmpData.Scan0, pixels.Length);
bmp.UnlockBits(bmpData);
g.DrawImageUnscaled(bmp, 0, 0);
}
private void GFill(int newColor, int x, int y, int bcolor, int Fcolor, int width, int height, int[] pixels)
{
if ((x >= 0) && (x < width) && (y >= 0) && (y < height))
{
int offset = x + y * width;
int c = pixels[offset];
if ((c != newColor) && (c != bcolor) && (c != Fcolor))
{
pixels[offset] = newColor;
GFill(newColor, x + 1, y, bcolor, Fcolor, width, height, pixels);
GFill(newColor, x, y + 1, bcolor, Fcolor, width, height, pixels);
GFill(newColor, x - 1, y, bcolor, Fcolor, width, height, pixels);
GFill(newColor, x, y - 1, bcolor, Fcolor, width, height, pixels);
}
}
}
注意:我添加了支票像素在x,y已经是newColor以防止重新填充区域已经完成。
这个填充例程会很快溢出堆栈!!!
Notice: I added a check for the pixel at x,y already newColor to prevent re-filling areas already done.
This fill routine will overflow the stack fairly quickly!!!
除了正确的解决方案1:
对于如此大规模的操作,你永远不应该使用GetPixel / SetPixel
,非常慢,仅适用于极少数像素。相反,使用System.Drawing.Bitmap.LockBits
:
http://msdn.microsoft.com/en-us/library/system.drawing.bitmap.lockbits%28v=vs。 110%29.aspx [ ^ ]。
MSDN中这两种方法的代码示例和说明将帮助您理解他们做了什么以及如何使用它们。
另一个非常糟糕的事情是Application.DoEvents
。如果您需要并行执行某些操作,请使用线程;但这是一个不同的故事。
请参阅下面的评论。如果你需要从屏幕上获取一个像素,那你就错了。
参见,例如:
http://stackoverflow.com/questions/1483928/how-to-read-the-color-of-a-屏幕像素 [ ^ ],
http://bobpowell.net/eyedropper.aspx [ ^ ]。
不使用P / Invoke的干净方法也是:获取点击的屏幕坐标,获取屏幕的一小部分片段的副本(理想情况下,大小为一个像素),并使用System.Drawing.Graphics.CopyFromScreen
:
HTT p://msdn.microsoft.com/en-us/library/system.drawing.graphics.copyfromscreen%28v=vs.110%29.aspx [ ^ ]。
它将为您提供System.Drawing.Graphics
的实例,以便从屏幕上读取,甚至可以使用GetPixel
。
要获得点击的屏幕坐标,请使用 http://msdn.microsoft.com/en-us/library/system.windows.forms.control .pointtoscreen%28v = vs.110%29.aspx [ ^ ]。
-SA
In addition to the correct Solution 1:
For such a massive bit operations, you should never useGetPixel/SetPixel
, which is prohibitively slow and would be good only for working with very few pixels. Instead, useSystem.Drawing.Bitmap.LockBits
:
http://msdn.microsoft.com/en-us/library/system.drawing.bitmap.lockbits%28v=vs.110%29.aspx[^].
The code samples and description of these two methods in MSDN will help you to understand what they do and how to use them.
Another pretty bad thing isApplication.DoEvents
. If you need to do something in parallel, use threads; but this is a different story.
Please see my comments below. If you need to pick up a pixel from screen, you are doing it wrong.
See, for example:
http://stackoverflow.com/questions/1483928/how-to-read-the-color-of-a-screen-pixel[^],
http://bobpowell.net/eyedropper.aspx[^].
The clean way to do it without using P/Invoke is also this: get a screen coordinate of your click, take a copy of a little fragment of the screen (ideally, of a size of one pixel), and useSystem.Drawing.Graphics.CopyFromScreen
:
http://msdn.microsoft.com/en-us/library/system.drawing.graphics.copyfromscreen%28v=vs.110%29.aspx[^].
It will give you an instance ofSystem.Drawing.Graphics
to read from screen, possibly even withGetPixel
.
To get screen coordinates of the click, use http://msdn.microsoft.com/en-us/library/system.windows.forms.control.pointtoscreen%28v=vs.110%29.aspx[^].
—SA
在你的代码中你将像素0,0设置为蓝色,在下一行中你正在检查p的值ixel x,y。
几乎可以肯定x!= 0和y!= 0.
In your code you set pixel 0,0 to blue and in the next line you are examining value of pixel x, y.
Almost certainly x!=0 and y!=0.
Bitmap bmp = new Bitmap(this.Width,this.Height);
bmp.SetPixel(0, 0, Color.Blue);
int c = bmp.GetPixel(x, y).ToArgb();
这篇关于Getpixel()的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文