为什么在VisualC#中我无法将像素写入picturebox?
我正在编写一个仿真程序,虚拟显示器应该能够接收3字节的颜色数据并显示正确的颜色像素,类似于真实屏幕的工作方式。但是当我设置一些滚动条来测试像素的生成时,什么都没有发生。这是我的代码和表单的屏幕截图:为什么在VisualC#中我无法将像素写入picturebox?,c#,C#,我正在编写一个仿真程序,虚拟显示器应该能够接收3字节的颜色数据并显示正确的颜色像素,类似于真实屏幕的工作方式。但是当我设置一些滚动条来测试像素的生成时,什么都没有发生。这是我的代码和表单的屏幕截图: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace TSC_Multi_System_Emulator
{
public partial class Form1 : Form
{
private PictureBox Display = new PictureBox();
string @emulationfolderpath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
Bitmap screen = new Bitmap(@Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\Resource_Folder\" + @"FirstFrame.bmp");
int x = 0;
int y = 0;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, System.EventArgs e) {
// Dock the PictureBox to the form and set its background to black.
Display.BackColor = Color.Black;
// Connect the Paint event of the PictureBox to the event handler method.
// Add the PictureBox control to the Form.
this.Controls.Add(Display);
}
public void DigitalGraphicsDisplay(int red, int green, int blue) {
Graphics g = Display.CreateGraphics();
screen.SetPixel(x, y, Color.FromArgb(red, green, blue));
g.DrawImage(screen, 0, 0, screen.Width, screen.Height);
g.Save();
if (x < screen.Width)
{
x = x + 1;
}
else if (x == screen.Width)
{
x = 0;
if (y < screen.Height)
{
y = y + 1;
}
else if (y == screen.Height)
{
y = 0;
}
}
}
private void button1_Click(object sender, EventArgs e){
int rchannel = redControl.Value;
int gchannel = greenControl.Value;
int bchannel = blueControl.Value;
DigitalGraphicsDisplay(rchannel, gchannel, bchannel);
}
}
}
}
我得到的只是一个没有其他东西的白色图片盒。。。
(渐变代码确实有效)看起来您正试图直接在PictureBox控件本身上绘制 相反,您应该将图像指定给PictureBox,然后在图像上绘制 尝试更改代码,如下所示。(包括测试的点击事件。)
注意,PictureBox保留了对图像的直接引用,因此您不需要在类中使用单独的屏幕图像,除非您有不同的用途 此外,它使用
Bitmap.SetPixel()
,这是一种非常慢的像素设置方法。在这些其他链接中,有一种更快但稍微更复杂的方式:
因此,请务必仔细查看:
在click事件中运行我的测试代码将产生以下结果:
所有可能的错误一蹴而就
- 切勿使用
绘制持久图形!始终进行CreateGraphics
事件或将绘制到图像中绘制
不保存任何绘制的像素。它保存图形对象的状态,该对象不包含图形,但是写入相关位图的工具。状态包括缩放、旋转、平滑模式,然后是一些Graphics.Save
PictureBox.Image
或PictureBox.BackgroundImage
正如我所说的,你可以在PBox的表面上写上这两个字。为此,请使用Paint
事件、Invalidate
触发它,并使用类级变量保存必要的数据
后者用于变化很大的图形,前两个用于累积变化
控件。CreateGraphics
仅用于瞬态图形,如橡皮筋线或光标十字。缩短代码示例。例如,退出事件不是理解所必需的,也无助于解决您的问题。我用您的代码替换了我的函数,但它仍然没有做任何事情。。。还有,你为什么要画一个矩形?我只想一次画一个像素,你唯一能想到的方法就是画一个非常小的矩形吗?我有点困惑:(请参阅我答案中的更新代码。我对其进行了测试,它与显示您应该看到的内容的屏幕截图一起工作。为了简单起见,我将代码切换回SetPixel,尽管这样速度慢得多,但请参阅链接以获得更好的方式。此外,我简化了您的x,y增量代码。此外,您的单击事件一次只绘制一个像素,因此,您可以需要仔细查看。查看更改。请参阅屏幕截图以供参考。我提供了一个测试示例,可以更改整个图像,但由于设置像素的原因,速度会有点慢。如果这对您有效,请不要忘记标记为已回答,谢谢。您的代码可以工作,但我的按钮测试仍然无法工作,以下是我的按钮测试无法工作的代码:private void button1\u Click(对象发送方,事件参数e){Boolean a=false;int b=0;do{DigitalGraphicsDisplay(51153102);if(b==10000){a=true;}b=b+1;}while(a);}
它显示的是一个白色的图片框…它工作正常,但you's loop设计为只运行一次,在左上角只更改了一个像素(很难看到)。更改代码,使a
变量设置为true
,直到b==10000
,然后将其设置为false
。而循环仅在条件==true时运行。我将在上面答案的底部放置一个代码的工作副本。PS:一旦成功,别忘了将其标记为已回答。我们仍然可以如果你愿意,我会在之后讨论你的设计。这很有效!!!非常感谢你的帮助,你真的为我省了很多麻烦,我不敢相信我把while循环搞砸了。当一双新眼睛检查错误时,这真的很有帮助:)你在图像中画图是什么意思,我想我对你的意思有点了解,但我的代码仍然不起作用…你能给我一个代码示例吗?它意味着使用相关的图形对象来更改位图的像素。关系由Graphics G=Graphics.FromImage(someBitmap)创建
。你在问题的原始、较长版本中有这样的代码,想想看。在控件表面绘制和位图绘制的区别已经解释了-要更改像素,你可以在位图上使用SetPixel
,或者e.Graphics.FillRectangle(画笔,x,y,1,1)
在控件的绘制事件中..靠近代码一点我想知道应该显示什么:每个按钮点击一个像素,对吗?上一个像素应该仍然存在还是应该清除?上一个像素应该仍然存在,它应该自动前进到下一个像素值,(它应该异步工作)
public partial class Form1 : Form
{
string @emulationfolderpath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
Bitmap screen = new Bitmap(@Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\Resource_Folder\" + @"FirstFrame.bmp");
int x = 0;
int y = 0;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, System.EventArgs e) {
// Dock the PictureBox to the form and set its background to black.
Display.BackColor = Color.Black;
// Connect the Paint event of the PictureBox to the event handler method.
// Add the PictureBox control to the Form.
this.Controls.Add(Display);
}
public void DigitalGraphicsDisplay(int red, int green, int blue)
{
if (Display.Image == null)
{
Bitmap NewBMP = new Bitmap(Display.ClientRectangle.Width, Display.ClientRectangle.Height);
using (Graphics g = Graphics.FromImage(NewBMP))
{
g.Clear(Color.White);
}
Display.Image = NewBMP;
}
(Display.Image as Bitmap).SetPixel(x, y, Color.FromArgb(red, green, blue));
Display.Invalidate();
x++;
if (x >= Display.Image.Width)
{
x = 0;
y++;
if (y >= Display.Image.Height)
{
y = 0;
}
}
}
private void button1_Click(object sender, EventArgs e){
Boolean a = false;
int b = 0;
do
{
DigitalGraphicsDisplay(51, 153, 102);
if (b == 10000)
{
a = true;
}
b = b + 1;
} while (a);
}
}
int x = 0;
int y = 0;
public void DigitalGraphicsDisplay(int red, int green, int blue)
{
if (Display.Image == null)
{
Bitmap NewBMP = new Bitmap(Display.ClientRectangle.Width, Display.ClientRectangle.Height);
using (Graphics g = Graphics.FromImage(NewBMP))
{
g.Clear(Color.White);
}
Display.Image = NewBMP;
}
(Display.Image as Bitmap).SetPixel(x, y, Color.FromArgb(red, green, blue));
Display.Invalidate();
x++;
if (x >= Display.Image.Width)
{
x = 0;
y++;
if (y >= Display.Image.Height)
{
y = 0;
}
}
}
private void button1_Click(object sender, EventArgs e)
{
// Temporary code to show that it works (Due to Bitmap.SetPixel() it will be slow)
for (int I = 1; I < Display.ClientRectangle.Width * Display.ClientRectangle.Height; I++)
DigitalGraphicsDisplay((I/255)%255, (I % Display.ClientRectangle.Width) % 255, 127);
}
private void button1_Click(object sender, EventArgs e)
{
Boolean a = true;
int b = 0;
do
{
DigitalGraphicsDisplay(51, 153, 102);
if (b == 10000)
{
a = false;
}
b = b + 1;
} while (a);
}
public void DigitalGraphicsDisplay(int red, int green, int blue) {
Graphics g = Display.CreateGraphics();
screen.SetPixel(x, y, Color.FromArgb(red, green, blue));
g.DrawImage(screen, 0, 0, screen.Width, screen.Height);
g.Save();