I know to Inflate the Rectangle by Pixels, How to by Percentage?
Ex: rect.Inflate(45%,105%) the integer value should be passed as percent value not pixel value
How??
One option is to use the SizeF structure to allow for you to calculate the width and height values by percentage values, like this:
SizeF theSize = new SizeF(rect.Width * .45, rect.Height * 1.05);
SizeF holds floating point values, but unfortunately there is no overload for Inflate() that accepts a SizeF, but it does have an overload that accepts a Size structure. So we need to convert a SizeF to a Size, like this:
// Round the Size
Size roundedSize = Size.Round(theSize);
// Truncate the Size
Size truncatedSize = Size.Truncate(theSize);
Finally, we can use our converted Size (either the rounded or truncated), like this:
rect.Inflate(roundedSize);
OR
rect.Inflate(truncatedSize);
There is no function to do this. You will need to calculate the pixels from the percentage and use those instead.
Related
How can I calculate in C# the exact resolution based on megapixels?
Let's say I have a 5000x4000 pixels image and I want to rescale to 0.6mpx, how can I get the exact horizontal and vertical resolution to get an image of 0.6mpx keeping the original aspect ratio?
I have this:
int nXPixels=5000; // original image Width
int nYPixels=4000; // original image Height
float fRatio=5000/4000; // original image aspect ratio
int nNewPixelResolution=600000; // 0.6mpx new resolution
int nNewXPixels=?
int nNewYPixels=?
Amount of megapixels is equal to the product of the length and width of the resolution, divided by 1 million. So for your 5000x4000 pixels, you would have 20 Mpx. To rescale it to 0.6Mpx, but keeping the ratio, you would just need to rescale each dimension by the squareroot of 20Mpx/0.6Mpx, so that, when the newly computed dimensions will be multiplied, the result would be equal to 0.6Mpx
So your computation should be similar to :
ratio=sqrt(20/0.6)
newWidth=oldWidth/ratio
newHeight=oldHeight/ratio
If you then multiply newWidth with newHeight, the result should be aproximately 0.6Mpx, or 600000 px
int nXPixels=5000; // original image Width
int nYPixels=4000; // original image Height
//float fRatio=5000/4000; // original image aspect ratio
int nNewPixelResolution=600000; // 0.6mpx new resolution
int nOldPixelResolution=nXPixels*nYPixels;
double conv = Math.sqrt((double)nNewPixelResolution/(double)nOldPixelResolution);
int nNewXPixels= (int)Math.round(nXPixels*conv);
int nNewYPixels= (int)Math.round(nYPixels*conv);
I want to be able to set the number of lines in a multilined TextBox.
I've tried the following:
int initHeight = textBox1.Height;
textBox1.Height = initHeight * numOfLines;
But this makes it too large when numOfLines gets large. So then I tried this:
float fontHeight = textBox1.CreateGraphics().MeasureString("W", textBox1.Font).Height;
textBox1.Height = fontHeight * numOfLines;
But this was too small when numOfLines was small, and too large when numOfLines was large.
So I'm doing SOMETHING wrong... any ideas?
This would set the exact Width & Height of your multi line Textbox:
Size size = TextRenderer.MeasureText(textBox1.Text, textBox1.Font);
textBox1.Width = size.Width;
textBox1.Height = size.Height + Convert.ToInt32(textBox1.Font.Size);
Something like this should work:
Size size = TextRenderer.MeasureText(textBox1.Text, textBox1.Font);
textBox1.Width = size.Width;
textBox1.Height = size.Height;
This was from C# Resize textbox to fit content
What you are doing should work, but you need to set the MinimumSize and MaximumSize I am not 100% positive, but I think this constraint will still hold if height is set via code
From the documentation of Graphics.MeasureString:
To obtain metrics suitable for adjacent strings in layout (for example, when implementing formatted text), use the MeasureCharacterRanges method or one of the MeasureString methods that takes a StringFormat, and pass GenericTypographic. Also, ensure the TextRenderingHint for the Graphics is AntiAlias.
As such, you should use one of these overloads, such as this one, which allow you to specify StringFormat.GenericTypograpic to get the required size.
Try this:
float fontHeight;
using (var g = textBox1.CreateGraphics())
fontHeight = g.MeasureString("W", textBox1.Font, new PointF(), StringFormat.GenericTypograpic).Height;
I'm developing an application to manipulate images scanned on a wide-image scanner. These images are shown as a ImageBrush on a Canvas.
On this Canvas they can a make Rectangle with the mouse, to define an area to be cropped.
My problem here is to resize the Rectangle according to the original image size, so that it crops the exact area on the original image.
I've tried many things so far and it's just sqeezing my brain, to figure out the right solution.
I know that I need to get the percent that the original image is bigger than the image shown on the canvas.
The dimentions of the original image are:
h: 5606
w: 7677
And when I show the image, they are:
h: 1058,04
w: 1910
Which gives these numbers:
float percentWidth = ((originalWidth - resizedWidth) / originalWidth) * 100;
float percentHeight = ((originalHeight - resizedHeight) / originalHeight) * 100;
percentWidth = 75,12049
percentHeight = 81,12665
From here I can't figure how to resize the Rectangle correctly, to fit the original image.
My last approach was this:
int newRectWidth = (int)((originalWidth * percentWidth) / 100);
int newRectHeight = (int)((originalHeight * percentHeight) / 100);
int newRectX = (int)(rectX + ((rectX * percentWidth) / 100));
int newRectY = (int)(rectY + ((rectY * percentHeight) / 100));
Hopefully someone can lead me in the right direction, because i'm off track here and I can't see what i'm missing.
Solution
private System.Drawing.Rectangle FitRectangleToOriginal(
float resizedWidth,
float resizedHeight,
float originalWidth,
float originalHeight,
float rectWidth,
float rectHeight,
double rectX,
double rectY)
{
// Calculate the ratio between original and resized image
float ratioWidth = originalWidth / resizedWidth;
float ratioHeight = originalHeight / resizedHeight;
// create a new rectagle, by resizing the old values
// by the ratio calculated above
int newRectWidth = (int)(rectWidth * ratioWidth);
int newRectHeight = (int)(rectHeight * ratioHeight);
int newRectX = (int)(rectX * ratioWidth);
int newRectY = (int)(rectY * ratioHeight);
return new System.Drawing.Rectangle(newRectX, newRectY, newRectWidth, newRectHeight);
}
I think the only reliable option is to let your users zoom in to the image (100% or higher zoom level) and make a selection on part of the image. This way they can make an exact pixel-based selection. (Assuming that the purpose of your selection rectangle is to select part of an image.)
Your problem now is that you're using floating-point calculations because of the 75% zoom level and rounding errors will make your selection rectangles inaccurate. No matter what you do, when you try to make a selection on a shrinked image, you're not selecting exact pixels - you're selecting parts of pixels as you resize your rectangle. Since a partial pixel cannot be selected, the selection edges will be rounded up or down so you either select one pixel too many or one pixel too few in a given direction.
Another issue that I just noticed is that you distort your image - horizontally it's 75% zoom, vertically it's 81%. This makes it even harder for users because the image will be smoothed differently in the two directions. Horizontally 4 original pixels will be interpolated on 3 output pixels; vertically 5 original pixels will be interpolated on 4 output pixels.
You are actually doing a form of projection. Don't use percentages, just use the ratio between 5606 and 1058,4 = ~5.30. When the user drags the rectangle, reproject it which is selectedWidth * 5606/1058.4.
I am looking for An ImageResizer Like below that supports MaxWidth & MaxHeight ...
where can i find it?
the below module does many other jobs that are not necessary for me.
just want to change format & support maxwidth and maxheight.
ImageResizer
You can write a wrapper that enforces the maximum width and maximum height, and maintains the aspect ratio.
For example, say you have an image that's 640 x 120 and your maximums are 1,920 x 1,440. Now, you want to make that image as large as possible, so you write:
ResizeImage(image, 1920, 1440)
If you were to do that, the aspect ratio would be shot.
You need to compute the aspect ratio of the existing image and adjust the values.
// Compute existing aspect ratio
double aspectRatio = (double)image.Width / image.Height;
// Clip the desired values to the maximums
desiredHeight = Math.Min(desiredHeight, MaxHeight);
desiredWidth = Math.Min(desiredWidth, MaxWidth);
// This is the aspect ratio if you used the desired values.
double newAspect = (double)desiredWidth / desiredHeight;
if (newAspect > aspectRatio)
{
// The new aspect ratio would make the image too tall.
// Need to adjust the height.
desiredHeight = (int)(desiredWidth / aspectRatio);
}
else if (newAspect < aspectRatio)
{
// The new aspect ratio would make the image too wide.
// Need to adjust the width.
desiredWidth = (int)(desiredHeight * aspectRatio);
}
// You can now resize the image using desiredWidth and desiredHeight
It doesn't matter if the library does more than what you need. If it does what you need it to, use it. The extra stuff isn't going to impair you at all.
I'm trying to figure out a good way to auto-size a Rectangle that has text drawn inside of it. I basically want the size to have a ratio of width/height and then "grow" according to that ratio to fit the text. I've looked at Graphics.MeasureString but I don't think it does what I'm looking for (maybe it does and I'm just using it wrong).
I don't want to specify a specific width of the rectangle to be drawn. Instead I want to say find the smallest width/height to fit this text given a minimum width but the found rectangle must have some specific ratio of width and height.
This doesn't have to be specific to C#, any idea for solving this problem I'm sure can be mapped to C#.
Thanks!
I believe you can use Graphics.MeasureString. This is what I have used in my GUI code to draw rectangles around text. You hand it the text and the font you want to use, it returns to you a rectangle (technically a SizeF object - width and height). Then you can adjust this rectangle by the ratio you want:
Graphics g = CreateGraphics();
String s = "Hello, World!";
SizeF sizeF = g.MeasureString(s, new Font("Arial", 8));
// Now I have a rectangle to adjust.
float myRatio = 2F;
SizeF adjustedSizeF = new SizeF(sizeF.Width * myRatio, sizeF.Height * myRatio);
RectangleF rectangle = new RectangleF(new PointF(0, 0), adjustedSizeF);
Am I understanding your question correctly?
You should use TextRenderer.MeasureText, all controls use TextRenderer to draw text in .NET 2.0 and up.
There is no unambiguous solution to your question, there are many possible ways to fit text in a Rectangle. A wide one that displays just one line is just as valid as a narrow one that displays many lines. You'll have to constrain one of the dimensions. It is a realistic requirement, this rectangle is shown inside some other control and that control has a certain ClientSize. You'll need to decide how you want to lay it out.
On the back of my comment about the System.Windows.Forms.Label, maybe you could have a look at the code driving the painting of a Label? If you use Reflector this should get you part of the way.
There seems to be some methods on there like GetPreferredSizeCore() for example that probably have what you want which I'm sure could be made generic enough given a little work.
I've found my own solution. The following code determines the best rectangle (matching the ratio) to fit the text. It uses divide and conquer to find the closest rectangle (by decrementing the width by some "step"). This algorithm uses a min-width that is always met and I'm sure this could be modified to include a max width. Thoughts?
private Size GetPreferredSize(String text, Font font, StringFormat format)
{
Graphics graphics = this.CreateGraphics();
if (format == null)
{
format = new StringFormat();
}
SizeF textSize = SizeF.Empty;
// The minimum width allowed for the rectangle.
double minWidth = 100;
// The ratio for the height compared to the width.
double heightRatio = 0.61803399; // Gloden ratio to make it look pretty :)
// The amount to in/decrement for width.
double step = 100;
// The new width to be set.
double newWidth = minWidth;
// Find the largest width that the text fits into.
while (true)
{
textSize = graphics.MeasureString(text, font, (int)Math.Round(newWidth), format);
if (textSize.Height <= newWidth * heightRatio)
{
break;
}
newWidth += step;
}
step /= 2;
// Continuously divide the step to adjust the rectangle.
while (true)
{
// Ensure step.
if (step < 1)
{
break;
}
// Ensure minimum width.
if (newWidth - step < minWidth)
{
break;
}
// Try to subract the step from the width.
while (true)
{
// Measure the text.
textSize = graphics.MeasureString(text, font, (int)Math.Round(newWidth - step), format);
// If the text height is going to be less than the new height, decrease the new width.
// Otherwise, break to the next lowest step.
if (textSize.Height < (newWidth - step) * heightRatio)
{
newWidth -= step;
}
else
{
break;
}
}
step /= 2;
}
double width = newWidth;
double height = width * heightRatio;
return new Size((int)Math.Ceiling(width), (int)Math.Ceiling(height));
}