Here's the problem. I have a picture that will have a different Height every time according to the picture that's loaded.
I'd like to scale that picture so it fits inside of the document which has 800 pixels height. So if the image has 2560px in height, I need to find out the PERCENTAGE needed to bring that pixel height down to 750 so it fits snuggly on the page.
I'm stuck trying to find the formula for this simple enough problem.
Here's my code:
iTextSharp.text.Image pic = iTextSharp.text.Image.GetInstance(
image, System.Drawing.Imaging.ImageFormat.Jpeg);
if (pic.Height > pic.Width)
{
//Maximum height is 800 pixels.
pic.Height formula goes here....
}
else
{
//Maximum width is 600 pixels.
pic.Width formula goes here....
}
Some number p is such that p * 2560 = 750. Therefore, p = 750 / 2560 = 0.29296875.
Of course, make sure that you do floating-point division.
The rule of three will help you sort it out.
I don't know if I understand your problem exactly. Do you mean something like this?
percentage = (frameHeight / picHeight) * 100
Example:
(750 / 2560) * 100 = 29
That means: 2560 * 0.29 = 750
Here x is the maximum desired height, y is the actual image height and p is the percentage.
p = x / y;
x = p * y;
y = x / p;
Given any two you can find the other.
Related
I have an array of points which all range from x(0-512) and y(0-384) which means an aspect ratio of 4:3.
If I want to display every points, perfectly, on a 16:9 monitor, what math would be needed to achieve this?
Let's say "ee" is my 4:3 point and "point" is the 16:9 point I need..
I thought since I'm trying to scale it on a 1920:1080 monitor, which is a 16:9 aspect ratio
point = new PointF(ee.x * (1920 / 512), ee.y * (1080 / 384));
But this seems to be off by abit.
Any help? Thanks.
You can't match exactly the aspect other than by multiplying each dimension by an integer. Here the only integer that would fit is 2 (cause 384 * 3 > 1080)...
so you would have to do:
point = new Point (ee.x * 2, ee.y * 2);
and you could center it with:
point = new Point (ee.x * 2 + ((1920 - 512*2)/2), ee.y * 2 + ((1080 - 384*2)/2)));
Hope that helps...
Edit: with floats, you have to take the minimum of the multiplier:
var multiplier = Math.Min(1920.0/512, 1080.0/384);
point = new Point (ee.x * multiplier + ((1920 - 512*multiplier)/2), ee.y * multiplier + ((1080 - 384*multiplier)/2)));
Could you elaborate what you mean by "off"?
If you mean that the image looks stretched horizontally, it is because the aspect ratio is larger than before. If you want the image to look like what it was before (but bigger), you'll need to scale one axis by the aspect ratio to fix it.
aspect_ratio_before = 4.0f / 3.0f;
aspect_ratio_after = 16.0f / 9.0f;
// This is equal to 4/3.
aspect_ratio_difference = aspect_ratio_after / aspect_ratio_before;
// I squish the X axis here.
point.x /= aspect_ratio_difference;
// Alternatively, you can also multiply point.y by the
// aspect_ratio_difference, though that will stretch the Y axis instead.
// Use only one!
// point.y *= aspect_ratio_difference;
Disclaimer: I have not worked with .net before, so I don't know all the details of its rendering engine. This is based off my experience working with OpenGL and scaling.
how i can compare 2 images in c# suppose
imageA size 1024x640
imageB size 320x480
i want to know how i can get percentage of size imageb like
image B is nn% smaller than imageA
i did this but want to know if i am doing it right???
image A total pixels 655360 (1024x640)
image B total pixels 153600 (320x480)
so
string ImageBSize= (153600/655360)*100 +" smaller then imageA";
Assuming you're using System.Drawing.Image or System.Drawing.Bitmap, you could just request the 'Size' property of each of the images. The 'Size' is divided in 'Height' and 'Width'. Calculate 'Height * Width' for each of the images and then you can calculate the ratio between the 'Sizes' of both images.
Image imageA = new System.Drawing.Image("ImageA.png");
Image imageB = new System.Drawing.Image("ImageB.png");
double imageASize = imageA.Size.Height * imageA.Size.Width;
double imageBSize = imageB.Size.Height * imageB.Size.Width;
string ratio = string.Format("Image B is {0}% of the size of image A",
((imageBSize / imageASize)*100).ToString("#0"));
Your algorithm is correct, but be careful that you cast (or assign) your values to doubles before you perform the division, otherwise you will get integer division which will always result in 0 if imageB is smaller than imageA.
You could do it in one line like this:
string ImageBSize = (((double) 153600 / 655360) * 100) + " percent smaller than imageA";
But it would be more readable and maintainable if you broke up your statement into smaller, clearer statements:
double imageASize = imageA.Size.Height * imageA.Size.Width;
double imageBSize = imageB.Size.Height * imageB.Size.Width;
double percentBIsSmaller = (imageBSize / imageASize) * 100;
string result = String.Format("B is {0:F2} percent smaller than A");
This would result in output like this:
B is 12.5 percent smaller than A
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.
If we have 2 same images. One is small and one is big. Now we have x y value on small image
then how we will map it on the same position on big image. Can anyone tell me with formula?
I'd imagine you'd just scale it:
int bigX = smallX * (bigWidth / smallWidth);
int bigY = smallY * (bigHeight / smallHeight);
Note that you may wish to use floating point arithmetic to avoid integer arithmetic issues:
int bigX = (int) (smallX * ((double) bigWidth / smallWidth));
int bigY = (int) (smallY * ((double) bigHeight / smallHeight));
Simply use proportions.
Point bigpoint = new Point((int)(smallpoint.X * bigwidth/smallwidth),
(int)(smallpoint.Y * bigheight/smallheight));
// Assuming that Point smallpoint is the pixel of small image
I want to increase the size of my rectangle by 10 pixels. The following code seems not working. Assume sampleRect is my rectangle. Please let me know.
Rectangle temp = new Rectangle(
sampleRect.X - 10,
sampleRect.Y - 10,
sampleRect.Width + 2*10,
sampleRect.Height + 2*10);
It will work, but you can write the same thing more elegantly using the Inflate method:
rect.Inflate(10, 10);
One important difference between your approach and Inflate method is that you create a new rectangle instance, while Inflate modifies an existing rectangle.
I'm not sure why you would ask "will this work" - try it!
However,
someRectangle.Inflate(10,20);
//or
someRectangle.Inflate(10);
should work
Depending on your definition of "grow by 10 pixels", here is what I would do:
int size = 10;
int halfSize = size/2;
Rectangle temp = new Rectangle(
sampleRect.X - halfSize,
sampleRect.Y - halfSize,
sampleRect.Width + size,
sampleRect.Height + size);
The code you have will make a new Rectangle at x,y -10 compared to the sampleRect. To compensate you increase the Width and Height with 20.
I assume you are trying to increase the rectangle around the center, in that case you need to move the rectangle half of the new increase.
Example:
var sizeIncrease = 10;
var newX = sampleRect.X - 0.5 * sizeIncrease;
var newY = sampleRect.Y - 0.5 * sizeIncrease;
var newWidth = sampleRect.Width + sizeIncrease;
var newHeight = sampleRect.Height + sizeIncrease;
These values should give you what you are looking for
Rectangle.Inflate will also change the size around the center.