I have an Image control set for Uniform stretch. It is wider than tall (landscape). I am putting a graphic (source) in it that is taller than wide (portrait). This means that the top and bottom of the graphic match the top and bottom of the Image control and there is 'dead space' on either side of the graphic. Got the picture? (pun intended)
At this point I zoom in and out of the graphic using a Matrix.ScaleAtPrepend on the Image control and pan using Matrix.OffsetX and OffsetY. Works great.
Now I would like to click on the panned/zoomed graphic and get the pixel coordinates of my click relative to the graphic and not relative to the Image control.
How might I do that?
Related
Is this possible?
I want to do something like store the X and Y coordinates of a point in an image and jump to that area on the click of a button.
What I have in my form is a Panel with the Auto Scroll property set to true. Inside the panel is a PictureBox, if the image gets bigger scroll bars appear on the panel. So what I currently have is getting the positions of the scrollbars then moving to that position using Panel1.AutoScrollPosition works fine except if the image size changes like when zooming in or out, then i'm looking at the wrong position.
So is it possible to get a specific point on the image itself and not the picturebox or any control in the form? Note that the image i'm currently playing with is 33722 x 4672.
I believe what you're looking for is the Bitmap class.
You can use the function GetPixel() to get the pixel at a location in your image.
To put your PictureBox Image into a Bitmap object do this.
Bitmap bitmap = new Bitmap(mypicturebox.Image);
bitmap.GetPixel(i, j);
What possibilities are there to simulate negative padding in a picturebox in C#? I want to be able to show a cropped version of an image without actually cropping it. When "cropping" the right or bottom side it's easy just to change the size of the picturebox to hide a part of the image, but how do I get the picturebox to hide some pixels on the left or top sides without either cropping the original image or creating a new cropped version of it?
Specifically: I need to capture as a bitmap a specific region of what a picturebox is actually displaying. The coordinates of the region are specified by the bounds of a control that I have overlayed on top of the picturebox (but that belongs to the picturebox). The control is hidden when I make the "snapshot" of the region.
I tried using normal screen capture methods (CopyFromScreen), but you can't really control the timing there. So it was capturing "interstitial" states, like transitions between photos in my picturebox. Frequently it was only capturing purely black images (the background color of the picture box).
So I tried just converting the image (picturebox.image property) being displayed to a bitmap. The problem there is that the picture box is rarely showing exactly the image. It's displaying some PORTION of the image, scaled and clipped as appropriate to it's sizemode (which is zoom). So the I can't just take my control coordinates and clip them from the image as a whole.
So I tried to estimate what portion of the image was being displayed, and correcting my rectangle based on that. Turns out that I was basically re-creating the "zoom" code of the picturebox to do this (using aspect ratio of the picturebox, the aspect ratio of the image, guessing at what level of scaling is currently happening to the image if it's larger or smaller than the picturebox, etc). It was not pretty.
So: now I need a method of just capturing only the bitmap currently being displayed in the client area of the picturebox, including the photo and any black "letterboxing" currently being displayed around it. Anybody got one?
Remember that I can't rely on using CopyFromScreen. It's not reliable enough for my purposes. I think I need a method of getting picturebox to TELL me the bits it is displaying.
This will copy and save the currently shown content of the PictureBox including a BackgroundImage (if there is one and if it shines through) and also all Controls that belong to the PictureBox, like Labels etc.. Also included are elements drawn in the Paint event. Things drawn outside the Paint event are non-persistent and will not be included.
using (Bitmap bmp = new Bitmap(pictureBox1.ClientSize.Width,
pictureBox1.ClientSize.Height))
{
pictureBox1.DrawToBitmap(bmp, pictureBox1.ClientRectangle);
bmp.Save(yourfilename, ImageFormat.Png);
}
Note: On my test Form the PicureBox is sitting inside an AutoScroll Panel pan_PBscroll. The PictureBox is displaying pixels 1:1 and is therefore, with a photograph loaded, much bigger than the Panel, the Form or even the Screen. So to clip to the actually visible parts I could not use the pictureBox1.ClientSize and pictureBox1.ClientRectangle but used the dimensions of that Panel. This may well apply to you, too.
I'm not sure about your timing issues. But since you mentioned CopyFromScreen here are a few differences:
CopyFromScreen makes a 1:1 copy of each screen pixel
This includes non-persistent drawings and excludes anything covered or hidden
Control.DrawToBitmap makes the Control draw itself onto a Bitmap, just as it draws itself during Paint
This excludes anything that doesn't belong to the Control but includes all members of its Controls collection
This also excludes non-persistent drawings but includes the full Size of the Control, whether it fits on the Form or Screen or not and whether it is hidden or covered or not.
For Controls with active Scrollbars only the visible parts are copied. To copy all you need to resize it temporarily. Then you can get a complete image of a listbox even if it has a thousand items..
Since you're using a PictureBox I would say to take a look PictureBox.Image where you can get the Bitmap object.
Hope it helps.
I am attempting to make a reusuable, XAML, icon. It is composed of three parts.
Background, Bezel and Graphic Path objects. The shape is of a rectangle with the top right corner cut off, the bezel is same shape with the middle cut out and a margin of 1.
I need the graphic path to fit inside of this with a slight margin.
I would like it to be intelligent enough to scale itself to fit within the confines of the bezel regardless of it's shape. Like ClipToBounds only I don't want the graphic to clip - I would like it to scale.
I initially thought setting the Margin would work, however, setting the Margin of the graphic is based on a Rectangle and not the irregular shape of the bezel; so graphics with a more rectangular shape are often touching or too close to the right-side cut off of the bezel.
Does anyone have any ideas on how I might achieve this kind of ScaleToBounds behavior?
EDIT:
Please see attached pictures for an example of the problem. Both graphics are contained inside a ViewBox with a Margin. The circular graphic is the ideal margin I would like to see around the graphic. The rectangular graphic is too close to the bezel - I would like to have graphics such as the rectangular graphic scale themselves down slightly so they fit within the bezel with some margin.
rectangular graphic http://s11.postimage.org/a5v05ve2n/rectangular.png
circular graphic http://s11.postimage.org/do7029eyn/circular.png
I need to move the black square in an arbitrary area of the screen and copy screen area inside black square to area in my application.
How to do it? Thanks.
Take a look at Graphics.CopyFromScreen():
http://msdn.microsoft.com/en-us/library/system.drawing.graphics.copyfromscreen.aspx
As for the movable black rectangle, I'd suggest making a transparent form and manually painting the border as desired. Use the client area size and position of the form as a hint as what to pass to CopyFromScreen().