Hello How to draw a circle with the bitmap. That is, I need to get the image of the circle, using it to draw something.
Use ColorTranslator.FromHtml for this purpose.
This will give you the corresponding System.Drawing.Color:
using (Bitmap btm = new Bitmap(25, 30))
{
using (Graphics grf = Graphics.FromImage(btm))
{
using (Brush brsh = new SolidBrush(ColorTranslator.FromHtml("#ff00ffff")))
{
grf.FillEllipse(brsh, 0, 0, 19, 19);
}
}
}
Or Refer Code:
Bitmap bmp = new Bitmap(pictureBox1.Width, pictureBox1.Height);
Graphics g = Graphics.FromImage(bmp);
Pen blackPen = new Pen(Color.Black);
int x = pictureBox1.Width/4;
int y = pictureBox1.Height/4;
int width = pictureBox1.Width / 2;
int height = pictureBox1.Height / 2;
int diameter = Math.Min(width, height);
g.DrawEllipse(blackPen, x, y, diameter, diameter);
pictureBox1.Image = bmp;
If the PictureBox already contains a bitmap, replace the first and second lines with:
Graphics g = Graphics.FromImage(pictureBox1.Image);
Referance Link:
http://www.c-sharpcorner.com/Forums/Thread/30986/
Hope Its Helpful.
Bitmap b = new Bitmap(261, 266);// height & width of picturebox
int xo = 50, yo = 50;// center of circle
double r, rr;
r = 20;
rr = Math.Pow(r, 2);
for (int i = xo - (int)r; i <= xo + r; i++)
for (int j = yo - (int)r; j <= yo + r; j++)
if (Math.Abs(Math.Pow(i - xo, 2) + Math.Pow(j - yo, 2) - rr) <= r)
b.SetPixel(i, j, Color.Black);
pictureBox1.Image = b;
Related
public void ReadSetPixels(Bitmap image1, Bitmap image2)
{
int tolerance = 64;
for (int x = 0; x < image1.Width; x++)
{
for (int y = 0; y < image1.Height; y++)
{
Color pixelColor = image1.GetPixel(x, y);
// just average R, G, and B values to get gray. Then invert by 255.
int invertedGrayValue = 255 - (int)((pixelColor.R + pixelColor.G + pixelColor.B) / 3);
if (invertedGrayValue > tolerance) { invertedGrayValue = 255; }
// this keeps the original pixel color but sets the alpha value
image1.SetPixel(x, y, Color.FromArgb(invertedGrayValue, pixelColor));
}
}
// composite image1 on top of image2
using (Graphics g = Graphics.FromImage(image2))
{
g.CompositingMode = CompositingMode.SourceOver;
g.CompositingQuality = CompositingQuality.HighQuality;
g.DrawImage(image1, new Point(0, 0));
}
image2.Save(#"d:\mynewbmp.bmp");
image1.Dispose();
image2.Dispose();
}
using it
RadarPixels rp = new RadarPixels();
rp.ReadSetPixels(new Bitmap(#"d:\myimage1.png"),
new Bitmap(#"d:\clean_radar_image123.bmp"));
I looked on the example in the docs at : https://learn.microsoft.com/en-us/dotnet/api/system.drawing.bitmap.lockbits?redirectedfrom=MSDN&view=dotnet-plat-ext-7.0#overloads
but not sure how to implement it with my method.
UPDATE :
This is what I have tried so far :
created a new method :
public unsafe void Test(Bitmap Image1, Bitmap Image2)
{
int tolerance = 64;
int width = Image1.Width;
int height = Image1.Height;
//TODO determine bytes per pixel
int bytesPerPixel = 4; // we assume that image is Format32bppArgb
int maxPointerLenght = width * height * bytesPerPixel;
int stride = width * bytesPerPixel;
byte R, G, B, A;
BitmapData bData = Image1.LockBits(
new System.Drawing.Rectangle(0, 0, Image1.Width, Image1.Height),
ImageLockMode.ReadWrite, Image1.PixelFormat);
byte* scan0 = (byte*)bData.Scan0.ToPointer();
IntPtr ptr = bData.Scan0;
int bytes = Math.Abs(bData.Stride) * Image1.Height;
byte[] rgbValues = new byte[bytes];
System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);
for (int i = 0; i < maxPointerLenght; i += 4)
{
B = scan0[i + 0];
G = scan0[i + 1];
R = scan0[i + 2];
A = scan0[i + 3];
int invertedGrayValue = 255 - (int)((R + G + B) / 3);
if (invertedGrayValue > tolerance) { invertedGrayValue = 255; }
rgbValues[i] = (byte)invertedGrayValue;
}
Image1.UnlockBits(bData);
using (Graphics g = Graphics.FromImage(Image2))
{
g.CompositingMode = CompositingMode.SourceOver;
g.CompositingQuality = CompositingQuality.HighQuality;
g.DrawImage(Image1, new Point(0, 0));
}
Image2.Save(#"d:\mynewbmp.bmp");
Image2.Dispose();
}
but the result image is not as before with the method at the top with the get/set pixel. why it's not making the overlay like the method before ?
the result image :
I found a library to work with QR Code in C#.
https://github.com/codebude/QRCoder/
There is a sample to add our logo in QR Code generated image.
I want add my gif logo instead of png logo.
The gif is motion.
My question is: How I can add gif to Bitmap or something like that and save it?
In that library, they used Graphics.DrawImage to set icon in center of the generated QR Code Image.
The code they used is:
public Image GetGraphic(
int pixelsPerModule,
Color darkColor,
Color lightColor,
Bitmap icon = null,
int iconSizePercent = 15,
int iconBorderWidth = 0,
bool drawQuietZones = true,
Color? iconBackgroundColor = null)
{
int num1 = (QrCodeData.ModuleMatrix.Count - (drawQuietZones ? 0 : 8)) * pixelsPerModule;
int num2 = drawQuietZones ? 0 : 4 * pixelsPerModule;
Bitmap graphic = new Bitmap(num1, num1, PixelFormat.Format32bppArgb);
using (Graphics graphics = Graphics.FromImage(graphic))
{
using (SolidBrush solidBrush1 = new SolidBrush(lightColor))
{
using (SolidBrush solidBrush2 = new SolidBrush(darkColor))
{
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.Clear(lightColor);
bool flag = icon != null && iconSizePercent > 0 && iconSizePercent <= 100;
for (int index1 = 0; index1 < num1 + num2; index1 += pixelsPerModule)
{
for (int index2 = 0; index2 < num1 + num2; index2 += pixelsPerModule)
{
SolidBrush solidBrush3 = QrCodeData.ModuleMatrix[(index2 + pixelsPerModule) / pixelsPerModule - 1]
[(index1 + pixelsPerModule) / pixelsPerModule - 1] ? solidBrush2 : solidBrush1;
graphics.FillRectangle(solidBrush3, new Rectangle(index1 - num2,
index2 - num2, pixelsPerModule, pixelsPerModule));
}
}
if (flag)
{
float width = (iconSizePercent * graphic.Width) / 100f;
float height = flag ? width * icon.Height / icon.Width : 0.0f;
float x = (float)((graphic.Width - (double)width) / 2.0);
float y = (float)((graphic.Height - (double)height) / 2.0);
RectangleF rect = new RectangleF(x - iconBorderWidth, y - iconBorderWidth,
width + (iconBorderWidth * 2), height + (iconBorderWidth * 2));
RectangleF destRect = new RectangleF(x, y, width, height);
SolidBrush solidBrush4 = iconBackgroundColor.HasValue ? new SolidBrush(iconBackgroundColor.Value) : solidBrush1;
if (iconBorderWidth > 0)
{
using (GraphicsPath roundedRectanglePath = CreateRoundedRectanglePath(rect, iconBorderWidth * 2))
graphics.FillPath(solidBrush4, roundedRectanglePath);
}
graphics.DrawImage(icon, destRect, new RectangleF(0.0f, 0.0f, icon.Width, icon.Height), GraphicsUnit.Pixel);
}
graphics.Save();
}
}
}
return graphic;
}
I have an Bitmap with various color patterns and I need to find the bounding rectangles of one given color (For example: Red) within the Bitmap. I found some code to process images but unable to figure out how to achieve this.
Any help would be highly appreciated.
This is my code.
private void LockUnlockBitsExample(PaintEventArgs e)
{
// Create a new bitmap.
Bitmap bmp = new Bitmap("c:\\fakePhoto.jpg");
// Lock the bitmap's bits.
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
System.Drawing.Imaging.BitmapData bmpData =
bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite,
bmp.PixelFormat);
// Get the address of the first line.
IntPtr ptr = bmpData.Scan0;
// Declare an array to hold the bytes of the bitmap.
int bytes = Math.Abs(bmpData.Stride) * bmp.Height;
byte[] rgbValues = new byte[bytes];
// Copy the RGB values into the array.
System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);
// Set every third value to 255. A 24bpp bitmap will look red.
for (int counter = 2; counter < rgbValues.Length; counter += 3)
rgbValues[counter] = 255;
// Copy the RGB values back to the bitmap
System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes);
// Unlock the bits.
bmp.UnlockBits(bmpData);
// Draw the modified image.
e.Graphics.DrawImage(bmp, 0, 150);
}
Edit: The Bitmap contains solid color shapes, multiple shapes with same color can appear. I need to find the bounding rectangle of each shape.
Just like the paint fills color with bucket tool, I need the bounding rectangle of the filled area.
I can provide x, y coordinates of point on Bitmap to find the bound rectangle of color.
You would do this just like any other code where you want to find the min or max value in a list. With the difference that you want to find both min and max in both X and Y dimensions. Ex:
public static Rectangle GetBounds(this Bitmap bmp, Color color)
{
int minX = int.MaxValue;
int minY = int.MaxValue;
int maxX = int.MinValue;
int maxY = int.MinValue;
for (int y = 0; y < bmp.Height; y++)
{
for (int x = 0; x < bmp.Width; x++)
{
var c = bmp.GetPixel(x, y);
if (color == c)
{
if (x < minX) minX = x;
if (x > maxX) maxX = x;
if (y < minY) minY = y;
if (y > maxY) maxY = y;
}
}
}
var width = maxX - minX;
var height = maxY - minY;
if (width <= 0 || height <= 0)
{
// Handle case where no color was found, or if color is a single row/column
return default;
}
return new Rectangle(minX, minY, width, height);
}
There are plenty of resources on how to use LockBits/pointers. So converting the code to use this instead of GetPixel is left as an exercise.
If you are not concerned with the performance, and an exact color match is enough for you, then just scan the bitmap:
var l = bmp.Width; var t = bmp.Height; var r = 0; var b = 0;
for (var i = 0; i<rgbValues.Length, i++)
{
if(rgbValues[i] == 255) // rgb representation of red;
{
l = Math.Min(l, i % bmpData.Stride); r = Math.Max(r, i % bmpData.Stride);
t = Math.Min(l, i / bmpData.Stride); b = Math.Max(b, i / bmpData.Stride);
}
}
if(l>=r) // at least one point is found
return new Rectangle(l, t, r-l+1, b-t+1);
else
return new Rectangle(0, 0, 0, 0); // nothing found
You can search for the first point of each shape that fills a different area on the Bitmap, read a single horizontal row to get the points of the given color, then loop vertically within the horizontal range to get the adjacent points.
Once you get all the points of each, you can calculate the bounding rectangle through the first and last points.
public static IEnumerable<Rectangle> GetColorRectangles(Bitmap src, Color color)
{
var rects = new List<Rectangle>();
var points = new List<Point>();
var srcRec = new Rectangle(0, 0, src.Width, src.Height);
var srcData = src.LockBits(srcRec, ImageLockMode.ReadOnly, src.PixelFormat);
var srcBuff = new byte[srcData.Stride * srcData.Height];
var pixSize = Image.GetPixelFormatSize(src.PixelFormat) / 8;
Marshal.Copy(srcData.Scan0, srcBuff, 0, srcBuff.Length);
src.UnlockBits(srcData);
Rectangle GetColorRectangle()
{
var curX = points.First().X;
var curY = points.First().Y + 1;
var maxX = points.Max(p => p.X);
for(var y = curY; y < src.Height; y++)
for(var x = curX; x <= maxX; x++)
{
var pos = (y * srcData.Stride) + (x * pixSize);
var blue = srcBuff[pos];
var green = srcBuff[pos + 1];
var red = srcBuff[pos + 2];
if (Color.FromArgb(red, green, blue).ToArgb().Equals(color.ToArgb()))
points.Add(new Point(x, y));
else
break;
}
var p1 = points.First();
var p2 = points.Last();
return new Rectangle(p1.X, p1.Y, p2.X - p1.X, p2.Y - p1.Y);
}
for (var y = 0; y < src.Height; y++)
{
for (var x = 0; x < src.Width; x++)
{
var pos = (y * srcData.Stride) + (x * pixSize);
var blue = srcBuff[pos];
var green = srcBuff[pos + 1];
var red = srcBuff[pos + 2];
if (Color.FromArgb(red, green, blue).ToArgb().Equals(color.ToArgb()))
{
var p = new Point(x, y);
if (!rects.Any(r => new Rectangle(r.X - 2, r.Y - 2,
r.Width + 4, r.Height + 4).Contains(p)))
points.Add(p);
}
}
if (points.Any())
{
var rect = GetColorRectangle();
rects.Add(rect);
points.Clear();
}
}
return rects;
}
Demo
private IEnumerable<Rectangle> shapesRects = Enumerable.Empty<Rectangle>();
private void pictureBox1_MouseClick(object sender, MouseEventArgs e)
{
var sx = 1f * pictureBox1.Width / pictureBox1.ClientSize.Width;
var sy = 1f * pictureBox1.Height / pictureBox1.ClientSize.Height;
var p = Point.Round(new PointF(e.X * sx, e.Y * sy));
var c = (pictureBox1.Image as Bitmap).GetPixel(p.X, p.Y);
shapesRects = GetColorRectangles(pictureBox1.Image as Bitmap, c);
pictureBox1.Invalidate();
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
if (shapesRects.Any())
using (var pen = new Pen(Color.Black, 2))
e.Graphics.DrawRectangles(pen, shapesRects.ToArray());
}
HI guys i have problem in this code i want to display my photo cut in 9 pieces and display it in 9 pictureboxs to make puzzle game wish anyone could help .
Thanks In Advance
var knight = new Image[9];
var H = Image.FromFile("1425435_630471227004342_2061223205_o.jpg");
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
var index = i * 3 + j;
knight[index] = new Bitmap(200,200);
var m = Graphics.FromImage(knight[index]);
Rectangle r = new Rectangle( i * (knight[index].Width / 3),
j*(knight[index].Height / 3),
knight[index].Width / 3,
knight[index].Height / 3);
m.DrawImage(H, r, r, GraphicsUnit.Pixel);
m.Dispose();
}
}
pictureBox1.Image = knight[0];
pictureBox2.Image = knight[1];
pictureBox3.Image = knight[2];
pictureBox4.Image = knight[3];
pictureBox5.Image = knight[4];
pictureBox6.Image = knight[5];
pictureBox7.Image = knight[6];
pictureBox8.Image = knight[7];
pictureBox9.Image = knight[8];
Change this
Rectangle r = new Rectangle( i * (knight[index].Width / 3),
j*(knight[index].Height / 3),
knight[index].Width / 3,
knight[index].Height / 3);
m.DrawImage(H, r, r, GraphicsUnit.Pixel);
to this:
out of the loop:
// old size of the parts:
int ow = H.Width / 3;
int oh = H.Height / 3;
// new size of the parts:
int nw = knight[0].Width;
int nh = knight[0].Height;
// inner loop:
Rectangle rDest = new Rectangle(0, 0, nw, nh);
Rectangle rSource = new Rectangle(i * ow, j * oh, ow, oh);
m.DrawImage(H, rDest, rSource , GraphicsUnit.Pixel);
Note: If the proportions of the Original Image and the 9 PBs is different there will be a distortion:
You are not using a separate source rectangle (as TaW mentioned). Also you are not fully occupying the picturebox.
Try this code:
knight[index] = new Bitmap(640, 360); //enter the size of the original image
Rectangle src = new Rectangle(i * (knight[index].Width / 3), j * (knight[index].Height / 3), knight[index].Width / 3, knight[index].Height / 3);
Rectangle des = new Rectangle(0, 0, knight[index].Width, knight[index].Height);
m.DrawImage(H, des, src, GraphicsUnit.Pixel);
I have a bitmap object (or even any other image) and I'm drawing some lines on this bitmap to create a polygon.
after the drawing I need to clone/copy/cut the selection (based on the lines) area.
I cant use the bitmap.clone method becuase its working only with rectangle.
I need some kind of a clone implementation based on Point[] or GraphicsPath...
Please help new to GDI/Graphics... :)
Update
I tried doing something like this:
Graphics g = pbImage.CreateGraphics();
g.Clip = new Region(path);
Image img = null;
g.DrawImage(img, new Point(0, 0));
Can you provide a code example? I'm new for the GDI+ and I cant implement what you suggested.
I dont understand the:
another buffer/temp graphics object
An example of Barndon Moretzs solution.
int x = 0;
int y = 0;
int width = 0;
int height = 0;
Point[] pesource = null;
GraphicsPath gpdest = new GraphicsPath();
source = new Bitmap(Image.FromFile(#"IMAGEPATH"));
//Your polygon
pesource = new Point[]
{
new Point(10,100),
new Point(30,150),
new Point(40,170),
new Point(60,120),
new Point(70,250),
new Point(40,300),
new Point(10,250),
new Point(30,150)
};
//Determine the destination size/position
x = source.Width;
y = source.Height;
foreach (var p in pesource)
{
if (p.X < x)
x = p.X;
if (p.X > width)
width = p.X;
if (p.Y < y)
y = p.Y;
if (p.Y > height)
height = p.Y;
}
height = height - y;
width = width - x;
gpdest.AddPolygon(pesource);
Matrix m = new Matrix(1, 0, 0, 1, -x, -y);
gpdest.Transform(m);
//Create the Bitmap
clipped = new Bitmap(width, height);
//Draw on the Bitmap
using (Graphics g = Graphics.FromImage(clipped))
{
GraphicsPath gpgdi = new GraphicsPath();
g.SetClip(gpdest);
g.DrawImage(source, -x, -y);
}
You can use the Graphics.Clip to specify a custom clipping region (from a GraphicsPath) created from your "source" bitmap/image, then redraw it on another buffer/temp graphics object which should give you the desired result.
This isn't the most efficient solution, but it should at least get you going in the right direction.