I'm not sure how to ask this question in words without it becoming very confusing. So I'll provide point form data to try and relay my issue.
I've taken screenshots of the same image at different screen resolutions.
This results in the image having different widths & heights.
[]
img1.png
resolution = 1024×768
aspect ratio = 4:3
image = 43x43 pixels
img2.png
resolution = 1280×1024
aspect ratio = 5:4
image = 57x57 pixels
img3.png
resolution = 1920×1080
aspect ratio = 19:9
image = 60x60 pixels
img4.png
resolution = 3440x1440
aspect ratio = 21:9
image = 80x80 pixels
[]
we are given ONLY one of these four images
we also have a different resolution then this image
now find image = ??x?? pixels
[]
For sake of argument we have img3.png. Then change our resolution to 1280x1024. From here I can't figured out how to resize img3.png so that it knows it need to scale down to 57x57 instead of 60x60
i could hard code
4:3 = 0.716
5:4 = 0.95
21:9 = 1.33
then i could use 60*0.95 = 57
but i'm stubborn and want to be able to do this dynamically
[]
the reason behind this is so i can do an image search on different resolutions
I assume the same square image is displayed on different screen resolutions, and based on some logic, it is shown a little bigger or smaller. Now your problem is, what's that logic?
Since it is always square, so it is not related to the aspect ratio. Then I guess the logic is trying to fit a square area, probably holding multiple of your small square image, to the rectangular screen. Since all these screens are landscape, then I would like to test the heights of each screen:
768:1024:1080:1440 = 0.533:0.711:0.75:1,
43:57:60:80 = 0.537:0.712:0.75:1
Got it? It's just scaled proportional to the height of the screen!
Related
I'm trying to upload images and have them fit into different sized boxes....To give you an idea of what the application does: People upload images and have them printed onto posters.
For example, we'd have a poster size of 8" x 10"(live area) and the full size is 9.5" x 11.5", since the minimum DPI is 100, we typically multiple the 8x10 by 100 = 800x1000.
Here's an image explaining that I have an original image(http://i.imgur.com/Uds9rcZ.jpg) and need it to fit accordingly to the different sizes.
I may need to clarify this a bit, so ask questions if needed.
Thanks.
Canvas's context.drawImage has a version which allows you to scale an image while you are drawing it to the canvas.
If you resize disproportionally (like you do in your example) some of your resized image will fall off the canvas. Then your kitty will look distorted (in your example: stretched vertically)
This sample code resizes proportionally by using only the width. This way your kitty is not stretched.
// calculate how much to scale the resulting image
var originalWidth=16;
var originalHeight=20;
var desiredWidth=20;
var scalingFactor = desiredWidth/originalWidth;
// scale the original size proportionally
var newWidth=originalWidth*scalingFactor;
var newHeight=originalHeight*scalingFactor;
// resize the canvas to fit the desired image size
// Note: canvas is a reference to your html canvas element
canvas.width=newWidth;
canvas.height=newHeight;
// Draw the image to the canvas
// This version of drawImage allows you to scale the original image
// while you are drawing it to the canvas.
context.drawImage(
originalImage,
0,0,originalWidth,originalHeight,
0,0,newWidth,newHeight);
I would like to suggest you use the easyCanvas library to do this. The reason for this is that the built-in drawImage method of context do not scale the image proportionally for you, and it involves a small dose of math to get it right, especially in cases where destination shape differs from original and you want it to cover the whole area.
I made a method in this library to handle situations such as these allowing you to draw the original image proportionally into any shape even if the shape doesn't correspond with the original.
See this demo for an live example.
In essence what you do is to draw your uploaded image into the canvas with this method:
ez.drawImageProp(image, x, y, width, height);
where width and height would be that of destination.
It also has offset parameters so you can move the image around within that shape where an offset of 0.5 is center, 0 is from left and 1 is from right:
ez.drawImageProp(image, x, y, width, height, offsetX, offsetY);
Assuming image is already available all you need to do is:
var ez = new easyCanvas('canvas'); /// provide ID of existing canvas
ez.drawImageProp(image, 0, 0, ez.width, ez.height);
Disclaimer: I am the author of easyCanvas. easyCanvas is open-source (GPL3.0 license).
What happens with the code below is that image width is scaled to 100% as expected and the height also scales as expected keeping the aspect ratio correct. Issue is that there is a margin at the bottom and that seems to be the height of the original contentHeight of the image. How can I get rid of that?
I am using percentages so that it scales when device orientation changes.
backdrop.source = "http://cf2.imgobject.com/t/p/" + "w342" + data.backdrop;
backdrop.scaleMode = "letterbox";
backdrop.horizontalAlign = "left";
backdrop.verticalAlign = "top";
backdrop.smooth = true;
backdrop.percentWidth = 100;
The answer to your question is don't use the letterbox setting. That is going to preserve the aspect ratio and make the black area, hence the name letterbox :)
Try setting scaleMode to zoom instead. As the documentation states, zoom will result in one axis being clipped. This should scale the image, preserve the aspect ratio, but clip some edges of the image to avoid having the black area.
Other solutions to this problem are:
modify the original image outside of Flash
use a mask to achieve similar results that the zoom setting will provide. In this approach you make the image bigger, but then apply a square mask to the image. The mask reveals only the square portion ... clipping what is outside the mask.
(undesirable in most cases) use the scaleMode setting of strectch (and specify both width/height) so that the area is filled, this will not preserve the aspect ratio
PS: There is no way to avoid the black area if the image's aspect ratio is not square. Even with HTML/CSS. This is just math/geometry. The same thing happens in HTML -- the image is either stretched, clipped, or will not fill both dimensions.
[Edit]
PPS: One other idea, if you know the original aspect ratio of the image, is to calculate a new width that will be closest to the desired width, but naturally preserves the width to height aspect ratio.
For example, the width:height ratio is 4:3. Your desired width is 500 pixels. Using cross products you get this:
4 500
- = -
3 x
Using cross products you get the equation:
4x = 3*500
Now solve for x:
x = 3*500/4 = 375
Therefore, if the original aspect ratio is 4:3, you can set a width of 500 and a height of 375 to scale the image and not have any black areas. You can even write code that dynamically calculates the aspect ratio, and applies this logic to scale something nicely. The point is that you have to the respect aspect ratio when scaling the image to avoid the "black" areas.
I have a RGB image. I have scanned the image. So the image occupies a small portion of an A4 size sheet.
I want to find the border of the image and crop it. I could use edge detection operators like 'Sobel' etc, but they detect all the edges present in the image. All I want is the border of the image. Also many of the edge detection functions including 'bwboundaries' work only with binary or grayscale images. My image is RGB.
I tried using 'imcrop', but this is more of interactive cropping. I am keen on doing this automatically.
Uploading a test image:
Since this is an rgb image, there will be apparent color in the gray areas, but there should be none in the white ones. You can make use of this to find the image, then you can get the bounding box.
img = imread('http://i.stack.imgur.com/dEawA.jpg');
%# instead of "==" you can check for similarity within a tolerance
tt=img(:,:,1)==img(:,:,2) & img(:,:,2) == img(:,:,3);
%# invert tt so that it's 1 where there is signal
tt = ~tt;
%# clean up some of the smaller artifacts
tto = imopen(~tt,strel('square',100));
%# get the areas and bounding box of the areas above threshold
%# as an additional criterion, you could also use excentricity
%# or you could simply remove the bottom 100 rows of the scan
stats = regionprops(tto,'BoundingBox','Area');
area = cat(1,stats.Area);
[~,maxAreaIdx] = max(Area);
bb = round(stats(maxAreaIdx).BoundingBox);
%# note that regionprops switches x and y (it's a long story)
croppedImage = img(bb(2):bb(2)+bb(4),bb(1):bb(1)+bb(3),:);
There is a bit of a border left due to rotation. You can use the mask tto above to set all non-image pixels to NaN before cropping, or you can use imrotate to fix your image.
You can try to detect the corners of your image using e.g. the Harris-Detector (corner in Matlab). Set the maximum number of corners to detect to 4. Then use the positions of the corners in imcrop. If you would post an image I could give you more specific hints. Your image being RGB shouldn't be a problem, just convert it to grayscale.
You can try using bwlabel http://www.mathworks.com/help/toolbox/images/ref/bwlabel.html (along with find, as noted in the help page) to get the indices of the image and use those to crop the original.
You'll first need to convert the original image to binary using im2bw http://www.mathworks.com/help/toolbox/images/ref/im2bw.html.
I'm struggling to find the right approach to resize and crop and image, with a focus area. In my case the focus area is a face detected in the image, and I need to make sure that this area is visible in the cropped version.
I have focus area given by eg. face_height, face_width, face_center_x and face_center_y. These values are percentages of dimensions of the original image.
What I want to do, is getting a eg. 60x60 thumbnail. The normal approach would be to resize so either height or width of the image is equal 60px and then crop a 60x60 from center, like this:
mogrify -resize 60x -gravity 'Center' -crop 60x60 image.jpg
What approach can be taken focus my crop around a given area instead?
I'm thinking of a solution that includes several paths:
If the face area is bigger than the wanted thumbnail, resize the image just enough to make the whole face visible in 60x60 pixels, then crop
If the face area is smaller than the wanted thumbnail, then crop "expand" my face area until my wanted thumb can fit inside the area. Then crop. I guess I need to make sure that this doesn't exceed the bounds of the original image.
Is there a smarter approach? Can you try make some example code?
Thanks!
I'd first do the arithmetic in script or program, then feed exact coordinates to ImageMagick.
The arithmetic steps:
It'll be easier to operate with exact pixel values than percentages, so convert face_height, face_width, face_center_x and face_center_y to pixel values.
You'll want rectangular thumbnail, so pick the longest side and operate with that:
longest_side = max(face_height, face_width)
Now you can calculate top left point for your crop:
crop_x = face_center_x - longest_side / 2
crop_y = face_center_y - longest_side / 2
If any of the four crop corners fall outside your picture dimensions, adjust for that:
crop_x and crop_y should both be >= 0
crop_x + longest_side should be less than image width
crop_y + longest_side should be less than image height
Having calculated these, ImageMagick call gets quite straightforward:
mogrify -crop {longest_side}x{longest_side}+{crop_x}+{crop_y} -resize 60x60 image.jpg
I am confused in deciding the dimensions for a background image for my website. I am creating a collage like image in picasa and it defines the image dimensions using aspect ratios. If I want to create an image of 2048 x 1800, what aspect ratio should I use?
Wolfram Alpha gives the exact result 256/225, so an aspect ratio of 256:225 is correct. (Of course, a more inexact value would be 1.14:1, which would give you something like 2052x1800.)
As the aspect ratio is the ratio of the width of the image to its height, the aspect ratio of 2048x1800 image is 1.14:1 (2048/1800 = 1.14).