Не в состоянии успешно использовать локбиты
Привет, я действительно новичок в обработке изображений в C#, и код ниже в основном getpixel из изображения, которое я просматривал со своего компьютера, и сравнит значение RGB для пикселя с правильным пикселем, и, если оно будет таким же, оно установит пиксель в голубой цвет. проблема с getpixel, он действительно очень медленный даже на фотографиях с небольшим разрешением, и я также собираюсь добавить к нему больше функций. Я читал о блокировках и пытался, но не смог успешно написать код.
namespace Disimage
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public Bitmap pic;
public Bitmap pic2;
private bool compare_colour_constant(int original, int sample)
{
if (original == sample)
return true;
else
return false;
}
public void btn_browse_Click_Click(object sender, EventArgs e)
{
try
{
OpenFileDialog open = new OpenFileDialog();
open.Filter = "Image Files(*.jpg; *.jpeg; *.gif; *.bmp)|*.jpg; *.jpeg; *.gif; *.bmp";
if (open.ShowDialog() == DialogResult.OK)
{
pic = new Bitmap(Width, Height, PixelFormat.Format24bppRgb);
pic2 = new Bitmap(Width, Height, PixelFormat.Format24bppRgb);
//pictureBox1.Image = new Bitmap(open.FileName);
pic = new Bitmap(open.FileName);
pic2 = new Bitmap(open.FileName);
pictureBox1.Image = pic;
pictureBox2.Image = pic2;
pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
textBox1.Text = open.FileName;
pictureBox2.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
}
}
catch (Exception)
{
throw new ApplicationException("Failed loading image");
}
}
public void scan_Click(object sender, EventArgs e)
{
try
{
//Bitmap pic = new Bitmap(Width, Height, PixelFormat.Format24bppRgb);
//Bitmap pic2 = new Bitmap(Width, Height, PixelFormat.Format24bppRgb);
pictureBox1.Image = pic;
pictureBox2.Image = pic2;
progressBar1.Minimum = 0;
progressBar1.Maximum = pic.Width;
int []RGB = pic.GetPixel();
for (int w = 1; w < pic.Width - 1; w++)
{
progressBar1.Step = 1;
progressBar1.PerformStep();
if (progressBar1.Value == progressBar1.Maximum)
progressBar1.Value = 0;
for (int h = 1; h < pic.Height - 1; h++)
{
int red = pic.GetPixel(w, h).R;
int green = pic.GetPixel(w, h).G;
int blue = pic.GetPixel(w, h).B;
int colour = pic.GetPixel(w, h).R + pic.GetPixel(w, h).G + pic.GetPixel(w, h).B;
int colour2 = pic.GetPixel(w + 1, h).R + pic.GetPixel(w + 1, h).G + pic.GetPixel(w + 1, h).B;
/*textBox2.Text = red.ToString();
textBox3.Text = green.ToString();
textBox4.Text = blue.ToString();
*/
int Lred = pic.GetPixel(w - 1, h).R;
int Lgreen = pic.GetPixel(w - 1, h).G;
int Lblue = pic.GetPixel(w - 1, h).B;
int Rred = pic.GetPixel(w + 1, h).R;
int Rgreen = pic.GetPixel(w + 1, h).G;
int Rblue = pic.GetPixel(w + 1, h).B;
if (compare_colour_constant(colour, colour2) == true)
pic2.SetPixel(w, h, Color.Cyan);
}
}
}
catch (Exception)
{
throw new ApplicationException("Failed loading image");
}
}
}
}
1 ответ
Хотя я немного опоздал, я был бы рад ответить на ваш вопрос для других пользователей. Первое, что вам нужно сделать, это объявить переменную BitmapData, которая будет хранить (очевидно) данные из растрового изображения, которое было помещено в память. Сделать это:
System.Drawing.Imaging.BitmapData bmpdata = pic.LockBits(new Rectangle(pictureBox1.Location.X, pictureBox1.Location.Y, pictureBox1.Width, pictureBox1.Height),
System.Drawing.Imaging.ImageLockMode.ReadWrite,
System.Drawing.Imaging.PixelFormat);
После вызова этого кода вы можете приступить к редактированию BitmapData по своему вкусу. В этой ситуации вы можете вызвать цикл по байтовому массиву данных и сравнить RGB с RGB пикселя сразу справа и определить сходство. Пример:
unsafe
{
for (int y = 0; y < bmpdata.Height; y++) // Repeats for each row
{
byte* row = (byte*)bmpdata.Scan0 + (y * bmpdata.Stride); // Array of bytes for the current row of pixels
for (int x = 0; x < bmpdata.Width; x++) // Repeats for each pixel on each row
{
if (row[x * 4] == row[(x + 1) * 4] && row[(x * 4) + 1] == row[((x + 1) * 4) + 1] && row[(x * 4) + 2] == row[((x + 1) * 4) + 2])
{
row[x * 4] = 255; // Blue value of current pixel
row[(x * 4) + 1] = 255; // Green Value of current pixel
row[(x * 4) + 2] = 0; // Red value of current pixel
}
}
}
}
ВНИМАНИЕ: Хотя вышесказанное может сработать (и позвольте мне подчеркнуть, возможно), было бы гораздо надежнее зайти на сайт Боба Пауэлла и прочитать его страницу на LockBits. Хотя поначалу это может быть трудно понять, с течением времени все становится проще. Его страница гораздо более подробная, чем я мог бы быть в этом ответе, и у него, вероятно, есть рабочие примеры.