Enforcing a particular width on a scale? - image

We have the customer requirement that for a particular scale of an image ('teaser' scale) the width has to the always 160px independent of the image ratio. Specifying as (160,160)
scale does not work for images where the height is larger than the width. In this case 160px will be used.
Any idea how to ensure a fixed with of 160px in every case?

I used this scales in a site and it worked OK:
image_scales = {'thumb': (150,600), 'mini': (200, 800)}
The idea is to have a very long height so no matter the image ratio of the picture, it will always be 150 or 200 px width.

In Plone 4 there is an entirely new way of generating scales which can help with this problem. Using this approach you can tell it to scale the image 'down' instead of 'up', which means that it will scale the short side of the image to the specified size, rather than the long side (so the image ends up getting cropped, but always fills the specified area).
With this approach, you don't have to define the scales in your schema, but can simply include something like the following in your template. The scale will be generated on demand.
<img tal:define="scale context/##images"
tal:replace="structure python: scale.scale('image',
width=160, height=160, direction='down').tag()" />
See the plone.app.imaging page for more examples of this approach to scaling.

Related

What is the difference between cropping, resizing and scaling an image?

I am using Perl's
Image::Imlib2
package to generate thumbnails from larger images.
I've done such tasks before with several ImageMagick interfaces (PHP, Ruby, Python) and it was relatively easy. I have no prior experience with Imlib2 and it is a long time since I wrote something in Perl, so I am sorry if this seems naive!
This is what I've tried so far. It is simple, and assumes that scaling an image will keep the aspect ratio, and the generated thumbnail will be an exact miniature copy of the original image.
use strict;
use warnings;
use Image::Imlib2;
my $dir = 'imgs/*';
my #files = glob ($dir);
foreach my $img ( #files ) {
my $image = Image::Imlib2->load($img);
my $cropped_image = $image->create_scaled_image(50, 50);
$cropped_image->save($img);
}
Original image
Generated image
My first look at the image tells me that something is wrong. It may be my ignorance on cropping, resizing and scaling, but the generated image is displaying wrongly on small screens.
I've read What's the difference between cropping and resizing?, and honestly didn't understand anything. Also this one Image scaling.
Could someone explain the differences between those three ideas, and if possible give examples (preferably with Perl) to achieve better results? Or at least describe what I should consider when I want to create thumbnails?
The code you use isn't preserving the aspect-ratio. From Image::Imlib2::create_scaled_image
If x or y are 0, then retain the aspect ratio given in the other.
So change the line
my $cropped_image = $image->create_scaled_image(50, 50);
to
my $scaled_image = $image->create_scaled_image(50, 0);
and the new image will be 50 pixels wide, and its height computed so to keep the original aspect-ratio.
Since this is not cropping I've changed the variable name as well.
As for other questions, below is a basic discussion from comments. Please search for tutorials on image processing. Also, documentation of major libraries often have short and good explanations.
This is aggregated from comments deemed helpful. Also see Borodin's short and clear answer.
Imagine that you want to draw a picture (of some nice photograph) yourself in the following way. You draw a grid of, say, 120 (horizontally) by 60 (vertically) boxes. So 120 x 60, 720 boxes. These are your "pixels," and each you may fill with only one color. If the photo you are re-drawing is "mostly" blue at some spot, you color that pixel blue. Etc. It is not easy to end up with a faithful redrawing -- the denser the pixels the beter.
Now imagine that you want to draw another copy of this, just smaller. If you make it 20x20 that will be completely different, since it's a square. The best chance of getting it to "look the same" is to pick 2-to-1 ratio (like 120x60), so say 40x20. That's "aspect-ratio." But there is still a problem, since now you have to decide all over again what color to pick for each box, so to represent what is "mostly" on the photo at that spot. There are algorithms for that ("sampling," see your second link). That's involved with "resizing." The "quality" of the obtained drawing clearly must be much worse.
So "resizing" isn't all that simple. But, for us users, we mostly need to roughly know what is involved, and to find out how to use these features in a library. So read documentation. Some uses are very simple, while sometimes you'll have to decide which "algorithm" to let it use, or some such. Again, what I do is read manuals carefully.
The basic version of "cropping" is simple -- you just cut off a part of the picture. Say, remove the first and last 20 columns and the bottom and top 10 rows, and from the initial 120x60 you get a picture of 80x40. This is normally done when outer parts of an image have just white areas (or, worse, black!). So you want to "cut out" the picture itself from the whole image. Many graphics tools can do that on their own, by analyzing the image and figuring out those areas. Or, we select and hit a button.
I'm still not certain that you understand the difference between these terms
Your original image is 752 × 500 pixels
Resizing is a vague term that just means making a picture a different size somehow
Scaling is to change the size of an image proportionally. Scaling your picture down by a factor of ten would result in an image 75 × 50 (it should be 75.2 but we can't have 0.2 of a pixel). Scaling it up would make it bigger
You have scaled your picture to 50 × 50 pixels, which is a vertical scale of 10 (500 ÷ 5) but a horizontal scale of 15 (752 ÷ 50), so it appears squashed horizontally (or stretched vertically)
Cropping is to reduce an image by removing parts of it. To crop your image to 50 × 50 you would choose a 50 × 50 rectangle out of the whole picture and remove the rest. It would be a piece about the size of your monkey's nose, but you can pick any region you wish
zdim has shown you how you can call
$image->create_scaled_image(0, 50)
so that the height, or y-dimension, is reduced to 50, while the width, or x-dimension, is scaled by the same factor. That will result in a thumbnail 75 × 50 as above
I hope that helps
As I said in my comment, there is an
Image::Magick
Perl module if you would prefer to be back on familiar ground
Resizing and scaling is the same; you just change the size of the image. You can make it smaller or bigger.
Depending on the interface, you have to give either the new dimensions or a scaling factor for the operation. A factor less than or greater than 1.0 would make the image smaller or bigger. Smaller images are created by subsampling and bigger images by interpolation.
Cropping is very simple. You select a rectangular region of an image and that's your new image. It's like using scissors.
In your code example the image is named cropped_image although it is created through scaling, or resizing.
The output image is an image of size 50 x 50 pixels. That's what you did here:
my $cropped_image = $image->create_scaled_image(50, 50);
So no matter how your image looks before, you stuff it into 50 x 50 pixels. In this case not only reducing the resolution but also changing the aspect ratio.
The image is not displayed improperly, it's displayed perfectly fine.

Obtaining the ratio difference of two images

I have an image of the size 640*640*3, while another image of the size 125*314*3. I want to obtain the size ratio of the second image to the first image, but I can't find a way to do it.
I have tried the traditional divide method, as well as using rdivide but both are not working.
If I use the traditional approach of multiplying the image 3D values first, then compare, will the approach be correct?
For example, I would do something like 640*640*3 = 1,228,800 then 125*314*3 = 117,750 and finally, take 117,750 / 1,228,800 = 0.09. Is 0.09 the right answer?
I'm assuming you are referring to the ratio of the areas between the two images. If this is the case, just use the width and height. This looks like you are using RGB images, so don't use the number of channels. However, the number of channels cancels out when you use them in finding the ratio.
Therefore, yes your approach is correct:
(125*314) / (640*640) = 0.0958
This means that the smaller (or second) image occupies roughly 9.5% of the larger (or first) image.
That depends what you mean by size ratio.
Looks like you have RGB images, so if you mean the area, then it is (640*640)/(125*314), if you mean the height, then it is 640/314, more options too, be more specific in your question.

using get_serving_url() to resize SMALLER dimension (width or height) to a specific integer

I'm trying to use get_serving_url() to serve up thumbnails, but I need those those thumbnails' smaller dimension (could be width OR height) to be a certain number so that there won't be any gaps in its container div. According to the docs, the "size" argument for get_serving_url will adjust the LONGEST dimension to a given parameter. This might cause the opposite dimension to go below my required size. How can I fix this?
If you have the dimensions of the bitmap you can request a size that is larger than your smallest value by the factor of the image aspect ratio.
For example if the image is 1600x1200 and you want the thumbnail to be at least 32 pixels in in dimension, the size should be 43 (32*(1600/1200)) and the resulting image will be 43x32.
In order to get the image size you need to load the image date into the image class and use the width and height properties.
There's no way to do this currently; you will have to fetch the dimensions of the image and calculate the size of the longer size accordingly. You probably should do this anyway, or a 1x1000 image will break things for everyone.

How to resize the image width and height with same quality in Corona SDK?

I want to re-size the image for example say 1000 * 1000 to 100 * 100. And I want to display full image after resizing it. Please can anyone help me?
To scale display objects in Corona either use the scale() command or manipulate the xScale and yScale properties:
http://developer.anscamobile.com/node/2452
Note however that the scaling will look best if the image sticks to power of two divisions. That is, 1/2 size, 1/4 size, etc.
For fast animations (eg. the object transitions away over half a second) the exact scaling you describe would look fine, but otherwise I'm wondering why you would want to do that in Corona (as opposed to scaling the image in Photoshop and simply having a smaller image to begin with.)
It'd be best to create an image of a larger size than you'd like to display. This will preserve the quality. For example you have an image with dimensions of 100x100 and you'd like it to display as a 20x20 image. Do the following:
local IMAGE = display.newImageRect("IMAGE.png", 20, 20)

Web Layouts: pixels vs percentages

What are the use cases for defining distances in a web layout for pixels and percentages?
Is there any downside to using pixels with respect to multiple resolutions? Will they scale correctly?
Percentage layout
This is generally referred to as fluid layout. Your elements will take a defined percentage of the total space available to them. This available space is determined by the element's parent.
When using percentage layouts, it's a good idea to specify a min-width and max-width on your design so that it remains usable at very low and high resolutions.
Pros
Scales with screen size, therefore get to use more space if it's available.
Cons
Makes it more difficult to know the exact position of something on screen. As a result, it can make creating precise layouts more difficult.
Can lead to unexpected layouts if child elements are fixed width (i.e. an image) and end up being larger than their fluid width parent.
Pixel layout
This is usually known as fixed layout. Your element will always be the same defined pixel size and will not take available parent space into account.
Pros
Always know an element's exact size.
Creating precise layout is easier.
Cons
You don't scale with resolutions. Your layout will always be the same width, making for wasted space when people have high resolutions.
I'll reply to this one by telling you a true story.
We had a client which wanted a map view, made up of divs.
Suddenly, he decided he wanted zooming as well.
I had to change all those fine-grained pixel positions to percentages.
Causing the wrapping div to change width/height (in pixels) relatively, we got a nice and reasonable zooming effect.
NB: During design phase, I quickly drew up a prototype, I'm going to look it up for you...
Edit: Nope, nothing found, sorry.
For percentages you have to have a base value, so it would be something like an image that has a size set outside of the CSS, if you just use a percentage on a DIV, for example, it wouldn't have anything to base that off of except the actual size it was by its being filled with text, for example, so it would not be practical to use percentages as a way to size it as it would rarely produce the desired output, if you are re-sizing something with a pixel size, such as by using javascript, you could resize by a percentage that would resize the original value (in pixels)
They do different things.
Pixel values always relate to hypothetical pixels on the output device.
Percent values relate to the computed size of the containing block (for block elements) or the containing block's font size (for font sizes).
Em and pt values relate to the current font size.
If you want your item to scale with its container, use percentages. If you want it to scale with font size, use ems. If you don't want it to scale at all, use pixels.
And then there's IE6; whoever 'implemented' CSS in that thing obviously had no idea what the various CSS properties were supposed to do.
Be careful using percentages, webkit browsers don't calculate percentages correctly. It's all because webkit doesn't calculate subpixels correct.
Detailed information about this issue can be read here: Percentage bugs in webkit
I would recommend you to always use pixels to don't have any layout dimensions differences between browsers.

Resources