I'm making a small Reversi/Othello game and inside my method for drawing the board I have a nested for loop to display a grid of PictureBoxes each with an image in.
The first time the method is called all the PictureBoxes are created correctly and the images placed inside. However if I then call the method again I cannot seem to overwrite the images that are already there.
I've been researching for a while and as I understand it may be something to do with the PictureBox becoming locked or needing to correctly Dispose() the PictureBox before writing another image to it. I couldn't get any of these solutions to work though so any specific help would be much appreciated!
private void Draw()
{
Bitmap White = Properties.Resources.white;
Bitmap Black = Properties.Resources.black;
Bitmap None = Properties.Resources.none;
for (int r = 0; r <= grid.GetUpperBound(0); r++)
{
for (int c = 0; c <= grid.GetUpperBound(0); c++)
{
if (grid[r, c].value == 1)
{
var picbox = new PictureBox() // initialise picturebox for displaying images
{
Name = grid[r, c].name,
Size = new Size(64, 64),
Location = new Point(r * 65 + 15, c * 65 + 60),
Text = grid[r, c].name,
Image = White
};
Controls.Add(picbox); // add picturebox to form
picbox.Click += ClickBox;
MessageBox.Show("white draw" + grid[r, c].name);
}
if (grid[r, c].value == -1)
{
var picbox = new PictureBox()
{
Name = grid[r, c].name,
Size = new Size(64, 64),
Location = new Point(r * 65 + 15, c * 65 + 60),
Text = grid[r, c].name,
Image = Black
};
Controls.Add(picbox);
picbox.Click += ClickBox;
MessageBox.Show("black draw" + grid[r, c].name);
}
if (grid[r, c].value == 0)
{
var picbox = new PictureBox()
{
Name = grid[r, c].name,
Size = new Size(64, 64),
Location = new Point(r * 65 + 15, c * 65 + 60),
Text = grid[r, c].name,
Image = None
};
Controls.Add(picbox);
picbox.Click += ClickBox;
}
}
}
}
The problem is that you create new picturebox but do not remove/update the existing Picture box from Controls.
First of all you need to find a picture box you want to update or remove from Controls.
I suggest to create a grid of a Picture boxes, so you can get the picture box from the grid. First of all create the field.
private var pictureGrid = new PictureBox[8, 8];
And then
if (grid[r, c].value == 1)
{
if (pictureGrid[r,c] != null)
{
pictureGrid[r,c].Image = White;
}
else
{
var picbox = new PictureBox()
{
Name = grid[r, c].name,
Size = new Size(64, 64),
Location = new Point(r * 65 + 15, c * 65 + 60),
Text = grid[r, c].name,
Image = White
};
pictureGrid[r,c] = picbox;
Controls.Add(picbox);
picbox.Click += ClickBox;
MessageBox.Show("white draw" + grid[r, c].name);
}
}
You also can use Dictionary that contains (grid.Value - Color) pairs.
private Dictionary<int, Bitmap> colors = new Dictionary<int, Bitmap>();
private void Load()
{
Bitmap White = Properties.Resources.white;
Bitmap Black = Properties.Resources.black;
Bitmap None = Properties.Resources.none;
colors.Add(1, White);
colors.Add(-1, Black);
colors.Add(0, None);
}
So your method will look like
private var pictureGrid = new PictureBox[8, 8];
private Dictionary<int, Bitmap> colors = new Dictionary<int, Bitmap>();
private void Load()
{
Bitmap White = Properties.Resources.white;
Bitmap Black = Properties.Resources.black;
Bitmap None = Properties.Resources.none;
colors.Add(1, White);
colors.Add(-1, Black);
colors.Add(0, None);
}
private void Draw()
{
for (int r = 0; r <= grid.GetUpperBound(0); r++)
{
for (int c = 0; c <= grid.GetUpperBound(0); c++)
{
if (pictureGrid[r, c] != null)
{
pictureGrid[r,c].Image = colors[grid[r,c]];
}
else
{
var picbox = new PictureBox()
{
Name = grid[r, c].name,
Size = new Size(64, 64),
Location = new Point(r * 65 + 15, c * 65 + 60),
Text = grid[r, c].name,
Image = colors[grid[r,c]]
};
pictureGrid[r,c] = picbox;
Controls.Add(picbox);
picbox.Click += ClickBox;
MessageBox.Show("black draw" + grid[r, c].name);
}
}
}
}
Also you can find the picture box to update using linq
var pictureToRemove = this.Controls.OfType<PictureBox>().Where(x => x.Location.X == r * 65 + 15 && x.Location.Y == c * 65 + 60).First();
Related
Let's write a C# program of type "Windows Forms Application" to create a
application simulating the modulation and amplitude demodulation of signal transmission
Analog.
The carrier signal, the modulator signal, the modulated signal will be graphically displayed/
demodulated and the function of spectral density of signals.
I tried to color the picture boxes and they are displayed, but not their content.
My goal is to draw the 4 lines which I want to display in the 4 Picture boxes.
How can I modify this code to get the spec waveformsifice modulation and demodulation in amplitude of an analog signal?
My code:
using System;
using System.Windows.Forms;
using System.Drawing;
using static System.Math;
static class Program
{
[STAThread]
public static void Main()
{
Application.SetCompatibleTextRenderingDefault(true);
Application.Run(new ModulationDemodulationExample());
Application.EnableVisualStyles();
}
}
public class ModulationDemodulationExample : Form
{
// Declare controls and variables
private const int SignalLength = 100;
private PictureBox carrierSignalBox = new PictureBox();
private PictureBox modulatorSignalBox = new PictureBox();
private PictureBox modulatedSignalBox = new PictureBox();
private PictureBox demodulatedSignalBox = new PictureBox();
private double[] carrierSignal = new double[SignalLength];
private double[] modulatorSignal = new double[SignalLength];
private double[] modulatedSignal = new double[SignalLength];
private double[] demodulatedSignal = new double[SignalLength];
private double carrierFrequency = 2.0;
private Bitmap carrierSignalBmp;
private Bitmap modulatorSignalBmp;
private Bitmap modulatedSignalBmp;
private Bitmap demodulatedSignalBmp;
public ModulationDemodulationExample()
{
InitializeComponent();
}
private void InitializeComponent()
{
// Initialize form and controls
Text = "Modulation and Demodulation Simulator";
Size = new Size(800, 600);
PictureBox carrierSignalBox = new PictureBox()
{
Location = new Point(10, 10),
Size = new Size(360, 180),
Visible = true,
Name = "Carrier Signal"
};
PictureBox modulatorSignalBox = new PictureBox()
{
Location = new Point(10, 200),
Size = new Size(360, 180),
Visible = true,
Name = "Modulator Signal"
};
PictureBox modulatedSignalBox = new PictureBox()
{
Location = new Point(400, 10),
Size = new Size(360, 180),
Visible = true,
Name = "Modulated Signal"
};
PictureBox demodulatedSignalBox = new PictureBox()
{
Location = new Point(400, 200),
Size = new Size(360, 180),
Visible = true,
Name = "Demodulated Signal"
};
Controls.Add(carrierSignalBox);
Controls.Add(modulatorSignalBox);
Controls.Add(modulatedSignalBox);
Controls.Add(demodulatedSignalBox);
GenerateSignal();
CreateBitmaps();
DrawSignals();
}
private void GenerateSignal()
{
for (int i = 0; i < SignalLength; i++)
{
carrierSignal[i] = Math.Sin(2 * Math.PI * carrierFrequency * i);
modulatorSignal[i] = Math.Sin(2 * Math.PI * i);
modulatedSignal[i] = carrierSignal[i] * modulatorSignal[i];
demodulatedSignal[i] = modulatedSignal[i] * carrierSignal[i];
}
}
private void CreateBitmaps()
{
carrierSignalBmp = new Bitmap(carrierSignalBox.Width, carrierSignalBox.Height);
modulatorSignalBmp = new Bitmap(modulatorSignalBox.Width, modulatorSignalBox.Height);
modulatedSignalBmp = new Bitmap(modulatedSignalBox.Width, modulatedSignalBox.Height);
demodulatedSignalBmp = new Bitmap(demodulatedSignalBox.Width, demodulatedSignalBox.Height);
//carrierSignalBox.Image = carrierSignalBmp;
carrierSignalBox.DrawToBitmap(carrierSignalBmp, carrierSignalBox.ClientRectangle);
modulatorSignalBox.Image = modulatorSignalBmp;
modulatedSignalBox.Image = modulatedSignalBmp;
demodulatedSignalBox.Image = demodulatedSignalBmp;
}
private void DrawSignals()
{
DrawSignal(carrierSignalBox, carrierSignal, Color.Blue);
DrawSignal(modulatorSignalBox, modulatorSignal, Color.Red);
DrawSignal(modulatedSignalBox, modulatedSignal, Color.Green);
DrawSignal(demodulatedSignalBox, demodulatedSignal, Color.Black);
}
void DrawSignal(PictureBox pictureBox, double[] signal, Color color)
{
// Get the graphics object for the PictureBox
var graphics = pictureBox.CreateGraphics();
// Clear the PictureBox
graphics.Clear(Color.White);
// Set the pen color
var pen = new Pen(color);
// Scale the signal's values to the size of the PictureBox
var yScale = (double)pictureBox.Height / 2.0;
var xScale = (double)pictureBox.Width / (double)signal.Length;
// Draw the signal
for (int i = 0; i < signal.Length - 1; i++)
{
var x1 = (int)(i * xScale);
var y1 = (int)(yScale + (signal[i] * yScale));
var x2 = (int)((i + 1) * xScale);
var y2 = (int)(yScale + (signal[i + 1] * yScale));
graphics.DrawLine(pen, x1, y1, x2, y2);
}
}
}
I created the 4 signals but I can not display them in form ,I would have liked each signal to be displayed in the PictureBox.
You can change your program with an override Paint method for each PictureBox like this
public partial class ModulationDemodulationExample : Form
{
// Declare controls and variables
private const int SignalLength = 100;
private PictureBox carrierSignalBox = new PictureBox();
private PictureBox modulatorSignalBox = new PictureBox();
private PictureBox modulatedSignalBox = new PictureBox();
private PictureBox demodulatedSignalBox = new PictureBox();
private double[] carrierSignal = new double[SignalLength];
private double[] modulatorSignal = new double[SignalLength];
private double[] modulatedSignal = new double[SignalLength];
private double[] demodulatedSignal = new double[SignalLength];
private double carrierFrequency = 2.0;
public ModulationDemodulationExample()
{
InitializeComponent();
// Initialize form and controls
Text = "Modulation and Demodulation Simulator";
Size = new Size(800, 600);
PictureBox carrierSignalBox = new PictureBox()
{
Location = new Point(10, 10),
Size = new Size(360, 180),
Visible = true,
Name = "Carrier Signal"
};
carrierSignalBox.Paint += new PaintEventHandler(carrierSignalBox_Paint);
PictureBox modulatorSignalBox = new PictureBox()
{
Location = new Point(10, 200),
Size = new Size(360, 180),
Visible = true,
Name = "Modulator Signal"
};
modulatorSignalBox.Paint += new PaintEventHandler(modulatorSignalBox_Paint);
PictureBox modulatedSignalBox = new PictureBox()
{
Location = new Point(400, 10),
Size = new Size(360, 180),
Visible = true,
Name = "Modulated Signal"
};
modulatedSignalBox.Paint += new PaintEventHandler(modulatedSignalBox_Paint);
PictureBox demodulatedSignalBox = new PictureBox()
{
Location = new Point(400, 200),
Size = new Size(360, 180),
Visible = true,
Name = "Demodulated Signal"
};
demodulatedSignalBox.Paint += new PaintEventHandler(demodulatedSignalBox_Paint);
Controls.Add(carrierSignalBox);
Controls.Add(modulatorSignalBox);
Controls.Add(modulatedSignalBox);
Controls.Add(demodulatedSignalBox);
GenerateSignal();
}
private void GenerateSignal()
{
for (int i = 0; i < SignalLength; i++)
{
carrierSignal[i] = Math.Sin(2 * Math.PI * carrierFrequency * i);
modulatorSignal[i] = Math.Sin(2 * Math.PI * i);
modulatedSignal[i] = carrierSignal[i] * modulatorSignal[i];
demodulatedSignal[i] = modulatedSignal[i] * carrierSignal[i];
}
}
private void carrierSignalBox_Paint(object? sender, PaintEventArgs e)
{
DrawSignal(e.Graphics, carrierSignalBox, carrierSignal, Color.Blue);
}
private void modulatorSignalBox_Paint(object? sender, PaintEventArgs e)
{
DrawSignal(e.Graphics, modulatorSignalBox, modulatorSignal, Color.Red);
}
private void modulatedSignalBox_Paint(object? sender, PaintEventArgs e)
{
DrawSignal(e.Graphics, modulatedSignalBox, modulatedSignal, Color.Green);
}
private void demodulatedSignalBox_Paint(object? sender, PaintEventArgs e)
{
DrawSignal(e.Graphics, demodulatedSignalBox, demodulatedSignal, Color.Black);
}
void DrawSignal(Graphics graphics, PictureBox pictureBox, double[] signal, Color color)
{
// Get the graphics object for the PictureBox
//var graphics = pictureBox.CreateGraphics();
// Clear the PictureBox
graphics.Clear(Color.White);
// Set the pen color
var pen = new Pen(color);
// Scale the signal's values to the size of the PictureBox
var yScale = (double)pictureBox.Height / 2.0;
var xScale = (double)pictureBox.Width / (double)signal.Length;
// Draw the signal
for (int i = 0; i < signal.Length - 1; i++)
{
var x1 = (int)(i * xScale);
var y1 = (int)(yScale + (signal[i] * yScale));
var x2 = (int)((i + 1) * xScale);
var y2 = (int)(yScale + (signal[i + 1] * yScale));
graphics.DrawLine(pen, x1, y1, x2, y2);
}
}
}
When you want to redraw the PictureBox, just call the Invalidate method and the Paint event is automatically called. Example:
carrierSignalBox.Invalidate()
I have created a program to draw square grids on a selected image. It works fine for images that has small resolution, but it doesn't work properly on large images.
The all grid lines are not visible seem when the image is saved as file.
The image I am testing has resolution 3600x4320 and can be shown in the link.
How can I fix this problem?
My code:
Image drawGrid(int n, string imgPath)
{
Image img = Image.FromFile(imgPath);
Graphics grp = Graphics.FromImage(img);
grp.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
float m = img.Width * 1f / n;
for (int i = 1; i < n; i++)
{
var x = new PointF(i * m, 0);
var y = new PointF(i * m, img.Height);
grp.DrawLine(Pens.Red, x, y);
}
for (int i = 1; i <= (int)(this.Height / m); i++)
{
var x = new PointF(0, i * m);
var y = new PointF(img.Width, i * m);
grp.DrawLine(new Pen(Color.Red, 5f), x, y);
}
return img;
}
void BtnExportClick(object sender, EventArgs e)
{
if(saveFileDialog1.ShowDialog() == DialogResult.OK)
{
int n = (int)numericUpDown1.Value;
drawGrid(n, txtImagePath.Text).Save(saveFileDialog1.FileName, System.Drawing.Imaging.ImageFormat.Jpeg);
MessageBox.Show("Done");
}
}
The result image is below (resolution reduced to upload)
The grid lines not shown correctly.
The major problem is in this line:
for (int i = 1; i <= (int)(this.Height / m); i++)
▶ this.Height is clearly not what you wanted to write, let's replace it with the Image.Height
▶ grp.DrawLine(Pens.Red, x, y); and grp.DrawLine(new Pen(Color.Red, 5f), x, y); will draw lines of different size (1 and 5 pixels). In the sample code, the two methods accept Color and float arguments that define the Pen color and size.
▶ grp.SmoothingMode: we don't want any smoothing mode here, not needed to draw straight lines and it will add anti-alias which will be clearly visible, especially when saving the Image in JPEG format (it will anti-alias - sort of, it actually mangles the colors - these lines by itself).
▶ You're not disposing of any of the Graphics object you create. This is quite important with both frequent graphics operations and when working with large Bitmaps.
The Pen and Graphics objects needs to be disposed.
Since it's not exactly clear if you want to generate a grid that has the same number of lines in both dimensions - hence, a grid with Cells in which the Width is not equal to the Height, most probably - or a grid with squared Cells (this is what the sample Image seems to show, not the code), I posted two method that draw both grid types:
First method, same number of lines in both width and height:
var gridSizeX = (float)image.Width / lines;
var gridSizeY = (float)image.Height / lines;
private Image DrawGridLines(int lines, string imgPath, Color penColor, float penSize)
{
var image = Image.FromStream(new MemoryStream(File.ReadAllBytes(imgPath)), true);
using (var g = Graphics.FromImage(image)) {
g.PixelOffsetMode = PixelOffsetMode.Half;
var gridSizeX = (float)image.Width / lines;
var gridSizeY = (float)image.Height / lines;
for (int i = 1; i < lines; i++) {
var pointX1 = new PointF(0, i * gridSizeY);
var pointX2 = new PointF(image.Width, i * gridSizeY);
var pointY1 = new PointF(i * gridSizeX, 0);
var pointY2 = new PointF(i * gridSizeX, image.Height);
using (var pen = new Pen(penColor, penSize)) {
g.DrawLine(pen, pointX1, pointX2);
g.DrawLine(pen, pointY1, pointY2);
}
}
return image;
}
}
Second method, drawing a squared grid. The integer value, gridSection, is used to define a grid Cell based on the minimum dimension of the Bitmap.
This dimension is then used to determine how many lines to draw in the other dimension.
The grid size is calculated on the minimum dimension:
var gridSize = (float)Math.Min(image.Width, image.Height) / gridSection;
And the Cell are determined as a consequence:
var gridStepMin = Math.Min(image.Width, image.Height) / gridSize;
var gridStepMax = Math.Max(image.Width, image.Height) / gridSize;
private Image DrawSquaredGrid(int gridSection, string imgPath, Color penColor, float penSize)
{
var image = Image.FromStream(new MemoryStream(File.ReadAllBytes(imgPath)), true);
using (var g = Graphics.FromImage(image)) {
g.PixelOffsetMode = PixelOffsetMode.Half;
var gridSize = (float)Math.Min(image.Width, image.Height) / gridSection;
var gridStepMin = Math.Min(image.Width, image.Height) / gridSize;
var gridStepMax = Math.Max(image.Width, image.Height) / gridSize;
for (int i = 1; i < gridStepMin; i++) {
var pointY1 = new PointF(i * gridSize, 0);
var pointY2 = new PointF(i * gridSize, image.Height);
using (var pen = new Pen(penColor, penSize)) {
g.DrawLine(pen, pointY1, pointY2);
}
}
for (int i = 1; i < gridStepMax; i++) {
var pointX1 = new PointF(0, i * gridSize);
var pointX2 = new PointF(image.Width, i * gridSize);
using (var pen = new Pen(penColor, penSize)) {
g.DrawLine(pen, pointX1, pointX2);
}
}
return image;
}
}
The SaveFileDialog is refactored to allow multiple Image formats. and to call one of the drawing methods based on a selection (in the sample code, a CheckBox (chkSquared) is used select one of the Grid types).
You can add more formats, the ImageFormatFromFileName() methods selects the ImageFormat type based on the SaveFileDialog.FielName extension.
private void BtnExportClick(object sender, EventArgs e)
{
string imagePath = [Some Path];
using (var sfd = new SaveFileDialog()) {
sfd.Filter = "PNG Image (*.png)|*.png|TIFF Image (*.tif)|*.tif|JPEG Image (*.jpg)|*.jpg";
sfd.RestoreDirectory = true;
sfd.AddExtension = true;
if (sfd.ShowDialog() == DialogResult.OK) {
Image image = null;
if (chkSquared.Checked) {
image = DrawSquaredGrid((int)numericUpDown1.Value, imagePath, Color.Red, 5.0f);
}
else {
image = DrawGridLines((int)numericUpDown1.Value, imagePath, Color.Red, 5.0f);
}
image.Save(sfd.FileName, ImageFormatFromFileName(sfd.FileName));
MessageBox.Show("Done");
image.Dispose();
}
}
}
private ImageFormat ImageFormatFromFileName(string fileName)
{
string fileType = Path.GetExtension(fileName).Remove(0, 1);
if (fileType.Equals("tif")) fileType = "tiff";
if (fileType.Equals("jpg")) fileType = "jpeg";
return (ImageFormat)new ImageFormatConverter().ConvertFromString(fileType);
}
I ran into a problem when trying to change the size of all PictureBoxes in a project.
The PictureBoxes have been created like this:
for (int x = 0; x < 2; x++)
{
string filePath = fileEntries[i];
string fileName = Path.GetFileName(filePath);
int index = Array.IndexOf(fileEntries, filePath);
PictureBox image = new PictureBox();
image.Text = filePath;
image.Top = (int)y * 185 + 8 + 185;
image.Left = (int)x * 325 + 9;
image.Name = "picbox";
image.Click += picbox_Click;
image.Image = Image.FromFile(filePath);
image.BackColor = Color.FromArgb(0, 0, 110);
image.Height = 181;
image.Width = 318;
image.Padding = new Padding(2);
image.Name = "picbox";
this.Controls.Add(image);
}
Then, when clicking a box, I want to change the height, width, padding and Name of all PictureBoxes on the Form. Currently, I am using the following code:
picbox.BackColor = Color.FromArgb(0, 0, 110);
picbox.Height = 177;
picbox.Width = 314;
picbox.Padding = new Padding(0);
picbox.Name = "picboxnew";
This is not working, does anyone know how I can make this work?
Kind regards,
you can do it using Linq:
var pictureboxes = this.Controls.OfType<PictureBox>().ToList();
foreach (PictureBox pb in pictureboxes)
{
pb.Height = 500;
pb.Name = "some_name";
//etc
}
I'm trying to draw rectangles into a WriteableBitmap, unfortunatelly the WriteableBitmapEx that provides Fill* extensions are too slow and can be run only at the main thread.
I'm looking for alternatives specific for WP8.1 and don't know the best solution so far.
I need a way to draw the rectangles async, one approach was creating a Canvas at the MainWindow and adding xaml.Rectangles on it, this almost can be used as solution for the problem, but I want specific draw the rectangles on the WriteableBitmap instead of creating a ton of UIElements and adding all of then on the screen.
Sorry if any given solution can be found on internet, I can't find almost nothing about C#.
A test I did:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
var container = new Canvas()
{
Width = 300,
Height = 500
};
var winImage = new Image()
{
Width = 300,
Height = 500
};
container.Children.Add(winImage);
//var winImage = imageView.NativeView<Image>();
var img = new WriteableBitmap((int)winImage.Width, (int)winImage.Height);
var clr = Color.FromArgb(255, 0, 0, 255);
var start = DateTime.Now;
var random = new Random();
for (int i = 0; i < 50; i++)
{
//var color = Color.FromArgb(255, (byte)random.Next(255), (byte)random.Next(255), (byte)random.Next(255));
img.FillRectangle(i * 2, i * 2, i * 2 + 10, i * 2 + 10, clr);
}
Debug.WriteLine((DateTime.Now - start).TotalMilliseconds + "ms drawing");
winImage.Source = img;
Content = container;
}
This results in "792.1397ms drawing" running on debug mode on a Nokia Lumia 1020, that is pretty slow.
Using GetBitmapContext() should make it a lot faster.
protected override void OnNavigatedTo(NavigationEventArgs e)
{
var container = new Canvas()
{
Width = 300,
Height = 500
};
var winImage = new Image()
{
Width = 300,
Height = 500
};
container.Children.Add(winImage);
var img = BitmapFactory.New((int)winImage.Width, (int)winImage.Height);
winImage.Source = img;
Content = container;
var clr = Color.FromArgb(255, 0, 0, 255);
var random = new Random();
var sw = new Stopwatch();
sw.Start();
using (img.GetBitmapContext()) {
img.Clear(Colors.White);
for (var x = 0; x < 10; x++) {
for (var y = 0; y < 10; y++) {
img.FillRectangle(x * 10, y * 10, x * 10 + 10, y * 10 + 10, clr);
}
}
}
sw.Stop();
Debug.WriteLine(sw.ElapsedMilliseconds + "ms drawing");
}
I can filter red and blue color separately but i want to filter both at the same time.. so my code is like this
//FOR RED COLOR
ColorFiltering filter = new ColorFiltering();
filter.Red = new IntRange(100, 255);
filter.Green = new IntRange(0, 75);
filter.Blue = new IntRange(0, 75);
filter.ApplyInPlace(image1);
MyDraw(image1);
// FOR BLUE COLOR
EuclideanColorFiltering filter2 = new EuclideanColorFiltering();
filter2.CenterColor = new RGB(Color.FromArgb(9, 39, 101));
filter2.Radius = 50;
filter2.ApplyInPlace(image1);
MyDraw(image1);
public void MyDraw(Bitmap image)
{
BlobCounter blobCounter = new BlobCounter();
blobCounter.MinWidth = 2;
blobCounter.MinHeight = 2;
blobCounter.FilterBlobs = true;
blobCounter.ObjectsOrder = ObjectsOrder.Size;
Grayscale grayFilter = new Grayscale(0.2125, 0.7154, 0.0721);
Bitmap grayImage = grayFilter.Apply(image);
blobCounter.ProcessImage(grayImage);
Rectangle[] rects = blobCounter.GetObjectsRectangles();
foreach (Rectangle recs in rects)
{
if (rects.Length > 0)
{
Rectangle objectRect = rects[0];
//Graphics g = Graphics.FromImage(image);
Graphics g = pictureBox1.CreateGraphics();
reception = "Cam," + objectRect.X + "," + objectRect.Y;
Console.WriteLine("X: " + objectRect.X + " Y:" + objectRect.Y.ToString());
using (Pen pen = new Pen(Color.FromArgb(252, 3, 26), 2))
{
g.DrawRectangle(pen, objectRect);
}
int objectX = objectRect.X + (objectRect.Width / 2);
int objectY = objectRect.Y + (objectRect.Height / 2);
g.DrawString(objectX.ToString() + "X" + objectY.ToString(), new Font("Arial", 12), Brushes.Red, new System.Drawing.Point(250, 1));
g.Dispose();
}
}
}
So i want to recognize blue and red shapes on webcam and draw a rectangle around recognized shape. For now, I can do it as red or blue. But I want to recognize red and blue colors at the same time
how can i add multiple filters?