how to draw into image bounding box in c# - c#

i tried to draw into BMB image and i measure bounding box of each character i want to draw but nothing happen what's the wrong please ?
this is the code which draw the text
private void button2_Click(object sender, EventArgs e)
{
Bitmap bitmap = (Bitmap)Image.FromFile(imagepath);//load the image file
Bitmap newBitmap = new Bitmap(bitmap.Width, bitmap.Height);
PointF GLocation = new PointF(float.Parse(textBox1.Text), float.Parse(textBox2.Text));
/* PointF XLocation = new PointF(float.Parse(textBox3.Text), float.Parse(textBox4.Text));
PointF HLocation = new PointF(float.Parse(textBox5.Text), float.Parse(textBox6.Text));
PointF ZLocation = new PointF(float.Parse(textBox7.Text), float.Parse(textBox8.Text));
PointF YLocation = new PointF(float.Parse(textBox9.Text), float.Parse(textBox10.Text));
PointF KLocation = new PointF(float.Parse(textBox11.Text), float.Parse(textBox12.Text));
PointF FLocation = new PointF(float.Parse(textBox13.Text), float.Parse(textBox14.Text));
PointF ELocation = new PointF(float.Parse(textBox15.Text), float.Parse(textBox16.Text));*/
Graphics grPhoto = Graphics.FromImage(newBitmap);
grPhoto.DrawImage(bitmap, new Rectangle(0, 0, newBitmap.Width, newBitmap.Height), 0, 0, newBitmap.Width, newBitmap.Height, GraphicsUnit.Pixel);
//MessageBox.Show(measureAlphabet('G', arial).ToString());
int x = (int)measureAlphabet('G', arial).Width;
int y = (int)measureAlphabet('G', arial).Height;
Rectangle rec = measureAlphabet('G', arial);
for (int G = int.Parse(textBox1.Text); G <= G + x; G++)
{
for (G = int.Parse(textBox2.Text); G <= G + y; G++)
{
Color pixelcolor = newBitmap.GetPixel(x,y);
if (pixelcolor.R != 255 && pixelcolor.G != 255 && pixelcolor.B != 255)
{
using (Graphics graphics = Graphics.FromImage(newBitmap))
{
using (arial)
{
graphics.DrawString(firstchar, arial, Brushes.Blue, GLocation);
}
}
}
}
}
/* using (Graphics graphics = Graphics.FromImage(newBitmap))
{
using (arial)
{
graphics.DrawString(secondchar, arial, Brushes.Red, XLocation);
graphics.DrawString(thirdchar, arial, Brushes.Brown, HLocation);
graphics.DrawString(fourthchar, arial, Brushes.DarkCyan, ZLocation);
graphics.DrawString(fifthchar, arial, Brushes.DarkGreen, YLocation);
graphics.DrawString(sixthchar, arial, Brushes.Coral, KLocation);
graphics.DrawString(seventhchar, arial, Brushes.Salmon, FLocation);
graphics.DrawString(eighthchar, arial, Brushes.SeaGreen, ELocation);
}
}*/
bitmap.Dispose();
// newBitmap.Dispose();
newBitmap.Save(imagepath);
}
method which measure bounding box
public Rectangle measureAlphabet(char alph, Font font)
{
SizeF size = CreateGraphics().MeasureString(alph.ToString(), font);
Bitmap bmp = new Bitmap((int)size.Width, (int)size.Height);
Graphics grp = Graphics.FromImage(bmp);
grp.FillRectangle(Brushes.White, 0, 0, bmp.Width, bmp.Height);
grp.DrawString(alph.ToString(), font, Brushes.Black, new PointF(0, 0));
Bitmap img = (Bitmap)bmp;
int x = 0, y = 0, width = 0, height = 0;
for (int i = 0; i < img.Width; i++)
for (int j = 0; j < img.Height; j++)
if (img.GetPixel(i, j).B < 2)
{
x = i;
goto jmp1;
}
jmp1:;
for (int i = img.Width - 1; i >= 0; i--)
for (int j = 0; j < img.Height; j++)
if (img.GetPixel(i, j).B < 2)
{
width = i - x;
goto jmp2;
}
jmp2:;
for (int i = 0; i < img.Height; i++)
for (int j = 0; j < img.Width; j++)
if (img.GetPixel(j, i).B < 2)
{
y = i;
goto jmp3;
}
jmp3:;
for (int i = img.Height - 1; i >= 0; i--)
for (int j = 0; j < img.Width; j++)
if (img.GetPixel(j, i).B < 2)
{
height = i - y;
goto jmp4;
}
jmp4:;
Rectangle resultRectangle = new Rectangle(x, y, width, height);
return resultRectangle;
}

Related

Create multiple label over the multiple ellipse

I have 6 ellipse and 6 label. I want to add labels over the ellipse. 2 of labels is OK but the others not.
In debug mode there is no error.
Here is the code:
private void Form1_Paint(object sender, PaintEventArgs e)
{
int locY = 200, locX = 10, i = 0;
for (int k = 0; k < 3; k++)
{
locX += 40;
for (int j = 0; j < 2; j++)
{
locY += 30;
Pen pen = new Pen(Color.Red, 10);
e.Graphics.DrawEllipse(pen, new Rectangle(locX, locY, 10, 10));
Label label = new Label();
label.Text = i.ToString();
label.Location = new Point(locX,locY);
label.BackColor = Color.Transparent;
Controls.Add(label);
i++;
}
locY = 200;
}
}
Here is the output:
You should also create that Pen outside of the loop and make sure to dispose of it.
Here's an example using DrawString() as described in the comments:
private void Form1_Paint(object sender, PaintEventArgs e)
{
StringFormat sf = new StringFormat();
sf.Alignment = StringAlignment.Center;
sf.LineAlignment = StringAlignment.Center;
int locY = 200, locX = 10, i = 0;
using (Pen pen = new Pen(Color.Red, 10))
{
for (int k = 0; k < 3; k++)
{
locX += 40;
for (int j = 0; j < 2; j++)
{
locY += 30;
Rectangle rc = new Rectangle(locX, locY, 10, 10);
e.Graphics.DrawEllipse(pen, rc);
SizeF szF = e.Graphics.MeasureString(i.ToString(), this.Font);
Rectangle rc2 = new Rectangle(new Point(rc.Left + rc.Width / 2, rc.Top + rc.Height / 2), new Size(1, 1));
rc2.Inflate((int)szF.Width, (int)szF.Height);
e.Graphics.DrawString(i.ToString(), this.Font, Brushes.Black, rc2, sf);
i++;
}
locY = 200;
}
}
}

How to Draw a Outline (Edge ) of Irregular Shape using c#

enter image description here
Please give me a solution about that I have ti find out many site's but i did not get any solution.
thankyou
private void Form1_Load(object sender, EventArgs e)
{
Bitmap bitmap = new Bitmap(#"D:\shapes_Images\4.png");
pictureBox1.Image = bitmap;
image = bitmap ;
}
Bitmap image;
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
//Create a path and add lines.
List<Point> outlinePoints = new List<Point>();
BitmapData bitmapData = image.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
byte[] originalBytes = new byte[image.Width * image.Height * 4];
Marshal.Copy(bitmapData.Scan0, originalBytes, 0, originalBytes.Length);
//find non-transparent pixels visible from the top of the image
for (int x = 0; x < bitmapData.Width; x++)
{
for (int y = 0; y < bitmapData.Height; y++)
{
byte alpha = originalBytes[y * bitmapData.Stride + 4 * x + 3];
if (alpha != 0)
{
Point p = new Point(x, y);
if (!ContainsPoint(outlinePoints, p))
outlinePoints.Add(p);
break;
}
}
}
//helper variable for storing position of the last pixel visible from both sides
//or last inserted pixel
int? lastInsertedPosition = null;
//find non-transparent pixels visible from the right side of the image
for (int y = 0; y < bitmapData.Height; y++)
{
for (int x = bitmapData.Width - 1; x >= 0; x--)
{
byte alpha = originalBytes[y * bitmapData.Stride + 4 * x + 3];
if (alpha != 0)
{
Point p = new Point(x, y);
if (!ContainsPoint(outlinePoints, p))
{
if (lastInsertedPosition.HasValue)
{
outlinePoints.Insert(lastInsertedPosition.Value + 1, p);
lastInsertedPosition += 1;
}
else
{
outlinePoints.Add(p);
}
}
else
{
//save last common pixel from visible from more than one sides
lastInsertedPosition = outlinePoints.IndexOf(p);
}
break;
}
}
}
lastInsertedPosition = null;
//find non-transparent pixels visible from the bottom of the image
for (int x = bitmapData.Width - 1; x >= 0; x--)
{
for (int y = bitmapData.Height - 1; y >= 0; y--)
{
byte alpha = originalBytes[y * bitmapData.Stride + 4 * x + 3];
if (alpha != 0)
{
Point p = new Point(x, y);
if (!ContainsPoint(outlinePoints, p))
{
if (lastInsertedPosition.HasValue)
{
outlinePoints.Insert(lastInsertedPosition.Value + 1, p);
lastInsertedPosition += 1;
}
else
{
outlinePoints.Add(p);
}
}
else
{
//save last common pixel from visible from more than one sides
lastInsertedPosition = outlinePoints.IndexOf(p);
}
break;
}
}
}
lastInsertedPosition = null;
//find non-transparent pixels visible from the left side of the image
for (int y = bitmapData.Height - 1; y >= 0; y--)
{
for (int x = 0; x < bitmapData.Width; x++)
{
byte alpha = originalBytes[y * bitmapData.Stride + 4 * x + 3];
if (alpha != 0)
{
Point p = new Point(x, y);
if (!ContainsPoint(outlinePoints, p))
{
if (lastInsertedPosition.HasValue)
{
outlinePoints.Insert(lastInsertedPosition.Value + 1, p);
lastInsertedPosition += 1;
}
else
{
outlinePoints.Add(p);
}
}
else
{
//save last common pixel from visible from more than one sides
lastInsertedPosition = outlinePoints.IndexOf(p);
}
break;
}
}
}
// Added to close the loop
outlinePoints.Add(outlinePoints[0]);
image.UnlockBits(bitmapData);
GraphicsPath myPath = new GraphicsPath();
myPath.AddLines(outlinePoints.ToArray());
// return outlinePoints.ToArray();
PathGradientBrush pthGrBrush = new PathGradientBrush(outlinePoints.ToArray());
//foreach (Point p in outlinePoints.ToArray())
//{
// //Point p1 = p;
//}
Color[] colors = { Color.Red , Color.Green };
pthGrBrush.SurroundColors = colors;
pthGrBrush.CenterColor = Color.Red;
Blend blend = new Blend();
// blend.Factors = new float[] { 1, 0 };
blend.Positions = new float[] { 0, 0.25f };
pthGrBrush.Blend = blend;
// LinearGradientBrush linGrBrush = new LinearGradientBrush(new Point(0, 10),new Point(200, 10),Color.FromArgb(255, 255, 0, 0),Color.FromArgb(255, 0, 0, 255));
e.Graphics.FillPath(pthGrBrush, myPath);
// Pen myPen = new Pen(Color.Black, 6);
// e.Graphics.DrawPath(pthGrBrush, myPath);
}

Grayscale vs Color FFT

The following code converts a color image to Grayscale and then computes its FFT:
private void button1_Click(object sender, EventArgs e)
{
Bitmap source = pictureBox1.Image as Bitmap;
Bitmap gray = Grayscale.ToGrayscale(source);
Complex[,] cpxImage = ImageDataConverter.ToComplex(gray);
Complex[,] fftCpxImage = FourierTransform.ForwardFFT(cpxImage);
Complex[,] shiftedFftCpxImage = FourierShifter.ShiftFft(fftCpxImage);
Bitmap mag = FourierPlot.FftMagnitudePlot(shiftedFftCpxImage, PixelFormat.Format8bppIndexed);
Bitmap phase = FourierPlot.FftPhasePlot(shiftedFftCpxImage, PixelFormat.Format8bppIndexed);
pictureBox2.Image = gray;
pictureBox3.Image = mag;
pictureBox4.Image = phase;
}
The following code splits a color image into three channels computes their FFTs and merges them together to form an RGB image of the FFT.
private void button2_Click(object sender, EventArgs e)
{
Bitmap source = pictureBox1.Image as Bitmap;
int [,,] array3d = ImageDataConverter.ToInteger3d(source);
int[,] red = ArrayTools<int>.Split(array3d, 0);
int[,] green = ArrayTools<int>.Split(array3d, 1);
int[,] blue = ArrayTools<int>.Split(array3d, 2);
Complex [,] cpxRed = ImageDataConverter.ToComplex(red);
Complex [,] cpxGreen = ImageDataConverter.ToComplex(green);
Complex [,] cpxBlue = ImageDataConverter.ToComplex(blue);
Complex[,] fftCpxRed = FourierTransform.ForwardFFT(cpxRed);
Complex[,] fftCpxGreen = FourierTransform.ForwardFFT(cpxGreen);
Complex[,] fftCpxBlue = FourierTransform.ForwardFFT(cpxBlue);
Complex[,] shiftedFftCpxRed = FourierShifter.ShiftFft(fftCpxRed);
Complex[,] shiftedFftCpxGreen = FourierShifter.ShiftFft(fftCpxGreen);
Complex[,] shiftedFftCpxBlue = FourierShifter.ShiftFft(fftCpxBlue);
int[,] fftRed = ImageDataConverter.ToIntegerMagnitude(shiftedFftCpxRed);
int[,] fftGreen = ImageDataConverter.ToIntegerMagnitude(shiftedFftCpxGreen);
int[,] fftBlue = ImageDataConverter.ToIntegerMagnitude(shiftedFftCpxBlue);
int [,,] dest = ArrayTools<int>.Merge(fftRed, fftGreen, fftBlue);
Bitmap mag = ImageDataConverter.ToBitmap3d(dest, PixelFormat.Format8bppIndexed);
Grayscale.SetPalette(mag);
pictureBox3.Image = mag;
}
Output
In the first case, the outcome is very good, and as expected. In the second case, the output is totally black.
One more test: if I take only one channel, again the output is cool:
... ... ...
Complex[,] shiftedFftCpxRed = FourierShifter.ShiftFft(fftCpxRed);
Complex[,] shiftedFftCpxGreen = FourierShifter.ShiftFft(fftCpxGreen);
Complex[,] shiftedFftCpxBlue = FourierShifter.ShiftFft(fftCpxBlue);
Bitmap mag = FourierPlot.FftMagnitudePlot(shiftedFftCpxRed, PixelFormat.Format8bppIndexed);
Bitmap phase = FourierPlot.FftPhasePlot(shiftedFftCpxRed, PixelFormat.Format8bppIndexed);
pictureBox2.Image = ImageDataConverter.ToBitmap2d(red, PixelFormat.Format8bppIndexed);
pictureBox3.Image = mag;
pictureBox4.Image = phase;
... ... ...
I think there is a problem in
public static int[,] ToIntegerMagnitude(Complex[,] image)
{
int Width = image.GetLength(0);
int Height = image.GetLength(1);
int[,] integer = new int[Width, Height];
for (int j = 0; j <= Height - 1; j++)
{
for (int i = 0; i <= Width - 1; i++)
{
integer[i, j] = ((int)image[i, j].Magnitude);
}
}
return integer;
}
This is only taking the magnitude part and hence losing data in the process.
Any suggestions?
.
Relevant Source Code
public static class FourierPlot
{
public static Bitmap FftMagnitudePlot(Complex[,] fftImage, PixelFormat pixelFormat)
{
int[,] FourierMagnitudeNormalizedInteger = FourierNormalizer.Normalize(fftImage, NormalizeType.Magnitude);
Bitmap color = ImageDataConverter.ToBitmap2d(FourierMagnitudeNormalizedInteger, pixelFormat);
Grayscale.SetPalette(color);
return color;
}
public static Bitmap FftPhasePlot(Complex[,] fftImage, PixelFormat pixelFormat)
{
int[,] FourierPhaseNormalizedInteger = FourierNormalizer.Normalize(fftImage, NormalizeType.Phase);
Bitmap color = ImageDataConverter.ToBitmap2d(FourierPhaseNormalizedInteger, pixelFormat);
Grayscale.SetPalette(color);
return color;
}
}
public partial class FourierNormalizer
{
public static int[,] Normalize(Complex[,] Output, NormalizeType normalizeType)
{
int Width = Output.GetLength(0);
int Height = Output.GetLength(1);
double[,] FourierDouble = new double[Width, Height];
double[,] FourierLogDouble = new double[Width, Height];
int[,] FourierNormalizedInteger = new int[Width, Height];
double max = 0;
if (normalizeType == NormalizeType.Magnitude)
{
for (int i = 0; i <= Width - 1; i++)
{
for (int j = 0; j <= Height - 1; j++)
{
FourierDouble[i, j] = Output[i, j].Magnitude;
FourierLogDouble[i, j] = (double)Math.Log(1 + FourierDouble[i, j]);
}
}
max = FourierLogDouble[0, 0];
}
else
{
for (int i = 0; i <= Width - 1; i++)
{
for (int j = 0; j <= Height - 1; j++)
{
FourierDouble[i, j] = Output[i, j].Phase;
FourierLogDouble[i, j] = (double)Math.Log(1 + Math.Abs(FourierDouble[i, j]));
}
}
FourierLogDouble[0, 0] = 0;
max = FourierLogDouble[1, 1];
}
for (int i = 0; i <= Width - 1; i++)
{
for (int j = 0; j <= Height - 1; j++)
{
if (FourierLogDouble[i, j] > max)
{
max = FourierLogDouble[i, j];
}
}
}
for (int i = 0; i <= Width - 1; i++)
{
for (int j = 0; j <= Height - 1; j++)
{
FourierLogDouble[i, j] = FourierLogDouble[i, j] / max;
}
}
if (normalizeType == NormalizeType.Magnitude)
{
for (int i = 0; i <= Width - 1; i++)
{
for (int j = 0; j <= Height - 1; j++)
{
FourierNormalizedInteger[i, j] = (int)(2000 * FourierLogDouble[i, j]);
}
}
}
else
{
for (int i = 0; i <= Width - 1; i++)
{
for (int j = 0; j <= Height - 1; j++)
{
FourierNormalizedInteger[i, j] = (int)(255 * FourierLogDouble[i, j]);
}
}
}
return FourierNormalizedInteger;
}
}
public static Bitmap ToBitmap3d(int[, ,] image, PixelFormat pixelFormat)
{
int Width = image.GetLength(1);
int Height = image.GetLength(2);
Bitmap bmp = new Bitmap(Width, Height, pixelFormat);
BitmapLocker locker = new BitmapLocker(bmp);
locker.Lock();
int [,] red = ArrayTools<int>.Split(image, 0);
int [,] green = ArrayTools<int>.Split(image, 1);
int [,] blue = ArrayTools<int>.Split(image, 2);
for (int y = 0; y < Height; y++)
{
for (int x = 0; x < Width; x++)
{
int r = red[x,y];
int g = green[x,y];
int b = blue[x,y];
Color clr = Color.FromArgb(r,g,b);
locker.SetPixel(x, y, clr);
}
}
locker.Unlock();
return bmp;
}
This comment solved my problem.
private void button2_Click(object sender, EventArgs e)
{
Bitmap source = (Bitmap)(pictureBox1.Image as Bitmap).Clone();
int[, ,] array3d = ImageDataConverter.ToInteger3d(source);
int[,] red = ArrayTools<int>.Split(array3d, 0);
int[,] green = ArrayTools<int>.Split(array3d, 1);
int[,] blue = ArrayTools<int>.Split(array3d, 2);
Complex[,] cpxRed = ImageDataConverter.ToComplex(red);
Complex[,] cpxGreen = ImageDataConverter.ToComplex(green);
Complex[,] cpxBlue = ImageDataConverter.ToComplex(blue);
Complex[,] fftCpxRed = FourierTransform.ForwardFFT(cpxRed);
Complex[,] fftCpxGreen = FourierTransform.ForwardFFT(cpxGreen);
Complex[,] fftCpxBlue = FourierTransform.ForwardFFT(cpxBlue);
Complex[,] shiftedFftCpxRed = FourierShifter.ShiftFft(fftCpxRed);
Complex[,] shiftedFftCpxGreen = FourierShifter.ShiftFft(fftCpxGreen);
Complex[,] shiftedFftCpxBlue = FourierShifter.ShiftFft(fftCpxBlue);
int[,] normRed = FourierNormalizer.Normalize(shiftedFftCpxRed, NormalizeType.Magnitude);
int[,] normGreen = FourierNormalizer.Normalize(shiftedFftCpxGreen, NormalizeType.Magnitude);
int[,] normBlue = FourierNormalizer.Normalize(shiftedFftCpxBlue, NormalizeType.Magnitude);
Bitmap mag = ImageDataConverter.ToBitmap3d(normRed, normGreen, normBlue, PixelFormat.Format8bppIndexed);
//Grayscale.SetPalette(mag);
//Bitmap mag = FourierPlot.FftMagnitudePlot(shiftedFftCpxRed, PixelFormat.Format8bppIndexed);
Bitmap phase = FourierPlot.FftPhasePlot(shiftedFftCpxRed, PixelFormat.Format8bppIndexed);
pictureBox2.Image = mag;
pictureBox3.Image = mag;
pictureBox4.Image = phase;
}

Crop image white space in C#

I have the request that crop image white space in C#, and I search some methods from the forum, but it could not satisfy my request.
There is the original image,
This is the result I expect,
Any help are appreciate.
You can try to get first image data(There is an image), and draw the data into a new image. Try this method. Hope it can help you.
private static Bitmap ImageTrim(Bitmap img)
{
//get image data
BitmapData bd= img.LockBits(new Rectangle(Point.Empty, img.Size),
ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
int[] rgbValues = new int[img.Height * img.Width];
Marshal.Copy(bd.Scan0, rgbValues, 0, rgbValues.Length);
img.UnlockBits(bd);
#region determine bounds
int left = bd.Width;
int top = bd.Height;
int right = 0;
int bottom = 0;
//determine top
for (int i = 0; i < rgbValues.Length; i++)
{
int color = rgbValues[i] & 0xffffff;
if (color != 0xffffff)
{
int r = i / bd.Width;
int c = i % bd.Width;
if (left > c)
{
left = c;
}
if (right < c)
{
right = c;
}
bottom = r;
top = r;
break;
}
}
//determine bottom
for (int i = rgbValues.Length - 1; i >= 0; i--)
{
int color = rgbValues[i] & 0xffffff;
if (color != 0xffffff)
{
int r = i / bd.Width;
int c = i % bd.Width;
if (left > c)
{
left = c;
}
if (right < c)
{
right = c;
}
bottom = r;
break;
}
}
if (bottom > top)
{
for (int r = top + 1; r < bottom; r++)
{
//determine left
for (int c = 0; c < left; c++)
{
int color = rgbValues[r * bd.Width + c] & 0xffffff;
if (color != 0xffffff)
{
if (left > c)
{
left = c;
break;
}
}
}
//determine right
for (int c = bd.Width - 1; c > right; c--)
{
int color = rgbValues[r * bd.Width + c] & 0xffffff;
if (color != 0xffffff)
{
if (right < c)
{
right = c;
break;
}
}
}
}
}
int width = right - left + 1;
int height = bottom - top + 1;
#endregion
//copy image data
int[] imgData = new int[width * height];
for (int r = top; r <= bottom; r++)
{
Array.Copy(rgbValues, r * bd.Width + left, imgData, (r - top) * width, width);
}
//create new image
Bitmap newImage = new Bitmap(width, height, PixelFormat.Format32bppArgb);
BitmapData nbd
= newImage.LockBits(new Rectangle(0, 0, width, height),
ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
Marshal.Copy(imgData, 0, nbd.Scan0, imgData.Length);
newImage.UnlockBits(nbd);
return newImage;
}
If your image only has 2 colors (white and black), you can iterate through your image and find the top left pixel set and the bottom right pixel set, then you can crop it:
(pseudo code, depends on what you use to get your image pixels)
int minX = int.MaxValue, maxX = 0, minY = int.MaxValue, maxY = 0;
for (x = 0; x < image.Width, x++)
{
for (y = 0; y < image.Height; y++)
{
if (image[x, y] == 1)
{
if (x < minX) minX = x;
else if (x > maxX) maxX = x;
if (y < minY) minY = y;
else if (y > maxY) maxY = y;
}
}
}
then you'll have the coordinates that will let you crop the image
I'm sure this could be optimized but that's the general idea

Drawing a border on an image

I'm currently trying to make a mask generator to generate polygons for images. Here's my code.
Bitmap bmp = new Bitmap(file);
int w = bmp.Width;
int h = bmp.Height;
List<Point> vertices = new List<Point>();
for (int y=0; y<h; y++)
{
bool rowbegin = false;
for (int x=0; x<w; x++)
{
Color c = bmp.GetPixel(x, y);
if (!rowbegin)
{
// Check for a non alpha color
if (c.A != Color.Transparent.A)
{
rowbegin = true;
// This is the first point in the row
vertices.Add(new Point(x, y));
}
} else {
// Check for an alpha color
if (c.A == Color.Transparent.A)
{
// The previous pixel is the last point in the row
vertices.Add(new Point(x-1, y));
rowbegin = false;
}
}
}
}
// Convert to an array of points
Point[] polygon = vertices.ToArray();
Graphics g = Graphics.FromImage(bmp);
g.DrawPolygon(Pens.LawnGreen, polygon);
g.Dispose();
But I'm getting wrong output.
The required.
What I want is also the gaps between the characters to be empty. Also why DrawPolygon is filling it?
Thanks.
Do you trying something like this:i hope my code help you:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
Bitmap bmp = new Bitmap(#"C:\Users\Ali\Desktop\1.png");
int w = bmp.Width;
int h = bmp.Height;
Lst_Data lastpointcolor = new Lst_Data() ;
for (int y = 0; y < h; y++)
{
for (int x = 0; x < w; x++)
{
Color c = bmp.GetPixel(x, y);
if (c.A != Color.Transparent.A)
{
if (lastpointcolor.color.A == Color.Transparent.A)
{
bmp.SetPixel(lastpointcolor.point.X, lastpointcolor.point.Y, Color.Red);
}
}
lastpointcolor = new Lst_Data() { point = new Point(x, y), color = bmp.GetPixel(x, y) };
}
}
for (int y = h-1; y > 0; y--)
{
for (int x = w-1; x > 0; x--)
{
Color c = bmp.GetPixel(x, y);
if (c.A != Color.Transparent.A)
{
if (lastpointcolor.color.A == Color.Transparent.A)
{
bmp.SetPixel(lastpointcolor.point.X, lastpointcolor.point.Y, Color.Red);
}
}
lastpointcolor = new Lst_Data() { point = new Point(x, y), color = bmp.GetPixel(x, y) };
}
}
pictureBox1.Image = bmp;
}
}
public struct Lst_Data
{
public Point point;
public Color color;
}
}
Edited:
And Another idea i have for you:D
Make a mask for original image with the same size and do this:
Bitmap orginal = new Bitmap(#"C:\Users\Ali\Desktop\orginal.png");
Bitmap mask = new Bitmap(#"C:\Users\Ali\Desktop\mask.png");
for (int i = 0; i < orginal.Width; i++)
{
for (int j = 0; j < orginal.Height; j++)
{
if (orginal.GetPixel(i, j).A == Color.Transparent.A)
{
mask.SetPixel(i, j, Color.Transparent);
}
}
}
Bitmap bitmap = new Bitmap(mask, mask.Height, mask.Height);
using (Graphics g = Graphics.FromImage(bitmap))
{
g.DrawImage(mask, 0, 0);
g.DrawImage(orginal,0,0);
}
pictureBox1.Image = bitmap;
Result:

Categories