I am reading in a bitmap that is quite large and has a lot of useless space. The original image height is 2048 and the width is 1024.
I want to crop/clip the image for display purposes starting from the bottom left and showing an image height of 1047 and width of 1024 in c#. I've tried using CroppedBitmap but I keep getting an out of bounds error.
(The code below shows some random parameters as I started inputting a lot of stuff to get it to work even a little.)
This gives me the error:
CroppedBitmap cb = new CroppedBitmap((BitmapSource)bitmapImage,
new Int32Rect(2048,0,30,50));
EDIT: To put it another way, I want to get rid of the top half of the image.
CroppedBitmap cb = new CroppedBitmap(
bitmapImage,
new Int32Rect(0, (int)(bitmapImage.Height/2),
(int)bitmapImage.Width, (int)(bitmapImage.Height/2));
This will create a CroppedBitmap from the lower half of the bitmapImage. The Int32Rect should describe the part you want to keep.
Related
I can create an image of an arbitrary size using this code:
using var image = original.Clone(context =>
context.Pad(width, height, Color.White)
);
However, this places the original image in the center of the new image. Is there a way to specify the location (e.g., using AnchorPositionMode)? I'd like the original image in the bottom right corner of the new image.
Pad as described in the docs is designed for evenly padding an image to fit the new dimensions.
You can combine Resize with ResizOptions to position padding but if you require fine grained control use DrawImage.
Hello Stackoverflow Community.
I currently work on an application which has a cursor region magnifyer feature, for the user to pick a color.
However, i've the problem that the Picturebox has white edges on the right and bottom, even though the image captured is only one dark color.
The captured screen is 10x10 pixel and the Picturebox is 80x80 pixel and it's SizeMode set to StretchImage.
I checked if the raw captured image maybe contains this edges already by saving it and checking it in Photoshop. But the raw captured image is fine, so it must be something weird with the Picturebox.
Here you can see how it looks (The mousecursor and the capture-region[green rectangle] are just painted on the screenshot for demonstration, as i was not able to screen my cursor, and yes - the green region is painted way too large, it should be just 10x10 pixel ^^)
Has it maybe something to do with the way the Image get's stretched internally? If so, is there any, not too complicated way around it?
I appreciate any help in advance :)
//Edit: I think it's actually about the stretching
I found this topic Image after resize has white border but i don't know what the GetSize() Method is, or where it is (from)
Have a great day!
I found a solution for the edges here, as you can see in the first screen. However, in the second screen you can see a 2x2 pixel capture, stretched to 80x80 pixel with the found "solution", will mix colors as it's actually 80x80 pixel in the end, while i want to have it displaying the raw pixels, so, 3 black ones and one white one in this case. Now i am even more stuck ^^
I guess i should instead read the pixel colors of the single pixels from captured image and set the colors in the preview picturebox, or make 4 panels in the case of just 2x2 pixels
public new Image Resize(Image image, int targetWidth, int targetHeight)
{
var resizedImage = new Bitmap(targetWidth, targetHeight);
using (var graphics = Graphics.FromImage(resizedImage))
{
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
var attributes = new ImageAttributes();
attributes.SetWrapMode(WrapMode.TileFlipXY);
var destination = new Rectangle(0, 0, targetWidth, targetHeight);
graphics.DrawImage(image, destination, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, attributes);
}
return resizedImage;
}
//Edit:
Okay i think i'm gonna use Get/SetPixel or Panels(for small captures), as i did here on the right, the left is still the 80x80 Picturebox
I'm writing an image viewer application that loads large still images. I must be able to zoom in to 1:1 to measure exact pixel coordinates of features in the image. I'm using the Viewport control posted here that works great for zoom and panning. I can load a 150 MP tiff image with BitmapDecoder and its pixel count is correct 14000 x 10000. However, when I assign this bitmap to the Image.Source property it gets decimated to roughly 15MP:
sourceBitmap.PixelWidth = 14204
sourceBitmap.PixelHeight = 10652
After assigning this bitmap to image1.Source we get
image1.Source.Width = 4545.27...
image1.Source.Height = 3408.64...
I'm aware of the unitless context of WPF graphics, and can work back the scale factors to read original coordinates, but there is a risk of rounding errors, and I'm working on a scaled copy that degrades the original image resolution.
According to the Microsoft documentation, a WPF bitmap can be up to 64GB in size, but the Image control seems not to be designed to work with bitmaps larger than 15MP. Setting Stretch to "None" makes things worst. It trims the image to the top left 4545 x 3408 pixels of the source and it displays it very small, almost as a thumbnail instead of 1:1.
Is there any way around this limitation?
In contrast to a BitmapSource's PixelWidth and PixelHeight, the Widthand Height values depend on its DPI (dots per inch), which is a TIFF or EXIF tag in the image file.
The values are identical when the resolution is 96 DPI, otherwise calculated as
Width = PixelWidth * 96 / DpiX
Height = PixelHeight * 96 / DpiY
Apparently, your images are tagged with 300 DPI.
This does in no way affect the pixel count, but just determines the native, unstretched size of the bitmap when it is shown in an Image element or ImageBrush.
Instead of using Width and Height, just keep using PixelWidth and PixelHeight:
var bitmap = (BitmapSource)image1.Source;
var width = bitmap.PixelWidth;
var height = bitmap.PixelHeight;
your help is much appreciated. I am using C# and EmguCV for image processing
I have tried noise removal, but nothing happens. I also tried image median filter, and it only works on the first image, but it does not work on the second image. It only makes the second image blurry and the objects larger and more square-like.
I want to remove obviously distinct objects(green ones) in my image below so that it would turn all black because they are obviously separated and are not grouped unlike the second image below.
Image 1:
At the same way, I want to do it in my image below, but remove only those objects -- (the black ones) -- that are not grouped/(lumped?) so that what remains on the image are the objects that are grouped/larger in scale?
Image 2:
Thank you
You may try Gaussian Blur and then apply Threshold to the image.
Gaussian Blur is a widely used effect in graphics software, typically to reduce image noise and reduce detail, which I think matches your requirements well.
For your 1st image:
CvInvoke.GaussianBlur(srcImg, destImg, new Size(0, 0), 5);//You may need to customize Size and Sigma depends on different input image.
You will get:
Then
CvInvoke.Threshold(srcImg, destImg, 10, 255, Emgu.CV.CvEnum.ThresholdType.Binary);
You will get:
For your 2nd image:
CvInvoke.GaussianBlur(srcImg, destImg, new Size(0, 0), 5);//You may need to customize Size and Sigma depends on different input image.
You will get:
Then
CvInvoke.Threshold(srcImg, destImg, 240, 255, Emgu.CV.CvEnum.ThresholdType.Binary);
You will get:
Hope this help!
You should first threshold the image using Otsus method. Second run connected component analysis on the threshold image. Third go over all the component that you found and for the ones that have a size that is smaller than some min size delete it from the original image.
cvThreshold (with CV_THRESH_BINARY/CV_THRESH_BINARY_INV(choose according to the image) + CV_THRESH_OTSU) http://www.emgu.com/wiki/files/1.3.0.0/html/9624cb8e-921e-12a0-3c21-7821f0deb402.htm + http://www.emgu.com/wiki/files/1.3.0.0/html/bc08707a-63f5-9c73-18f4-aeab7878d7a6.htm
CvInvoke.FindContours (RetrType == External,ChainApproxNone)
For each contour that we found in 2 calculate CvInvoke.ContourArea
If area is smaller than minArea draw on the original image(The one you want to filter) the value you want for them(0 I suppose) in the original image using CvInvoke.DrawContours with the current contour and with thickness==-1 to fill the inside of the contour.
I'm using the Drawstring method of the Graphics Class to Draw a Text on an Image.The Font is Specified before drawing.
G.DrawString(mytext, font, brush, 0, 0)
The Problem arises when the same text is drawn on an image with smaller size.The Text drawn appears to be larger.I'm looking for a solution to alter the font size according to the image size so that the text don't appear larger or smaller when drawn on images of different sizes.
I'm attaching the images with different sizes with the text of same font size drawn on it.
http://i.stack.imgur.com/ZShUI.jpg
http://i.stack.imgur.com/GUfbM.jpg
I can't directly post the image because I'm not allowed.
You would get most precise scaling by drawing on separate image and then slapping that image onto original one. You'd do that as follows:
Create in-memory Bitmap with enough space
Draw text on that bitmap in your default font
Draw image containing the text onto original image by scaling it to size you need
Code:
Bitmap textBmp = new Bitmap(100, 100);
Graphics textBmpG = Graphics.FromImage(textBmp);
textBmpG .DrawString("test 1", new Font(FontFamily.GenericSansSerif, 16), Brushes.Red, new PointF(0, 0));
Graphics origImgG = Graphics.FromImage(originalImg);
origImgG.DrawImage(textBmpG, new Rectangle(50, 50, 50, 50), new Rectangle(0, 0, 100, 100), GraphicsUnit.Pixel);
Take notice of last line and Rectangle parameters. Use them to scale your text bitmap onto original image. Alternatively, you can also choose Graphics.MeasureString method to determine how wide your text would be and make attempts until you get best one you can.
Use Graphics.MeasureString() to measure how big your string would be on the image
Decrease/increase font step by step accordingly
As you requested in comment I'll give you more detailed suggestion here. Say your original image width is WI1, and width of text on it using Graphics.MeasureString is WT1. If you resize your image to width WI2, then your perfect text width would be WT2 = WT1 * WI2 / WI1. Using DrawText method you may not be able to get this exact width because when you increase font by 1 it may jump over that value. So you have to make several attempts and find best. Pick a size of font, if resulting text width is smaller (measure with MeasureString), increase it until it becomes bigger than target and you've got about closest match. Same thing goes if it's too big. Decrease font step by step.
This is quick and dirty as you see, because you have many draws, but I can't think of better solution, unless you're using monospaced fonts.
Difference between those solutions would be that in first you can get text to fit EXACT size you need, but you probably would loose some font readability due to scaling. Second solution would give good readability, but you can't get pixel perfect size of text.
In my opinion you have two ways:
Draw text on original image and then resize resulting image (so, even text included in it)
Scale font size by a factor newImageWidth/originalImageWidth.
It's not perfect because you could have some problem with text height (if new image is not just scaled but with different aspect ratio), but it's an idea