I am trying to save my drawing from picturebox into bitmap and draw that bitmap into image. So far, nothing has appeared in the final image, but while debugging I can only say, that the original bitmap is not null and with/height are correct. However nothing appears after I draw it into image.
I save my drawing into bitmap like this:
GraphicsPath path = RoundedRectangle.Create(x, y, width, height, corners, RoundedRectangle.RectangleCorners.All);
g.FillPath(Brushes.LightGray, path);
g.SetClip(path);
using (Font f = new Font("Tahoma", 9, FontStyle.Bold))
g.DrawString(mtb_hotspotData.Text, f, Brushes.Black, textX, textY);
g.ResetClip();
bitmap = new Bitmap(width, height, g);
Then save it:
hs.bitmap = new Bitmap(bitmap);
And finally use it:
for (int i = 0; i < imageSequence.Count; i++) {
Graphics g = Graphics.FromImage(imageSequence[i]);
//g.CompositingMode = CompositingMode.SourceOver;
//hotspot.bitmap.MakeTransparent();
int x = hotspot.coordinates[i].X;
int y = hotspot.coordinates[i].Y;
g.DrawImage(hotspot.bitmap, new Point(x, y));
}
return imageSequence;
So far I was not able to find any problem in this solution, therefore I have no idea, where the malfunction is.
You seem to misunderstand the relation of a Bitmap and a Graphics object.
A Graphics object does not contain any graphics; it is a tool used to draw into a bitmap of some sort.
The Bitmap constructor you are using (public Bitmap(int width, int height, Graphics g)) does not really connect the Bitmap and the Graphics object. It only uses the dpi resolution from the Graphics.
You don't show how your Graphics is created. If you want to draw into a Bitmap (as opposed to a control's surface) the most direct way is this:
Bitmap bitmap = new Bitmap(width, height);
bitmap.SetResolution(dpiX, dpiY); // optional
using (Graphics G = Graphics.FromImage(bitmap ))
{
// do the drawing..
// insert all your drawing code here!
}
// now the Bitmap can be saved or cloned..
bitmap.Save(..);
hs.bitmap = new Bitmap(bitmap); // one way..
hs.bitmap = bitmap.Clone(); // ..or the other
// and finally disposed of (!!)
bitmap.Dispose();
Related
I'm trying to draw a part of a .png image but the code i found is not working. this is my code
//define canvas
canvas = pb.CreateGraphics();
sPicture = new Bitmap(pb.Width, pb.Height);
sCanvas = Graphics.FromImage(sPicture);
// Create a Bitmap object from a file.
Image image = Image.FromFile(#"");
// Clone a portion of the Bitmap object.
Rectangle cloneRect = new Rectangle(0, 0, 11, 6);
System.Drawing.Imaging.PixelFormat format =
image.PixelFormat;
Image cloneBitmap = image.Clone(cloneRect, format); //Error: No overload for method 'Clone' takes2 arguments
// Draw the cloned portion of the Bitmap object.
canvas.DrawImage(cloneBitmap, 0, 0);
This is for a sprite sheet and thanks.
You don't need to use Clone(), you can do this directly with Graphics.DrawImage(). It looks like you are trying to do this in WinForms. If, so handle OnPaint for the control you want to draw on. In the example below I'm drawing directly on the form.
private void Form1_Paint(object sender, PaintEventArgs e)
{
Graphics graphics = e.Graphics;
int width = 60;
int height = 60;
// Create a Bitmap object from a file.
Image sourceImage = Image.FromFile(#"C:\Users\Mike\Downloads\logo.png");
// Draw a portion of the source image.
Rectangle sourceRect = new Rectangle(0, 0, width, height);
graphics.DrawImage(sourceImage, 0, 0, sourceRect, GraphicsUnit.Pixel);
}
If you want to do this without WinForms, there is the extra step of creating the target Graphics instance.
int width = 60;
int height = 60;
// Create a Bitmap object from a file.
Image sourceImage = Image.FromFile(#"C:\Users\Mike\Downloads\logo.png");
// Create a drawing target
Bitmap bitmap = new Bitmap(width, height, sourceImage.PixelFormat);
Graphics graphics = Graphics.FromImage(bitmap);
// Draw a portion of the source image.
Rectangle sourceRect = new Rectangle(0, 0, width, height);
graphics.DrawImage(sourceImage, 0, 0, sourceRect, GraphicsUnit.Pixel);
// Save
bitmap.Save(#"C:\Users\Mike\Downloads\out.png");
I'm using C# and I would like to draw some polygons on a Form, then to save the graphics in a Bitmap.
Following this question answers I wrote a method in my Form class:
private void draw_pol()
{
Graphics d = this.CreateGraphics();
// drawing stuff
Bitmap bmp = new Bitmap(this.Width, this.Height, d);
bmp.Save("image.bmp");
}
In this way the Form displays correctly the graphics and the Bitmap file named "image.bmp" is created, but that file is a white image.
Why isn't the bmp file showing any image? What I'm doing wrong?
Thank you very much.
The graphics parameter you are passing to your bitmap is only used to specify the resolution of the bitmap. It does not in any way paint to the bitmap.
from MSDN:
The new Bitmap that this method creates takes its horizontal and vertical resolution from the DpiX and DpiY properties of g, respectively.
Instead, use Graphics.FromImage() to get a Graphics object you can use. Moreover, you should Dispose the Graphics object after painting. This is an ideal usage for the using statement.
Bitmap bmp = new Bitmap(this.Width, this.Height);
using (Graphics g = Graphics.FromImage(bmp))
{
//paint stuff
}
bmp.Save(yourFile);
If you also need to paint this to the form, you can easily just draw the bitmap you created:
Graphics g = this.CreateGraphics();
g.DrawImage(bmp, 0, 0);
A Graphics instance only operates on one Bitmap. It's either the one you want to save, or the one on your form.
You can for example do this to render the drawn bitmap on your form and save it afterwards:
private void DrawOnBitmap()
{
using (var bitmap = new Bitmap(this.Width, this.Height))
{
using (var bitmapGraphics = Graphics.FromImage(bitmap))
{
// Draw on the bitmap
var pen = new Pen(Color.Red);
var rect = new Rectangle(20, 20, 100, 100);
bitmapGraphics.DrawRectangle(pen, rect);
// Display the bitmap on the form
using (var formGraphics = this.CreateGraphics())
{
formGraphics.DrawImage(bitmap, new Point(0, 0));
}
// Save the bitmap
bitmap.Save("image.bmp");
}
}
}
you need a graphics object that represents the bitmap,so that you can draw on image.do lke this:
create the bitmap object
create the graphics object using Graphics.FromImage method
pass bitmap object as argument to graphics object
Bitmap bmp = new Bitmap(this.Width, this.Height, d);
bmp.Save("image.bmp");//for your need
Graphics d=Graphics.FromImage(bmp);
I am trying to do a simple crop of an image, but for some reason it is not respecting my starting x,y location. It is always starting the crop at 0,0. The following is what I am doing:
Bitmap original = new Bitmap(pictureBox1.Image);
int x = Convert.ToInt32(txtX.Text);
int y = Convert.ToInt32(txtY.Text);
int dX = Convert.ToInt32(txtDeltaX.Text);
int dY = Convert.ToInt32(txtDeltaY.Text);
Point loc = new Point(x, y);
Size cropSize = new Size(dX, dY);
Rectangle cropArea = new Rectangle(loc, cropSize);
Bitmap bmpCrop = CropImage(original, cropArea);
pictureBox1.Image = bmpCrop;
The cropping method:
public Bitmap CropImage(Bitmap source, Rectangle section)
{
// An empty bitmap which will hold the cropped image
Bitmap bmp = new Bitmap(section.Width, section.Height);
Graphics g = Graphics.FromImage(bmp);
// Draw the given area (section) of the source image
// at location 0,0 on the empty bitmap (bmp)
g.DrawImage(source, 0, 0, section, GraphicsUnit.Pixel);
return bmp;
}
This should be very simple, but for some reason its not working. Its cropping it, just at 0,0.
Thanks!
You should try to use
g.DrawImage(source, section);
Anyway this function works:
public Bitmap CropBitmap(Bitmap bitmap,
int cropX, int cropY,
int cropWidth, int cropHeight)
{
Rectangle rect = new Rectangle(cropX, cropY, cropWidth, cropHeight);
Bitmap cropped = bitmap.Clone(rect, bitmap.PixelFormat);
return cropped;
}
You might want to use Graphics.DrawImageUnscaledAndClipped
Try to use, something like this :
g.DrawImage(source, x, y, section, GraphicsUnit.Pixel);
I have following problem. I want to make some graphics in c# windows form.
I want to read bitmap to my program and after it write some text on this bitmap. In the end I want this picture load to pictureBox. And it's my question. How can I do it?
example, how must it work:
Bitmap a = new Bitmap(#"path\picture.bmp");
a.makeTransparent();
// ? a.writeText("some text", positionX, positionY);
pictuteBox1.Image = a;
Is it possible do to?
Bitmap bmp = new Bitmap("filename.bmp");
RectangleF rectf = new RectangleF(70, 90, 90, 50);
Graphics g = Graphics.FromImage(bmp);
g.SmoothingMode = SmoothingMode.AntiAlias;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
g.DrawString("yourText", new Font("Tahoma",8), Brushes.Black, rectf);
g.Flush();
image.Image=bmp;
Very old question, but just had to build this for an app today and found the settings shown in other answers do not result in a clean image (possibly as new options were added in later .Net versions).
Assuming you want the text in the centre of the bitmap, you can do this:
// Load the original image
Bitmap bmp = new Bitmap("filename.bmp");
// Create a rectangle for the entire bitmap
RectangleF rectf = new RectangleF(0, 0, bmp.Width, bmp.Height);
// Create graphic object that will draw onto the bitmap
Graphics g = Graphics.FromImage(bmp);
// ------------------------------------------
// Ensure the best possible quality rendering
// ------------------------------------------
// The smoothing mode specifies whether lines, curves, and the edges of filled areas use smoothing (also called antialiasing).
// One exception is that path gradient brushes do not obey the smoothing mode.
// Areas filled using a PathGradientBrush are rendered the same way (aliased) regardless of the SmoothingMode property.
g.SmoothingMode = SmoothingMode.AntiAlias;
// The interpolation mode determines how intermediate values between two endpoints are calculated.
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
// Use this property to specify either higher quality, slower rendering, or lower quality, faster rendering of the contents of this Graphics object.
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
// This one is important
g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
// Create string formatting options (used for alignment)
StringFormat format = new StringFormat()
{
Alignment = StringAlignment.Center,
LineAlignment = StringAlignment.Center
};
// Draw the text onto the image
g.DrawString("yourText", new Font("Tahoma",8), Brushes.Black, rectf, format);
// Flush all graphics changes to the bitmap
g.Flush();
// Now save or use the bitmap
image.Image = bmp;
References
https://msdn.microsoft.com/en-us/library/system.drawing.graphics.smoothingmode(v=vs.110).aspx
https://msdn.microsoft.com/en-us/library/system.drawing.drawing2d.interpolationmode(v=vs.110).aspx
https://msdn.microsoft.com/en-us/library/system.drawing.graphics.pixeloffsetmode(v=vs.110).aspx
https://msdn.microsoft.com/en-us/library/system.drawing.graphics.textrenderinghint(v=vs.110).aspx
https://msdn.microsoft.com/en-us/library/system.drawing.stringformat(v=vs.110).aspx
https://msdn.microsoft.com/en-us/library/21kdfbzs(v=vs.110).aspx
You need to use the Graphics class in order to write on the bitmap.
Specifically, one of the DrawString methods.
Bitmap a = new Bitmap(#"path\picture.bmp");
using(Graphics g = Graphics.FromImage(a))
{
g.DrawString(....); // requires font, brush etc
}
pictuteBox1.Image = a;
var bmp = new Bitmap(#"path\picture.bmp");
using( Graphics g = Graphics.FromImage( bmp ) )
{
g.DrawString( ... );
}
picturebox1.Image = bmp;
If you want wrap your text, then you should draw your text in a rectangle:
RectangleF rectF1 = new RectangleF(30, 10, 100, 122);
e.Graphics.DrawString(text1, font1, Brushes.Blue, rectF1);
See: https://msdn.microsoft.com/en-us/library/baw6k39s(v=vs.110).aspx
How to convert Image to Graphic?
You can't convert a Graphics object into an image, as the Graphics object doesn't contain any image data.
The Graphics object is just a tool used to draw on a canvas. That canvas is typically a Bitmap object or the screen.
If the Graphics object is used for drawing on a Bitmap, then you already have the image. If the Graphics object is used for drawing on the screen, you would have to make a screen shot to get an image of the canvas.
If the Graphics object was created from a window control, you could use the control's DrawToBitmap method to render the control on an image instead of on the screen.
You need an Image in order to draw your Graphics on, so you probably already have the image:
Graphics g = Graphics.FromImage(image);
As Darin states, you probably already have the image. If you don't, you can create a new one and draw to that one
Image bmp = new Bitmap(width, height);
using (Graphics g = Graphics.FromImage(bmp)) {
// draw in bmp using g
}
bmp.Save(filename);
Save saves the image to a file on your hard drive.
If you're drawing directly on a Control's graphics, you can create a new Bitmap with the same dimensions as the control and then call Control.DrawToBitmap(). However, the better way to go is usually to start with a Bitmap, draw to its graphics (as suggested by Darin), and then paint the bitmap onto the Control.
The best method to turn graphics into a bitmap is to get rid of the 'using' stuff:
Bitmap b1 = new Bitmap(Screen.PrimaryScreen.Bounds.Width,Screen.PrimaryScreen.Bounds.Height);
Graphics g = Graphics.FromImage(b1);
g.CopyFromScreen(0, 0, Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y, new Size(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height));
b1.Save("screen.bmp");
I discovered this while figuring out how to turn graphics into a bitmap, and it works like a charm.
I have some examples on how to use this:
//1. Take a screenshot
Bitmap b1 = new Bitmap(Screen.PrimaryScreen.Bounds.Width,Screen.PrimaryScreen.Bounds.Height);
Graphics g = Graphics.FromImage(b1);
g.CopyFromScreen(0, 0, Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y, new Size(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height));
b1.Save("screen.bmp");
//2. Create pixels (stars) at a custom resolution, changing constantly like stars
private void timer1_Tick(object sender, EventArgs e)
{
/*
* Steps to use this code:
* 1. Create new form
* 2. Set form properties to match the settings below:
* AutoSize = true
* AutoSizeMode = GrowAndShrink
* MaximizeBox = false
* MinimizeBox = false
* ShowIcon = false;
*
* 3. Create picture box with these properties:
* Dock = Fill
*
*/
//<Definitions>
Size imageSize = new Size(400, 400);
int minimumStars = 600;
int maximumStars = 800;
//</Definitions>
Random r = new Random();
Bitmap b1 = new Bitmap(imageSize.Width, imageSize.Height);
Graphics g = Graphics.FromImage(b1);
g.Clear(Color.Black);
for (int i = 0; i <r.Next(minimumStars, maximumStars); i++)
{
int x = r.Next(1, imageSize.Width);
int y = r.Next(1, imageSize.Height);
b1.SetPixel(x, y, Color.WhiteSmoke);
}
pictureBox1.Image = b1;
}
With this code, you can use all the commands for the Graphics Class, and copy them to a bitmap, therefore allowing you to save anything designed with the graphics class.
You may use this to your advantage.