I'm fairly new to working with c#, so I am sure there is a way to accompish this, but I have been unable to find an answer that works.
I am making a simple game where you create a pizza (similar to dominoes interactive ordering system). The user selects the toppings from a list and they appear on the pizza image. I planned to simply change the visibility of the topping .pngs when the items are selected, however, the last .png to appear covers up all previous ones.
I have tried using picture boxes and panels.
When using picture boxes, only the top visible image shows. I have the .pngs backgrounds set to transparent, and while they do show the form's background color, they mask the other .pngs.
When I used the panels, I had problems with the upper images parenting with the lower ones, so if I changed the visibility of the bottom one, all ones above it were hid as well.
I appreciate any help and advice.
Mix images at runtime and add it to your picturebox:
Bitmap bmp = (Bitmap)Bitmap.FromFile("pizza.png"); //or get it from any other source
Bitmap bmp2 = (Bitmap)Bitmap.FromFile("over.png"); //or get it from any other source
Bitmap bmpdest = new Bitmap(bmp.Width, bmp.Height);
Graphics g = Graphics.FromImage(bmpdest);
g.DrawImage(bmp, new Point(0, 0));
g.DrawImage(bmp2, new Point(0, 0));
PictureBox1.Image = (Image)bmpdest;
Related
I'm writing a little program that tranfers a screen shot of a user screen to my wpf image control but when the image is displayed it is not full,not the whole screen is displayed even if the action was done through my computer and not my leptop and it is blurry
Bitmap bmp=
new Bitmap((int)SystemParameters.PrimaryScreenWidth(int)SystemParameters.PrimaryScreenHeight);
Graphics g = Graphics.FromImage(bmp);
g.CopyFromScreen(0, 0, 0, 0, bmp.Size);
the code above is the code to take the screenshot
BitmapImage bmI = new BitmapImage();
bmI.BeginInit();
bmI.UriSource = new Uri(FullPath);
bmI.EndInit();
Screen_Shot.Source = bmI;
And this code is the code to dislpay the image, Screen_Shot is the image name, and the full path is where i put the bitmap image
I tried to use
Screen_Shot.Stretch = Stretch.Fill; and UseLayoutRounding="True" SnapsToDevicePixels="True"
but none of them seems to get the job's done
this is an exsample of a screenshot i took from my own pc
You want to set the Stretch property to Uniform or else your image will be distorted as it will fill regardless of the Image control's size/shape. You also have to remember that the screen size may be different than your programs window size. If you don't uniformly stretch the image it will distort almost always (even if it's just a bit).
Regarding your "blurry" image, you need to specify the rendering option of you Screen_Shot image control or it will set the image to a lower quality that it can render more easily. This is honestly better to just set in the xaml. I normally use Fant, but look other options specified here.
<Image Name="Screen_Shot" RenderOption.BitmapScalingMode="Fant"/>
I want to use a PictureBox as a canvas and draw some text on it and save.
I wrote this piece of code but I'm not sure if im doing this the correct way:
Bitmap b = new Bitmap(pictureBox1.Width, pictureBox1.Height);
Graphics g = Graphics.FromImage(b);
g.FillRectangle(new SolidBrush(Color.White), new Rectangle(0, 0, pictureBox1.Width, pictureBox1.Height)); // i used this code to make the background color white
g.DrawString("some text", new Font("Times New Roman", 20), new SolidBrush(Color.Red), new PointF(10, 10));
pictureBox1.Image = b;
This code works well but when I want to change the background color of the image I have to redraw the text.
Is there a way to change the background color without having to redraw the text?
Writing a Paint program is a lot of fun, but you need to plan ahead for all or most of the features you want.
So far you have these:
A background you can change
A way to modify an image by drawing text on it
The need to save it all to a file
Here are a few more things you will need:
Other tools than just text, like lines, rectangles etc..
A choice of colors and pens with widths
A way to undo one or more steps
Here are few thing that are nice to have:
A way to help with drawing and positioning with the mouse
Other type backgrounds like a canvas or pergament paper
The ability to draw with some level of tranparency
A redo feature (*)
Rotation and scaling (***)
Levels (*****)
Some things are harder (*) or a lot harder (***) than others, but all get hard when you decide to patch them on too late..
Do read this post (starting at 'actually') about PictureBoxes, which explain how it is the ideal choice for a Paint program.
Your original piece of code and your question have these problems:
You seem to think that repeating anything, like redrawing the text is wrong. It is not. Windows redraws huge numbers of things all the time..
You have mixed two of the tasks which really should be separate.
You have not parametrizied anything, most notably the drawing of the text should use several variables:
Font
Brush
Position
the text itself
The same will be true once you draw lines or rectangles..
So here are the hints how do get it right:
Use the BackgroundColor and/or the BackgroundImage of the Picturebox to dynamically change the background!
Collect all things to draw in a List<someDrawActionclass>
Combine all drawings by drawing it into he Picturebox's Image
Use the Paint event to draw supporting things like the temporary rectangle or line while moving the mouse. On MouseUp you add it to the list..
So, coming to the end, let's fix your code..:
You set the backgound with a function like this:
void setBackground(Color col, string paperFile)
{
if (paperFile == "") pictureBox1.BackColor = col;
else pictureBox1.BackgroundImage = Image.FromFile(paperFile);
}
you can call it like this: setBackground(Color.White, "");
To draw a piece of text into the Image of the PictureBox, first make sure you have one:
void newCanvas()
{
Bitmap bmp = new Bitmap(pictureBox1.ClientSize.Width, pictureBox1.ClientSize.Height);
pictureBox1.Image = bmp;
}
Now you can write a function to write text. You really should not hard-code any of the settings, let alone the text! This is just a quick and very dirty example..:
void drawText()
{
using (Font font = new Font("Arial", 24f))
using (Graphics G = Graphics.FromImage(pictureBox1.Image))
{
// no anti-aliasing, please
G.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixel;
G.DrawString("Hello World", font, Brushes.Orange, 123f, 234f);
}
pictureBox1.Invalidate();
}
See here and here for a few remarks on how to create a drawAction class to store all the things your drawing is made up from..!
The last point is how to save all layers of the PictureBox:
void saveImage(string filename)
{
using (Bitmap bmp = new Bitmap(pictureBox1.ClientSize.Width,
pictureBox1.ClientSize.Height))
{
pictureBox1.DrawToBitmap(bmp, pictureBox1.ClientRectangle);
bmp.Save("yourFileName.png", ImageFormat.Png);
}
}
I need to be able to compare two different Images in the following way:
The images are displayed on top of each other so first there is only one image visible. When hovering with the mouse coursor over the image this defines the X-position of a vertical line which is splitting the image, displaying part of the first image left to the line and the rest of the second image right to the line.
This basically should be used as a quality comparison for two images with identical contents.
Here is a picture that hopefully makes my intentions clear:
you can use splitter control. splitter one side you put one picture control another side put other picture control
I was able to resolve this by using a SplitContainer and custom drawing. As described in the comment of Vasanthakumar's answer purely using a picturebox is not enough as you will not be able to align the right image at the same starting point than the left image (top left of the form).
What I did was the following:
pictureBox 1 displays its image normally
the Image in pictureBox 2 is drawn on every move of the splitter (this.splitContainer1.SplitterMoved += new System.Windows.Forms.SplitterEventHandler(this.splitContainer1_SplitterMoved); with a custom subset of the Image to be displayed.
This effectively allows to generate the overlay I need.
Part of my implementation showing the drawing logic:
Bitmap bmp = new Bitmap(gImg2.Width, gImg2.Height);
using (Graphics g = Graphics.FromImage(bmp))
{
g.DrawImage(gImg2, 0, 0, new Rectangle(e.SplitX, 0, gImg2.Width - e.SplitX, gImg2.Height), GraphicsUnit.Pixel);
}
pictureBox2.Image = bmp;
I have two overlapping pictureboxes.The images of both picture boxes have some transparent pixels.I want to see the bottom picture box through the transparent pixels of the overlapping picture box.
I tried setting the background color of both picture boxes as transparent.But it just sets the back color of the picture box to the background color of the form.
Clearly you are using Winforms. Yes, transparency is simulated by drawing the pixels of the Parent. Which is the form, you only see the form pixels, stacking effects don't work. There's a KB article that shows a workaround for this. It is painful. Another approach is to not use PictureBox controls but just draw the images in the form's Paint event.
Consider WPF, it has a very different rendering model that easily supports transparency.
Solutions to that problem might be various, and it mainly depends on your skills and amount of work will depend on kind of images you're dealing with. For example if images are always same resolution, size and overlapping image supports transparency you could try to do manipulation of two Image objects and draw one over another, then display it in PictureBox. Or if you will need to do it multiple times in various places of your app you could even consider creating your own UserContriol.
Code in answer of this question, method ResizeImagein particular, show how to create resized, good quality image, all you need it is to change it a little. Make it to get two Images as input parameters, and change it to draw one image over another.
Changes might look like this
public static Bitmap CombineAndResizeTwoImages(Image image1, Image image2, int width, int height)
{
//a holder for the result
Bitmap result = new Bitmap(width, height);
//use a graphics object to draw the resized image into the bitmap
using (Graphics graphics = Graphics.FromImage(result))
{
//set the resize quality modes to high quality
graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
//draw the images into the target bitmap
graphics.DrawImage(image1, 0, 0, result.Width, result.Height);
graphics.DrawImage(image2, 0, 0, result.Width, result.Height);
}
//return the resulting bitmap
return result;
}
And use it, for example, like this:
pictureBox1.Image = CombineAndResizeTwoImages(Image.FromFile("c:\\a.png"), Image.FromFile("c:\\b.png"), 100,100);
But that its only example, and you must tune it up to your needs.
Good luck.
If it's one PictureBox inside another, you can use:
innerPictureBox.SendToBack();
innerPictureBox.Parent = outerPictureBox;
I'm working on a Map Editor for an XNA game I'm designing in my free time. The pieces of art used in the map are stored on a single texture and rectangles are stored with coordinates and widths etc.
In the winforms application I can add segments by selecting the segment I want from a listbox, which is populated from the array of possible segments.
Problem is I would like to be able to show a preview of the segment selected and, since it is stored on a common texture, I cant simply set a picturebox to display the image.
Is there anyway of using the rectangle information (.x, .y, .width, .height) to display only the section of the image in a picturebox, or to blit the section to a bitmap and display that?
Many Thanks
Michael Allen
You probably want to look into the GDI library. Using the Image or Bitmap object and the Graphics.DrawImage() together will get what you're looking for.
private void DrawImageRectRect(PaintEventArgs e)
{
// Create image.
Image newImage = Image.FromFile("SampImag.jpg");
// Create rectangle for displaying image.
Rectangle destRect = new Rectangle(100, 100, 450, 150);
// Create rectangle for source image.
Rectangle srcRect = new Rectangle(50, 50, 150, 150);
GraphicsUnit units = GraphicsUnit.Pixel;
// Draw image to screen.
e.Graphics.DrawImage(newImage, destRect, srcRect, units);
}
You also might be interested in using XNA within your WinForm instead of using PictureBoxes and GDI. It's not 100% supported yet, but a tutorial on that can be found here.
You can use Graphics.DrawImage() and that will accept a Rectangle.