Could anyone give me a pointer please?
I've almost finished a project I'm working on but have one last issue to resolve.
I have an image on a form that I apply a colour gradient to. However, when I grab this to create a bitmap
(this.DrawToBitmap(BackGroundBmp, BackGroundRect);)
I do not get the gradient. So, I've applied the gradient to the bitmap directly. However, this is noticeably darker than the form image with the gradient over it. Any idea?
Bitmap BackGroundBmp = new Bitmap(this.Width, this.Height);
Rectangle BackGroundRect = new Rectangle(0, 0,this.Width, this.Height);
this.DrawToBitmap(BackGroundBmp, BackGroundRect);
Graphics g = Graphics.FromImage(BackGroundBmp);
g.FillRectangle(RenderBGGradient, RenderBGGradBrush);
Thanks in advance.
I'm not going to pretend that I understand why but even though the image on the form had a gradient on it, but was not visible in the bitmap that was rendered (using -> this.DrawToBitmap), it must have some how applied this gradient (I'm using alpha blend in the gradient). It was doubling up on the gradient that was applied to the form and the bitmap...... which made it darker. I applied the gradient straight to the bitmap......problem solved. The gradient wasn't visible in the rendered bitmap so, therefore, if I'd not been so sloppy and removed the code that applied the gradient to the form, I would have solved this sooner.
Related
I am creating an Circle on a bitmap but want to have a hole in it. After serching for half an hour I only found ways to crop an image to a circle. The hard thing is, that the hole in the middle should be transparent as the rest of the Image.
This is the base image and the yellow circle represents the transparent area that should be added.
Thanks for any kind of help.
The start is simple: Create a transparent bitmap by doing a g.Clear(Color.Transparent) and then draw/fill a circle in a color.
The next step is a bit trickier: You next want to paint the hole with transparency.
To do so you need to switch the Graphics object to the right CompositingMode; default is SourceOver but you want SourceCopy. The former overlays the alpha values creating mixed colors. The latter will do what we want: Draw the hole by copying the drawn colors including alpha right over the old ones..
Here is an example:
Bitmap bmp = new Bitmap(500, 500);
using (Graphics g = Graphics.FromImage(bmp))
{
g.Clear(Color.Transparent);
//g.SmoothingMode = SmoothingMode.AntiAlias;
g.CompositingMode = CompositingMode.SourceCopy;
g.FillEllipse(Brushes.DarkGreen, 100, 100, 300, 300);
g.FillEllipse(Brushes.Transparent, 200, 200, 100, 100);
}
pictureBox1.Image = bmp;
This is what is looks like in a PictureBox with a BackgroundImage:
A few notes:
You can also use a semi-transparent brush to create a 'tinted' hole; do not use anti-aliasing for this though, as it would introduce colored fringes.
We used simple circles here but with a GraphicsPath you can create and fill shapes of almost any shape and complexity..
And using a GraphicsPath would also have been an alternative to filling with transparency: By first adding the large and then the smaller, inner ellipse the path would have been created with a hole and filling it would have had the very same result! But I found the solution above more instructive..
Final note: As clarkitect noted, to save, do use a format that supports transparency. Png is always recommended..
I'm actually trying to add some text to an image in C# with
System.Windows.Forms.TextRenderer.DrawText(Graphics, string, Rectangle, Color, TextFormaFlags)
I prepare my image (which is a png) by loading it in memory, with something similar to
Image image = ImageCache.Get(...);
bitmap = new Bitmap(image);
graphic = Graphics.FromImage(bitmap);
I then draw my text with the above command. The problem is that whatever I use for the color, even something like
System.Drawing.Color.FromArgb(0,255,255,255)
the transparency is not drawn. I tried many settings for
graphics.TextRenderingHint
and different combinations of fonts, transparency level, etc. Is there something I don't understand here? Any hint is appreciated.
Thank you.
As mentionned in the comments : if you try to draw transparent text with
System.Windows.Forms.TextRenderer.DrawText
because you look for the advantages brought by GDI in C#, you just can't. Use
System.Drawing.Graphics.DrawString
instead, even if the result for the word-wrapping is slightly inferior with GDI+.
I have been working on creating a program similar to MS Paint. I have several of the features it has down but the one which is currently giving me trouble is the rectangular selection tool. My program currently draws everything on the panel and saves it all in an ArrayList so each shape can be redrawn in Paint().
Like MS paint I would like the user to be able to select a section of the drawing on the panel and either copy it, move it, re-size it, or even delete it. I was thinking about having the user draw a rectangle & saving the information for it. Then taking that information for the rectangle, passing them to create a new Bitmap. I would then paint a new rectangle in the background color to give the appearance that the selected area was "removed" when the selected portion is moved. It sounded okay until I realized that I couldn't use the Graphics.FromImage() on the PaintEventArgs variable passed to Paint() which made my idea useless. Not sure if that makes sense so my apologies if it's a confusing mess.
I've been searching the internet for some assistance and I haven't found much to help so either this is very easy to do, very difficult, or "rectangle selection tool" is not the proper term. Any help or pointers would be greatly appreciated!!! Thank you for your time! :)
I understand that you actually have the Rectangle and now would like to copy an area from your painted Panel.
This is possible, assuming you have, as you should, placed all the painting in the Paint event of the Panel.
Then you can, use DrawToBitmap to ask the Panel to draw itself onto a new Bitmap; from there you can DrawImage the Rectangle onto your Panel.
Note: For this to integrate with your list of 'Paint-Actions' you will have to either now store that Bitmap or store the Rectangle and redo the whole operation.
using (Graphics G = panelCanvas.CreateGraphics() )
{
Rectangle R0 = new Rectangle(22,22,55,55); // your Rectangle!
using (Bitmap bmp = new
Bitmap(panelCanvas.ClientSize.Width, panelCanvas.ClientSize.Height))
{ panelCanvas.DrawToBitmap(bmp, panelCanvas.ClientRectangle);
G.DrawImage(bmp, 111f, 111f, R0, GraphicsUnit.Pixel);
}
}
Aside: Please do replace the ArrayList, which is depracated by the new List<T>, e.g. a List<PaintAction> or whatever name your class has!
If you simply want to extract a rectanglular area from the Panel Control you can use thsi function:
public Bitmap getAreaFrom(Control ctl, Rectangle area)
{
Bitmap bmp2 = new Bitmap(area.Width, area.Height);
using (Graphics G = ctl.CreateGraphics())
using (Bitmap bmp = new Bitmap(ctl.ClientSize.Width, ctl.ClientSize.Height))
{
ctl.DrawToBitmap(bmp, ctl.ClientRectangle);
using (Graphics G2 = Graphics.FromImage(bmp2))
G2.DrawImage(bmp, 0f, 0f, area, GraphicsUnit.Pixel);
}
return bmp2;
}
I have an idea and maybe you guys can give me a good start or an idea in which path might be correct.
I have a picturebox right now loading a specific bmp file. What I want to do is load this bmp file into the picturebox and then load another picture on top of it. The kicker to this all is the 2nd picture must be drawn. The 2nd picture is just a fill in black box. This black box must also overlay on the first image exactly right, the black box has cordinates from paint on it (yes we have the # of the cordaints).
Still think the picturebox is the way to go, or is there a way to load paint into this, and then paint on top of the paint image?
1) Need to load an image
2) Need to read a specific file that has cords
3) Need to draw a black rectangle that matches those coords (Those cords were created in paint).
What do you think the best way to approach this is? A Picture box with code to draw in the cords of the redacted image
Here's a code sample that should do what you're after:
//Load in an image
pbTest.Image = Image.FromFile("c:\\Chrysanthemum.jpg");
//Create the graphics surface to draw on
using (Graphics g = Graphics.FromImage(pbTest.Image))
{
using (SolidBrush brush = new SolidBrush(Color.Black))
{
//Draw a black rectangle at some coordinates
g.FillRectangle(brush, new Rectangle(0, 0, 20, 10));
//Or alternatively, given some points
//I'm manually creating the array here to prove the point, you'll want to create your array from your datasource.
Point[] somePoints = new Point[] { new Point(1,1), new Point(20,25), new Point(35, 50), new Point(90, 100) };
g.FillPolygon(brush, somePoints);
}
}
The finished article:
This answer is written to apply to both web and non-web uses of C# (why I did not give specific examples.)
GDI and other graphics libs all have functions that will paint a filled rectangle on top of an image. This is the way to go. If you use two images there is a good chance for a standard user and a great chance for a hacker they will be able to view just the original image, exposing the information you are trying to hide.
If you only send an image with the areas redacted, you will never have to worry about them being seen.
I have a png image file with alpha blending of its own. Now I want to load it onto a form in a mobile. I tried so many ways but not work. Is there any solution? Thanks in advance.
This is what I use to load the image from resource:
Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("drawObj.Graph.png");
Bitmap myPNGImg = new Bitmap(stream);
Then create new bitmap with same size of the images Graph.png:
Bitmap myBlankImg = new Bitmap(48,48);
Graphics mynewGraph = Graphics.FromImage(myNew);
mynewGraph.Clear(Color.Transparent);
Draw the PNG bitmap: mynewGraph.DrawImage(myPNGImg, 0, 0);
And then something I read from internet:(
Rectangle rectDest = new Rectangle(50,50, 100, 100);
ImageAttributes imgatt = new ImageAttributes();
imgatt.SetColorKey(Color.Transparent, Color.Transparent);
myGraph.DrawImage(myNew, rectDest, 0, 0, 99, 99,GraphicsUnit.Pixel, imgatt);
It works, but just clear the four corner of the images(somekind of rounded rectangle). There's still some white border around the images left.
Loading images using Bitmap on Compact Framework will lose alpha information. Setting the color key is an alternative way of doing transparency where you sacrifice an exact single color as the transparent color.
To use alpha blending on Compact Framework, you can use the helper classes from OpenNETCF to load the PNG file, keeping the alpha information (see Transparency and alpha blending), then P/Invoke AlphaBlend. It's not pretty, but it's what it takes. Also be warned that you will take a heavy performance hit for using alpha blending. To bake some images dynamically, it's fine, but for generic on screen drawing operations, you might want to use another approach.
The problem is that in the CF, filling with Color.Transparent actually fills with white (see these two blog entries). Project Resistance has a very good example of how to do this blending (actually several of them).