I have written the code given below to get RGB value of each pixel which belongs to a image uploaded from a file. Then i want to list all color values of every pixels in the listbox. But "for" loop goes into infinite loop so there is nothing in the listbox.
int R, G, B, xi, yi, xf, yf;
private void button3_Click(object sender, EventArgs e)
{
listBox1.Items.Clear();
if (pictureBox1.Image == null)
{
MessageBox.Show("Lütfen bir JPEG resmi yükleyin.");
return;
}
Bitmap bmp2 = new Bitmap(pictureBox1.Image);
xi = 0;
yi = 0;
xf = bmp2.Width -1;
yf = bmp2.Height -1;
if (xi >= 0 && yi >= 0 && xf < bmp2.Width && yf < bmp2.Height)
{
for (int x = xi; x <= xf; x++)
{
for (int y = yi; y <= yf; y++)
{
Color pixelColor = bmp2.GetPixel(x, y);
R = pixelColor.R;
G = pixelColor.G;
B = pixelColor.B;
listBox1.Items.Add($"Xi: {x}, Yi: {y}, R: {R}, G: {G}, B: {B}");
}
}
// "test line"
listBox1.Items.Add("test line");
}
}
I tried taking the command to add listbox1 ouf of inner loop. I have only seen one single pixel and its RBG values. It was x:0 and y:0
You need to use pagination techniques to overcome this problem. Your loop is not as slow as you think, it is actually super-fast. The problem is with 'ListBox1.Items.Add' which is not designed to hold so many values you put into it, so after it get filled with few thousands of entries each additional entry take lots of time due to additional memory reallocation. I assume you are using winforms, here is an example as to how you can work this out with DataGridView which support pagination instead of using a listbox.
using System.Data;
using System.Windows.Forms;
namespace WinFormsApp2
{
public partial class Form1 : Form
{
private List<string> arr = new List<string>();
public Form1()
{
InitializeComponent();
dataGridView1.VirtualMode = true;
dataGridView1.CellValueNeeded += DataGridView1_CellValueNeeded;
}
private void DataGridView1_CellValueNeeded(object? sender, DataGridViewCellValueEventArgs e)
{
if (e.RowIndex >= 0 && e.RowIndex < arr.Count)
e.Value = arr[e.RowIndex];
}
private void button1_Click(object sender, EventArgs e)
{
openFileDialog1.ShowDialog(this);
pictureBox1.ImageLocation = openFileDialog1.FileName;
}
private void button2_Click(object sender, EventArgs e)
{
int R, G, B, xi, yi, xf, yf;
if (pictureBox1.Image == null)
{
MessageBox.Show("Lütfen bir JPEG resmi yükleyin.");
return;
}
Bitmap bmp2 = new Bitmap(pictureBox1.Image);
xi = 0;
yi = 0;
xf = bmp2.Width - 1;
yf = bmp2.Height - 1;
arr = new List<string>();
if (xi >= 0 && yi >= 0 && xf < bmp2.Width && yf < bmp2.Height)
{
for (int x = xi; x <= xf; x++)
{
for (int y = yi; y <= yf; y++)
{
Color pixelColor = bmp2.GetPixel(x, y);
R = pixelColor.R;
G = pixelColor.G;
B = pixelColor.B;
arr.Add($"Xi: {x}, Yi: {y}, R: {R}, G: {G}, B: {B}");
}
}
}
dataGridView1.RowCount = arr.Count;
}
}
}
And here is another approach in case you don't really want to retain a "model" of the data which is the arr and just want to browse the pixels values:
using System.Data;
using System.Windows.Forms;
namespace WinFormsApp2
{
public partial class Form1 : Form
{
private Bitmap bmp2;
public Form1()
{
InitializeComponent();
dataGridView1.VirtualMode = true;
dataGridView1.CellValueNeeded += DataGridView1_CellValueNeeded;
}
private void DataGridView1_CellValueNeeded(object? sender, DataGridViewCellValueEventArgs e)
{
if (e.RowIndex >= 0 && e.RowIndex < bmp2.Width*bmp2.Height)
{
var x = e.RowIndex % bmp2.Width;
var y = e.RowIndex / bmp2.Width;
Color pixelColor = bmp2.GetPixel(x, y);
var R = pixelColor.R;
var G = pixelColor.G;
var B = pixelColor.B;
e.Value = $"Xi: {x}, Yi: {y}, R: {R}, G: {G}, B: {B}";
}
}
private void button1_Click(object sender, EventArgs e)
{
openFileDialog1.ShowDialog(this);
pictureBox1.ImageLocation = openFileDialog1.FileName;
}
private void button2_Click(object sender, EventArgs e)
{
if (pictureBox1.Image == null)
{
MessageBox.Show("Lütfen bir JPEG resmi yükleyin.");
return;
}
bmp2 = new Bitmap(pictureBox1.Image);
dataGridView1.RowCount = bmp2.Width * bmp2.Height;
}
}
}