Crop rectangle from image and print and save it - c#

I want to draw a rectangle inside an image (imageToCrop), which is in a Canvas, and print that cropped rectangle beside the image.
Then I need to save it to a new file.
I draw a System.Windows.Shapes.Rectangle on my image and this work.
Here is my code to crop the rectangle and print it to another image (croppedImage) :
croppedImage.Width = selectionBox.Width;
croppedImage.Height = selectionBox.Height;
CroppedBitmap cb = new CroppedBitmap((BitmapSource)imageToCrop.Source, new Int32Rect(Convert.ToInt32(Canvas.GetLeft(selectionBox)), Convert.ToInt32(Canvas.GetTop(selectionBox)), Convert.ToInt32(selectionBox.Width), Convert.ToInt32(selectionBox.Height)));
croppedImage.Source = cb;
The problem is that I get in the other image a new image witch have the good sizes, Height and Width of the drawn rectangle, but it's an unyform color, not related to the drawn rectangle...
I don't understand why ?

Related

Saving off picturebox composed of image and drawings

Here is what I am trying to do. I have an Image that is 1920X1080. I am showing that image in a PictureBox and allowing a user to draw an ellipse on the screen. Once they finish that I will need to save that image off with the image and ellipse in 1 photo.
So I have tried several ways:
1. Just trying to save the image and ellipse from the PictureBox. No success doing that.
2. To store the location of the ellipse on the picture box and then redraw that ellipse on a new copy of the image using a graphics object. The problem with this one is that when it saves off the ellipse is not in the right place due to the size of the PictureBox and the original image difference.
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
pictureBox1.Cursor = Cursors.Default;
if (isMoving)
{
Circles.Add(mouseDownPosition, mouseMovePosition);
}
isMoving = false;
}
Bitmap newImage = new Bitmap(new Bitmap(#"C:\Personal\test\Sample.jpg"));
Graphics g = Graphics.FromImage(newImage);
foreach (var circle in Circles)
{
g.DrawEllipse(new Pen(Color.Red, 3), new Rectangle(circle.Key, new Size(circle.Value.X - circle.Key.X, circle.Value.Y - circle.Key.Y)));
}
newImage.Save(#"C:\Projects\Projects\SampleCombine.jpg");
I am really just looking for a way to take exactly what I see on the PictureBox and save it as its own jpg.
My take is that I need to figure out how to reposition the "Circle" based on where it was drawn and where it should be drawn on a larger file.
Any ideas?

Strech image to fill the transparent background using Magick.NET

I have an image (attached).
I want the image to be stretched out to cover the yellow area.
I am using c#, magick.net
What will be the best approach?
I propose the following approach:
read input image saving original size
remove the transparent* area using trim
stretch the (now smaller) image to the original size
*If the yellow area in your sample image is actually transparent you can leave fuzz = 0 in the following code, otherwise you'll have to adjust the value to be sure to remove all the unwanted area.
string srcImageFullPath = "c:\input.png";
int fuzz = 0;
string destImageFullPath = "c:\output.png";
// Read image from file
using (MagickImage image = new MagickImage(srcImageFullPath))
{
//save height/width of the original image
int height = image.Page.Height;
int width = image.Page.Width;
//set fuzz percentage
image.ColorFuzz = new ImageMagick.Percentage(fuzz);
//trim borders
image.Trim();
//resize image to original size
MagickGeometry size = new MagickGeometry(width, height);
size.IgnoreAspectRatio = true;
image.Resize(size);
// Save the result
image.Write(destImageFullPath);
}
In the following picture you can see the original image on the left, and the image after resizing on the right:
Notes
Trim removes any border that has the same color of the pixels in the corner of you image (see here for the details)
Since the yellow border in your sample image is not made of a single color you can use Fuzz to remove "similar" colors (more info here). As said before if your border is transparent just leave fuzz = 0

How to place a Rectangle in a new image with different size, while preserving the size and quality of the orignial Rectangle?

I have an image that contains some letters. Each of the letters has been placed in a Rectangle object.
The rectangles are of different sizes, but i want to save each of them to a new image which has the same size. In this case 260x260.
Here is my approach:
foreach(Rectangle letter in letters)
{
Bitmap letterBitmap = img2.Clone(letter, img2.PixelFormat);
Image newImage = (Image) letterBitmap;
Bitmap newLetterBitmap = new Bitmap(newImage, new Size(260, 260));
}
The Problem is that the size of the rectangle gets changed, so it fits the new size of the Bitmap. I just want the new image to have a black background and be bigger than the original rectangle.
Try something like this:
Bitmap newLetterBitmap = new Bitmap(260, 260);
Graphics g = Graphics.FromImage(newLetterBitmap);
g.DrawImageUnscaled(newImage, 0, 0);

How to save the painted control as a bitmap?

I have a picturebox (pictureBox1), and it gets lines drawn on it, from the paint event. I was wondering how to convert that drawing (with the lines) to a bitmap, and save it as a file. I've tried:
Bitmap bmp = new Bitmap(pictureBox1.Width, pictureBox.Height);
pictureBox1.DrawToBitmap(bmp, pictureBox1.Bounds);
bmp.Save("MyImage.bmp");
But that is a blank image, without the lines. Does anyone know how I can save it with the lines? Thank you.
int bitmapX = 100
int bitmapY = 100
Bitmap imgToSave = new Bitmap(bitmapX, bitmapY);
Graphics gfx = Graphics.FromImage(imgToSave);
// draw on the image with
gfx.DrawLine() // or whatever you want to draw
// save the screenshot
string saveFilePath = Application.StartupPath + "\<name of the image>.png";
imgToSave.Save(saveFilePath, ImageFormat.Png);
This is a code snippet that works for me.
Don't use the PictureBox.Bounds property but instead use a simple Rectangle object/structure filled with the `PictureBox' width and height like this:
var bitmap = new Bitmap(pictureBox1.Width, pictureBox1.Height);
pictureBox1.DrawToBitmap(bitmap, new Rectangle(0, 0, pictureBox1.Width, pictureBox1.Height));
bitmap.Save("c:\\temp\\image.bmp");
Using the Bounds property you are fetching the correct size of the picture box control, but depending on the position not the 0,0 coordinate, but the control position, which leads to an empty bitmap.

Capturing an image behind a rectangle

I have written a small application which will be used in my work environment for cropping images. The windows form (.NET 3.5) that contains the image has a transparent rectangle which I use for dragging over a section of an image and hitting a button to get me whatever was behind the rectangle.
Currently I am using the code below, this is causing me issues because the area that it is capturing is off by quite a few pixels, and I think it's something to do with my CopyFromScreen function.
//Pass in a rectangle
private void SnapshotImage(Rectangle rect)
{
Point ptPosition = new Point(rect.X, rect.Y);
Point ptRelativePosition;
//Get me the screen coordinates, so that I get the correct area
ptRelativePosition = PointToScreen(ptPosition);
//Create a new bitmap
Bitmap bmp = new Bitmap(rect.Width, rect.Height, PixelFormat.Format32bppArgb);
//Sort out getting the image
Graphics g = Graphics.FromImage(bmp);
//Copy the image from screen
g.CopyFromScreen(this.Location.X + ptPosition.X, this.Location.Y + ptPosition.Y, 0, 0, bmp.Size, CopyPixelOperation.SourceCopy);
//Change the image to be the selected image area
imageControl1.Image.ChangeImage(bmp);
}
If anyone can spot why when the image is redrawn its quite a bit out, I'd be eternally grateful at this point. Also, the ChangeImage function is fine - it works if I use a form as a select area but using a rectangle has jazzed things up a bit.
You've retrieved the relative position to the screen as ptRelativePosition, but you never actually use that - you add the rectangle's location to your form's location, which doesn't account for the form's border.
Here's that fixed, with a few optimizations:
// Pass in a rectangle
private void SnapshotImage(Rectangle rect)
{
// Get me the screen coordinates, so that I get the correct area
Point relativePosition = this.PointToScreen(rect.Location);
// Create a new bitmap
Bitmap bmp = new Bitmap(rect.Width, rect.Height, PixelFormat.Format32bppArgb);
// Copy the image from screen
using(Graphics g = Graphics.FromImage(bmp)) {
g.CopyFromScreen(relativePosition, Point.Empty, bmp.Size);
}
// Change the image to be the selected image area
imageControl1.Image.ChangeImage(bmp);
}
Interestingly, this was because of the space between the main form and the control that the image was on and the toolbar at the top of the form separating the control and the top of the main form. To get around this I simply modified one line in capture screen to account for those pixels, as shown below:
g.CopyFromScreen(relativePosition.X + 2, relativePosition.Y+48, Point.Empty.X, Point.Empty.Y, bmp.Size);
Cheers

Categories

Resources