I tried to write a code for detecting elips objects with Aforge blobcounter function but when I want to draw it with graphics I am getting an error.
The error is:
Argument 2:cannot covert from 'AForge.IntPoint' to 'System.Drawing.PointF'.What is the thing that I am doing wrong and how can I fix it?
Here is the code:
namespace blobdnm
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog sfd = new OpenFileDialog();
sfd.Filter = "Image Files|*.bmp|All Files|*.*";
sfd.InitialDirectory = ".";
if (sfd.ShowDialog() != DialogResult.OK)
{
return;
}
pictureBox1.ImageLocation = sfd.FileName;
}
private void button2_Click(object sender, EventArgs e)
{
Bitmap bmp = new Bitmap(pictureBox1.Image);
BitmapData BmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
byte[] data = new byte[bmp.Width*bmp.Height*3];
IntPtr ptr = BmpData.Scan0;
Marshal.Copy(ptr, data, 0, data.Length);
for (int i = 0; i < bmp.Width*bmp.Height*3; i=i+3)
{
double a = data[i] * 0.2125 + data[i + 1] * 0.7154 + data[i + 2] *0.0721;
if(a>100)
{
data[i] = 0;
data[i+1] = 0;
data[i+2] = 0;
}
}
Bitmap bmp2 = new Bitmap(bmp.Width,bmp.Height,PixelFormat.Format24bppRgb);
BitmapData BmpData2 = bmp2.LockBits(new Rectangle(0, 0, bmp2.Width, bmp2.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
Marshal.Copy(data, 0,BmpData2.Scan0, data.Length);
bmp2.UnlockBits(BmpData2);
ColorFiltering colorFilter = new ColorFiltering();
BlobCounter blobCounter = new BlobCounter();
blobCounter.FilterBlobs = true;
blobCounter.MinWidth = 5;
blobCounter.MinHeight = 5;
blobCounter.MaxWidth = 3000;
blobCounter.MaxHeight = 3000;
blobCounter.ProcessImage(BmpData2);
Blob[] blobs = blobCounter.GetObjectsInformation();
Graphics g = Graphics.FromImage(bmp2);
Pen redPen = new Pen(Color.Red, 2);
List<IntPoint> edgePoints=null;
for (int i = 0; i < blobs.Length; i++)
{
edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]);
for (int k = 0; k < edgePoints.Count; k++)
{
g.DrawPolygon(redPen, edgePoints[k]); //This is the part that I am getting an error
}
}
redPen.Dispose();
g.Dispose();
pictureBox1.Image = bmp2;
}
private System.Drawing.Point[] ToPointsArray(List<IntPoint> points)
{
System.Drawing.Point[] array = new System.Drawing.Point[points.Count];
for (int i = 0, n = points.Count; i < n; i++)
{
array[i] = new System.Drawing.Point(points[i].X, points[i].Y);
}
return array;
}
}
}
You have to convert AForge.IntPoint into System.Drawing.Point and then pass it to Graphics.DrawPolygon() method.
This will do the job:
public System.Drawing.Point ToPoint(IntPoint point)
{
return new System.Drawing.Point(point.X, point.Y);
}
In fact you have method ToPointsArray() doing the same conversion but on the list of IntPoint in your code.
Related
I am trying to write a shape detection algorithm using Blobcounter with Aforge.Actually I want to get number of all pixels on the edges of the objects with this code but I could not be successfull about writing clearly and I am getting an error:
System.ArgumentOutOfRangeException: 'Index was out of range. It must not be a negative value and must be smaller than the size of the collection.
How can I fix that?
This is the code that I wrote:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.Drawing.Imaging;
using AForge.Imaging;
using System.Runtime.InteropServices;
using AForge.Math.Geometry;
using AForge;
using AForge.Imaging.Filters;
using System.Windows.Forms;
namespace blobdnm
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog sfd = new OpenFileDialog();
sfd.Filter = "Image Files|*.bmp|All Files|*.*";
sfd.InitialDirectory = ".";
if (sfd.ShowDialog() != DialogResult.OK)
{
return;
}
pictureBox1.ImageLocation = sfd.FileName;
}
private void button2_Click(object sender, EventArgs e)
{
Bitmap bmp = new Bitmap(pictureBox1.Image);
BitmapData BmpData1 = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
bmp.UnlockBits(BmpData1);
Grayscale gfilter = new Grayscale(0.2125, 0.7154, 0.0721);
Invert ifilter = new Invert();
BradleyLocalThresholding thfilter = new BradleyLocalThresholding();
bmp = gfilter.Apply(bmp);
thfilter.ApplyInPlace(bmp);
ifilter.ApplyInPlace(bmp);
BitmapData BmpData2 = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
BlobCounterBase blobCounter = new BlobCounter();
blobCounter.FilterBlobs = true;
blobCounter.MinWidth = 1;
blobCounter.MinHeight = 1;
blobCounter.MaxWidth = 8;
blobCounter.MaxHeight = 8;
ColorFiltering colorFilter = new ColorFiltering();
colorFilter.Red = new IntRange(0, 64);
colorFilter.Green = new IntRange(0, 64);
colorFilter.Blue = new IntRange(0, 64);
colorFilter.FillOutsideRange = false;
colorFilter.ApplyInPlace(BmpData2);
blobCounter.ProcessImage(BmpData2);
bmp.UnlockBits(BmpData2);
Blob[] blobs = blobCounter.GetObjectsInformation();
SimpleShapeChecker shapeChecker = new SimpleShapeChecker();
Bitmap bmp3 = new Bitmap(bmp.Width, bmp.Height);
Graphics g = Graphics.FromImage(bmp3);
Pen redPen = new Pen(Color.Red, 2);
Pen brownPen = new Pen(Color.Brown, 2);
Pen greenPen = new Pen(Color.Green, 2);
Pen bluePen = new Pen(Color.Blue, 2);
for (int i = 0; i < blobs.Length; i++)
{
List<IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]);
{
List<IntPoint> corners;
if (shapeChecker.IsConvexPolygon(edgePoints, out corners))
{
PolygonSubType subType = shapeChecker.CheckPolygonSubType(corners);
Pen pen;
if (subType == PolygonSubType.Unknown)
{
pen = (corners.Count == 4) ? redPen : bluePen;
}
else
{
pen = (corners.Count == 4) ? brownPen : greenPen;
}
g.DrawPolygon(pen, ToPointsArray(corners));
}
}
}
redPen.Dispose();
greenPen.Dispose();
bluePen.Dispose();
brownPen.Dispose();
g.Dispose();
Clipboard.SetDataObject(bmp3);
pictureBox1.Image = bmp3;
}
private System.Drawing.Point[] ToPointsArray(List<IntPoint> points)
{
System.Drawing.Point[] array = new System.Drawing.Point[points.Count];
for (int i = 0, n = points.Count; i < n; i++)
{
array[i] = new System.Drawing.Point(points[i].X, points[i].Y);
}
return array;
}
}
}
This is the part that I am getting an error.
if (shapeChecker.IsConvexPolygon(edgePoints, out corners))//This is the part of the code that I am getting an error
{
PolygonSubType subType = shapeChecker.CheckPolygonSubType(corners);
Pen pen;
if (subType == PolygonSubType.Unknown)
{
pen = (corners.Count == 4) ? redPen : bluePen;
}
else
{
pen = (corners.Count == 4) ? brownPen : greenPen;
}
g.DrawPolygon(pen, ToPointsArray(corners));
}
}
}
Graphics graphics = Graphics.FromImage(BitMap_1); // <--This is not allowed? How can I fix it?How can I declare graphics as global?
Here is some more code...
Here is some more code...
Here is some more code...
Here is some more code...
public partial class Form1 : Form
{
string WAV_filePath = #"";
string MIDI_filePath = #"";
string filePath = #"C:\Users\Steffan\Desktop\guitar\Gert toets die Elektroniese Konsertina.wav";//Guitar 2.wav";//Sine Wave 440Hz.wav";
SoundPlayer player1 = new SoundPlayer();
byte[] RawWaveDataArray = new byte[100];
Int16[] Data_16Bit = new Int16[100];
int NumberOfSamples = 0;
bool PLAY_ = false;
Point[] Points = new Point[886];
// Create pen.
Pen Pen_ = new Pen(Color.White, 0);
Bitmap BitMap_1 = new Bitmap(1138, 72);
Graphics graphics = Graphics.FromImage(BitMap_1); // <--This is not allowed? How can I fix it?How can I declare graphics as global?
public Form1()
{
InitializeComponent();
}
private void timer1_Tick(object sender, EventArgs e)
{
if (PLAY_ == true)
{
Wave_x_Inc = 0;
graphics.Clear(Color.Black);
for (int x = 0; x < 886; x++)
{
Points[x] = new Point(Wave_x_Inc, (int)((Data_16Bit[DataIndex] * 0.002F) + (pictureBox4.Height / 2)));
Wave_x_Inc = Wave_x_Inc + 2;
DataIndex = DataIndex + 2;
if (DataIndex > Data_16Bit.Length/2) { DataIndex = 0; x = 886; }
}
if (Wave_x_Inc > pictureBox4.Width) { Wave_x_Inc = 0; }
graphics.DrawBeziers(Pen_, Points);
WaveLengthCounter = WaveLengthCounter + 886;
int Temp_Val = WaveLengthCounter / DataLenth_Fraction;
if (Temp_Val <= 300) { trackBar1.Value = Temp_Val; }
else { trackBar1.Value = 0; }
if (WaveLengthCounter > Data_16Bit.Length/2)
{
WaveLengthCounter = 0;
}
pictureBox4.Image = BitMap_1;
}
}
}
Try this, it may help you.
var bitmap = new Bitmap(width, height);
var graphics = Graphics.FromImage(bitmap);
graphics.DrawRectangle(Pens.Black, 0, 0, 10, 10);
bitmap.Save("MyShapes.png");
I try to write simple shape detection app. I'm using sample from Aforge.net library. But I always get same error:
cannot convert from 'AForge.Point[]' to 'System.Drawing.PointF[]'
I try to change some things in ImageProcess method as well as in ToPointsArray, but effect is always the same. What else can I try? What I do wrong?
Here is code:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
try
{
ProcessImage((Bitmap)Bitmap.FromFile(openFileDialog1.FileName));
}
catch
{
MessageBox.Show("Załadowanie obrazu niepowiodło się.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void ProcessImage(Bitmap bitmap)
{
//-------------------------------------
BitmapData bitmapData = bitmap.LockBits(
new Rectangle(0, 0, bitmap.Width, bitmap.Height),
ImageLockMode.ReadWrite, bitmap.PixelFormat);
//-------------------------------------
ColorFiltering colorFilter = new ColorFiltering();
colorFilter.Red = new IntRange(0, 64);
colorFilter.Green = new IntRange(0, 64);
colorFilter.Blue = new IntRange(0, 64);
colorFilter.FillOutsideRange = false;
colorFilter.ApplyInPlace(bitmapData);
//-------------------------------------
BlobCounter blobCounter = new BlobCounter();
blobCounter.FilterBlobs = true;
blobCounter.MinHeight = 5;
blobCounter.MinWidth = 5;
blobCounter.ProcessImage(bitmapData);
Blob[] blobs = blobCounter.GetObjectsInformation();
bitmap.UnlockBits(bitmapData);
//-------------------------------------
SimpleShapeChecker shapeChecker = new SimpleShapeChecker();
Graphics g = Graphics.FromImage(bitmap);
Pen redPen = new Pen(Color.Red, 2); // quadrilateral
Pen brownPen = new Pen(Color.Brown, 2); // quadrilateral with known sub-type
Pen greenPen = new Pen(Color.Green, 2); // known triangle
Pen bluePen = new Pen(Color.Blue, 2); // triangle
for (int i = 0, n = blobs.Length; i < n; i++)
{
List<IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]);
{
List<IntPoint> corners;
// is triangle or quadrilateral
if (shapeChecker.IsConvexPolygon(edgePoints, out corners))
{
// get sub-type
PolygonSubType subType = shapeChecker.CheckPolygonSubType(corners);
Pen pen;
if (subType == PolygonSubType.Unknown)
{
pen = (corners.Count == 4) ? redPen : bluePen;
}
else
{
pen = (corners.Count == 4) ? brownPen : greenPen;
}
g.DrawPolygon(pen, ToPointsArray(corners));
}
}
}
redPen.Dispose();
greenPen.Dispose();
bluePen.Dispose();
brownPen.Dispose();
g.Dispose();
// put new image to clipboard
Clipboard.SetDataObject(bitmap);
// and to picture box
pictureBox1.Image = bitmap;
UpdatePictureBoxPosition();
}
private Point[] ToPointsArray(List<IntPoint> points)
{
Point[] array = new Point[points.Count];
for (int i = 0, n = points.Count; i < n; i++)
{
array[i] = new Point(points[i].X, points[i].Y);
}
return array;
}
Your problem is that AForge have there own Point struct so your ToPointArray method actually returns an Aforge Points array rather than an array of the needed .net Point. The simplest solution is to fully qualify the type you want to use, so your method would become
private System.Drawing.Point[] ToPointsArray(List<IntPoint> points)
{
System.Drawing.Point[] array = new System.Drawing.Point[points.Count];
...
}
Alternatively, if you wanted to save a few characters you could alias the namespace with a using statement at the top of the class.
using NetPoint = System.Drawing.Point;
private NetPoint ToPointsArray(List<IntPoint> points)
{
NetPoint array = new NetPoint[points.Count];
...
}
As a side note this method could be shortened if linq is available to use. For example,
private System.Drawing.Point[] ToPointsArray(List<IntPoint> points)
{
return points.Select(p => new System.Drawing.Point(p.X, p.Y)).ToArray();
}
I Have windows form but i want to print panel in windows form to hidden print button and it's my code :
private void printDoc_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
System.Drawing.Image image = System.Drawing.Image.FromStream(this.streamToPrint);
int x = e.MarginBounds.X;
int y = e.MarginBounds.Y;
int width = image.Width;
int height = image.Height;
if ((width / e.MarginBounds.Width) > (height / e.MarginBounds.Height))
{
width = e.MarginBounds.Width;
height = image.Height * e.MarginBounds.Width / image.Width;
}
else
{
height = e.MarginBounds.Height;
width = image.Width * e.MarginBounds.Height / image.Height;
}
System.Drawing.Rectangle destRect = new System.Drawing.Rectangle(x, y, width, height);
e.Graphics.DrawImage(image, destRect, 0, 0, image.Width, image.Height, System.Drawing.GraphicsUnit.Pixel);
}
public void StartPrint(Stream streamToPrint, string streamType)
{
this.printDoc.PrintPage += new PrintPageEventHandler(printDoc_PrintPage);
this.streamToPrint = streamToPrint;
this.streamType = streamType;
System.Windows.Forms.PrintDialog PrintDialog1 = new PrintDialog();
PrintDialog1.AllowSomePages = true;
PrintDialog1.ShowHelp = true;
PrintDialog1.Document = printDoc;
DialogResult result = PrintDialog1.ShowDialog();
if (result == DialogResult.OK)
{
printDoc.Print();
//docToPrint.Print();
}
}
private void button_Print_Certificate_Click(object sender, EventArgs e)
{
Graphics g1 = this.CreateGraphics();
Image MyImage = new Bitmap(this.ClientRectangle.Width, this.ClientRectangle.Height, g1);
Graphics g2 = Graphics.FromImage(MyImage);
IntPtr dc1 = g1.GetHdc();
IntPtr dc2 = g2.GetHdc();
BitBlt(dc2, 0, 0, this.ClientRectangle.Width, this.ClientRectangle.Height, dc1, 0, 0, 13369376);
g1.ReleaseHdc(dc1);
g2.ReleaseHdc(dc2);
MyImage.Save(#"D:\PrintPage.jpg", ImageFormat.Jpeg);
FileStream fileStream = new FileStream(#"D:\PrintPage.jpg", FileMode.Open, FileAccess.Read);
StartPrint(fileStream, "Image");
fileStream.Close();
if (System.IO.File.Exists(#"D:\PrintPage.jpg"))
{
System.IO.File.Delete(#"D:\PrintPage.jpg");
}
}
In order to print a particular control, you'll want to use that control as the source of your BitBlt operation.
So instead of this.CreateGraphics(), call panel.CreateGraphics(). Similarly, use panel.ClientRectangle to get the width and height of the image.
But take a look at https://stackoverflow.com/a/597088/103167 which gives you an easier way.
I have a program which displays an image to the windows form, and places a message within the image as it paints it (this works fine) i then have a method which reads the message back. However, doing this causes the winforms screen to freeze! i must be getting stuck in an endless loop. The method does work as i do get the message back.... can anyone help un-freeze my program?
Code below:
public partial class MyImages : Form
{
//I have variables related to encoding and decoding here(deleted)
private const String MESSAGE = "2008-01-07";
Bitmap firstLoaded;
Bitmap theImage;
Bitmap imageEmbedded;
Boolean isGetMessage = false;
Boolean isEmbedImage = false;
Boolean isLoaded = false;
Graphics graphicsWindow; // reference to the graphic surface of this window
Graphics graphicsImage; // reference to in-memory surface
BitArray bitsOfMessage = new BitArray(8);
String bytesOfTheMessage = null;
public MyImages()
{
InitializeComponent();
this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.DoubleBuffer, true);
}
private void MyImages_Paint(object sender, PaintEventArgs e)
{
HandlePainting();
}
public void HandlePainting()
{
if (isLoaded == true)
{
theImage = new Bitmap(Width, Height); // bitmap for window surface copy
graphicsWindow = CreateGraphics(); // get our current window's surface
graphicsImage = Graphics.FromImage(theImage); // create surfaces from the bitmaps
graphicsImage.DrawImage(firstLoaded, 0, 0, Width, Height);
if (isEmbedImage == true)
{
theImage = embedMessageInImage(theImage);
}
else if (isGetMessage == true)
{
getEmbeddedMessage(imageEmbedded);
}
if (isGetMessage == false)
{
graphicsWindow.DrawImage(theImage, 0, 0);
}
else if (isGetMessage == true)
{
graphicsWindow.DrawImage(imageEmbedded, 0, 0);
}
}
}
private void toolStripMenuItemLoadImage_Click(object sender, EventArgs e)
{
using (OpenFileDialog ofd = new OpenFileDialog())
{
ofd.Title = "Load Image";
if (ofd.ShowDialog() == DialogResult.OK)
{
firstLoaded = new Bitmap(ofd.FileName);
this.Invalidate();
}
}
isLoaded = true;
}
private void toolStripMenuEmbedMessage_Click(object sender, EventArgs e)
{
isEmbedImage = true;
isGetMessage = false;
this.Invalidate();
}
private void toolStripMenuItemGetMessage_Click(object sender, EventArgs e)
{
isEmbedImage = false;
isGetMessage = true;
this.Invalidate();
}
public void convertToChar(int byteChar)
{
char val = Convert.ToChar(byteChar);
String nextChar = val.ToString();
bytesOfTheMessage += nextChar;
}
private Bitmap embedMessageInImage(Bitmap bmp)
{
//Embed message in this method (deleted)
//unlock the bitmaps
newBitmap.UnlockBits(newData);
bmp.Save("tina.bmp");
bmp.UnlockBits(originalData);
newBitmap.Save("tina7.bmp");
imageEmbedded = newBitmap;
return newBitmap;
}
}
private void getEmbeddedMessage(Bitmap bmp)
{
unsafe
{
//create an empty bitmap the same size as original
Bitmap newBitmap = new Bitmap(bmp.Width, bmp.Height);
//lock the original bitmap in memory
System.Drawing.Imaging.BitmapData originalData = bmp.LockBits(
new Rectangle(0, 0, bmp.Width, bmp.Height),
System.Drawing.Imaging.ImageLockMode.ReadOnly,
System.Drawing.Imaging.PixelFormat.Format24bppRgb);
//lock the new bitmap in memory
System.Drawing.Imaging.BitmapData newData = newBitmap.LockBits(
new Rectangle(0, 0, bmp.Width, bmp.Height),
System.Drawing.Imaging.ImageLockMode.WriteOnly,
System.Drawing.Imaging.PixelFormat.Format24bppRgb);
//set the number of bytes per pixel
int pixelSize = 3;
for (int y = 0; y < bmp.Height; y++)
{
//get the data from the original image
byte* originalImageRow = (byte*)originalData.Scan0 + (y * originalData.Stride);
//get the data from the new image
byte* newImageRow = (byte*)newData.Scan0 + (y * newData.Stride);
for (int x = 0; x < bmp.Width; x++)
{
byte b = (byte)(originalImageRow[x * pixelSize + 0]); // B
getEachBitOfMessage(b, BLUE);
byte g = (byte)(originalImageRow[x * pixelSize + 1]); // G
getEachBitOfMessage(g, GREEN);
byte r = ((byte)(originalImageRow[x * pixelSize + 2])); //R
getEachBitOfMessage(r, RED);
}
}
//unlock the bitmaps
newBitmap.UnlockBits(newData);
bmp.UnlockBits(originalData);
}
}
public byte changeEachBit(byte byteToManipulate, int colour, byte theMessage)
{
byte value = 0;
byte returnByte = 0;
if (colour == BLUE)
{
value= (byte)(theMessage & BValueMask);
value = (byte)(value>>5);
returnByte = (byte)(byteToManipulate & BlueMask);
returnByte = (byte)(returnByte | value);
}
else if (colour == GREEN)
{
value = (byte)(theMessage & GValueMask);
value = (byte)(value >> 3);
returnByte = (byte)(byteToManipulate & GreenMask);
returnByte = (byte)(returnByte | value);
}
else if (colour == RED)
{
value = (byte)(theMessage & RValueMask);
returnByte = (byte)(byteToManipulate & RedMask);
returnByte = (byte)(returnByte | value);
}
return returnByte;
}
public void getEachBitOfMessage(byte byteToManipulate, int colour)
{
//I Input bits into image here (deleted)
}
}
}
Let it freeze and click the Pause button on the top toolbar.
This will cause the debugger to break wherever execution may be, and you can then easily identify where it got stuck, and try and find out why as well (don't forget to watch values using the watch window or hovering them).