In a Windows Forms application, how do I take a "screenshot" of certain coordinates?
In the picture below, you see a Window and inside that window is a little gray box, somewhere near the center.
Where every I might place that box, how can I take a "screenshot" of it (including whatever content is inside it) programmatically?
Simple way
Simple, use Graphics.CopyFromScreen
private Bitmap bitmap;
private Graphics graph;
graph.CopyFromScreen(X, Y, 0, 0, Size, CopyPixelOperation.SourceCopy);
Now you can use bitmap, that contains a source copy of the area.
Hacky way
SendKeys.Send("%{PRTSC}"); //Alt + PrtSc to screenshot just the active window.
Bitmap clipboardImage = Clipboard.GetImage(); //Get image from the clipboard
//Here you crop the image using Bitmap.Clone();
//Be happy and question yourself why you are doing this way.
Related
I'm developing drawing tool control using inkcanvs in wpf.
When i draw rectangle, this is original image.
Original Image
And i set that editing mode is erase by point. When i erase rectangle, this is image after working.
Erased Image
I want that erase function works as well as default drawing tool in windows. It would be worked by pixel. Erase shape by pixel.
Part of Source Codes
public class Label : Stroke
{
protected override void DrawCore(DrawingContext drawingContext, DrawingAttributes drawingAttributes)
Rect rect = new Rect((Point)this.StylusPoints[0], (Point)this.StylusPoints[1]);
drawingContext.DrawRectangle(...)
This is not possible with the standard API.
Only by translating an ink image (strokes, which are enhanced vectors) to a bitmap image (which contains pixels) individual pixels can be manipulated but the stroke information will be lost.
With quite some effort an application could be created that keeps track of all its user's actions (draw some strokes, add a pixel, remove a pixel) and replays them all every time the UI needs a redraw, injecting the transformation from vector to bitmap where needed.
This is a nice exercise but might prove to be too slow and/or complex.
I'm currently designing a program in "Visual Studio 2015 C#" and would like to implement circular picture boxes. In the program there are picture boxes which source image is downloaded from the web. In it's default state, the "picturebox" is square. I would like to know how I could change the shape of the "picturebox" to a circle. That way the image when loaded will be circular instead of squared or rectangular.
I already figured out how to downscale the image and keep it's quality and center it, but I do not know how to change the "picturebox" into a circle.
I found a couple ways to do it, but unfortunately with this methods the circle is not smooth, instead it is pixelated.
This is an example of what I would like: http://i.imgur.com/kaOfTFU.png
You create a path (that is a circle, or whatever shape you want), and set the picturebox region to that path. Here's an example with a circle:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
System.Drawing.Drawing2D.GraphicsPath path = new System.Drawing.Drawing2D.GraphicsPath();
path.AddEllipse(0, 0, pictureBox1.Width, pictureBox1.Height);
pictureBox1.Region = new Region(path);
}
}
This StackExchange post has how to make any path smooth for a picturebox:
Possible to have anti-aliasing when drawing a clipped image?
I need to create a program that will display lines or dots of coordinates read from a txt file. The application will be attached to the output of an eye-tracking program, and will display the data.
How do I display some sort of graphic at a particular coordinate on the screen?
Note: The window is full-screen, and I can use WPF or WinForms.
I would overlay your video with an Image element; something like:
<Grid>
<Image x:Name=TrackingImage />
<MediaElement/>
</Grid>
Then in your code behind; set the source to a WriteableBitmap. The documentation has an excellent sample, but to summarize it here:
WriteableBitmap writeableSource = new WriteableBitmap(100, 100, 96, 96, PixelFormats.Bgra32, null);
// Calculate the number of bytes per pixel.
int _bytesPerPixel = (writeableSource .Format.BitsPerPixel + 7) / 8;
// Stride is bytes per pixel times the number of pixels.
// Stride is the byte width of a single rectangle row.
int _stride = writeableSource .PixelWidth * _bytesPerPixel;
private void SomeUpdateFunction()
{
// Define the rectangle of the writeable image we will modify.
// The size is that of the writeable bitmap.
Int32Rect _rect = new Int32Rect(0, 0, _wb.PixelWidth, _wb.PixelHeight);
//Update writeable bitmap with the colorArray to the image.
_wb.WritePixels(_rect, pixelBuffer, _stride, 0);
TrackingImage.Source = writeableSource;
}
Note that it uses WritePixels (specifically; this overload: MSDN)
Obviously you will need to modify the parameters to get the correct pixel in the correct place. This is the right technique though.
This answer was inspired by: Drawing Pixels in WPF It might be worth looking at if you need more info.
Various bitmap formats are instructions to put colored dots at specific locations. Why not use something like that? What ELSE do you need it to do?
Regarding your eye-tracking and point-data comment, if you want to composite it with captured video, then you don't need to worry about how to display the images so much as you need to think about how to add the dots to the video itself. The video player will do the displaying.
From what I know about screen-capture and video codecs (not a whole lot) it will be best to work with the uncompressed video before it gets encoded. Otherwise you'll have to decode, add, and re-encode. I'd look for a way to hook into the capture program and add the live eye-tracker data to the captured frames.
Alright guys last little bit of this project I'll ask for help on I promise.
So I go to load the images, works fine however I notice upon loading that the dimensions of the image have been scaled down in the y to 300 (all are a constant value of 433) and up or down from their original width to 600.
I'm using the following method to load them
foreach (string file in Directory.EnumerateFiles(imagePath, "*.JPG"))
{
Image contents = Image.FromFile(file);
treesImage[count] = contents;
count++;
}
and this is the resulting image when I have it loaded.
http://i.stack.imgur.com/Q40kK.png
As you can see the image below the red rectangle is quite small
Any help would be appreciated. If you require any more information please post below and I'll make sure to edit the original question with the relevant information as soon as humanly possible.
EDIT: I am using a simple windows form application and not another graphical framework for my own reasons.
Thanks in advance :)
I'll assume you are using a PictureBox control to display the image.
When someone chooses a tree from your map, you obviously set the PictureBox Image property to the image object referenced by the index in the array. Use the Image object to set the ClientSize of the PictureBox control.
...
Image img = treesImage[idx];
MyPictureBox.SizeMode = PictureBoxSizeMode.Normal;
MyPictureBox.ClientSize = new Size(img.Width,img.Height);
MyPictureBox.Image = img;
...
Alternately you can define one size for your PictureBox and force all the images to be scaled to that size by setting the control SizeMode property to StretchImage declaratively.
I would recommend that you create a simple class (MyImageInfo for example) that would store the Path, Width, and Height of the images found in your first function into a list and then just as before when a user clicks to view an image you set the width and height of the PictureBox and then call the LoadAsync(path) method to get the image. then you aren't storing all images in memory at once, just as you need them since it doesn't look like this requires a lot of quick jumping from image to image.
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.