Carrierwave difference between resizing options - image-processing

I am trying to understand the difference between resize_to_fill, resize_to_fit, and resize_to_limit.
Say I have two images. Image A is 500x300 and image B is 300x100
resize_to_fill 300 x 300
A - will just slice off 200 pixels of width?
B - will blow it up to 900x300 and then slice off 600px of width?
resize_to_fit 300 x 300
A - will shrink it down to 300x180?
B - will not change anything?
resize_to_limit -- not sure what the difference between this one and resize_to_fit is..
Can someone explain in a way that's easy to understand?

Related

Chop image into 4*4 tiles with Imagemagick

I am trying to figure out if it is possible to chop an image into 4*4 tiles equally (i.e so you create 16 images from every single image).
I know it is possible, but cannot figure out the command.
With ImageMagick you can use the "-crop" operator in several ways. To cut the image into 16 pieces, 4 tiles by 4 tiles, try this command...
convert input.png -crop 4x4# +repage output%02d.png
That will create 16 output images named "output00.png", "output01.png", etc. Keep in mind if the input image width or height is not evenly divisible by 4, the output images may not be identical dimensions. They will, however, always be plus or minus 1 pixel of the same.
To start numbering at 01 instead of 00, put "-scene 1" just before the name of the output.

Non-linear image scaling

Starting Situation:
I have a distorted image, for example a geographic map with a grid. The distortion is of that kind: At the top of the map 10° geographic latitude correspond to 30 px, but at the bottom of the image 10° latitude correspond to only 10 px.
Aim:
Now I want to scale the image, that 10° latitude correspond to let's say 20 px all over the image.
Let me illustrate the problem a litte more:
Starting situaiton: Image with an overall height of 100 px:
Area 1 - 30 px height
Area 2 - 25 px height
Area 3 - 20 px height
Area 4 - 15 px height
Area 5 - 10 px height
Aim: Image overall height stays constant (100 px), but now the areas should be of equal height:
Area 1 - 20 px height
Area 2 - 20 px height
Area 3 - 20 px height
Area 4 - 20 px height
Area 5 - 20 px height
If this can be achieved with other software than imagemagick, hints are welcome, too.
Thanks for your replies in advance.
Now I found out the tranformation function between my starting map and the map I desire:
f(y_px) = 200 (-0.5 + 0.01 * sqrt(150 + y_px))
This can be done by any fitting software.
Now I succesfully transformed the map using the "-fx" parameter and a 'custom matrix':
convert -monitor -size 100x100 xc: map-starting.png \
-virtual-pixel Black -interpolate NearestNeighbor \
-fx "xx = i ;
yy = 200 (-0.5 + 0.01 * sqrt(150+ j));
v.p{xx,yy}" \
map-aim.png
map-aim.png is what I wanted ;)
It's not possible to correctly rescale and reproject map images with just a raster image processing tool like ImageMagick. You need a tool that is capable of computing a proper image transformation taking into account the change of map projection. You will also need projection metadata about your image, either in the image itself (if it is some format like GeoTIFF) or with associated metadata header files if it is a raw raster format like PNG or JPEG.
I suggest you look at the Geospatial Data Abstraction Library GDAL. It is a library that contains command line tools to allow you to properly reproject and transform many kinds of raster map images.

imcrop matlab does not return right size

I want to use imcrop to crop images in matlab. But, sometimes it results the images which has one size more than what I want. Basically, my question is same as this.
http://www.mathworks.se/matlabcentral/answers/46737-how-do-i-make-the-imcrop-function-accurate-to-the-pixel
But, even this is not solved. Please help!
imcrop does return the "right size", i.e. the size specified in its documentation. A rectangle r1 = [20 20 40 30] is always not sometimes 21 by 11 pixels wide.
If your expectation of what the right size should be is different, you could index the rectangle differently. If you want a rectangle with pixel (20,20) as its upper left edge and 20 pixels tall and 10 pixels wide, you can specify r1 = [20, 20, 39, 29].
imcrop works like this because it operates on image data consisting of pixels. Pixels are being indexed, not points in space. Mathematically, a point has no width and no height, but a pixel has the width and height of one pixel.
To provide an extreme example, r2 = [5, 6, 8, 9] includes the pixels from row 5 to 6 and column 8 to 9, and is thus 2 by 2 pixels wide.
I could not really resolve the problem. But, I applied a simple work around. I used imcrop to crop with the desired sizes. And then resize the cropped image to desired size again.

RMagick changing image extents with gravity

I've got an image that i'd like to 'pad' with white space and centre.
In most cases I need to resize the image from 16 or 32 pixels up to 32 pixels.
If the image is 16 pixels, I want to add 8px of white space on each side, making it a 32 pixel image (with the original floating in the middle).
If it's a 32 pixel image, then nothing changes.
I'm using RMagick to do the conversion:
image.change_geometry!("#{size}x#{size}") { |cols, rows, img|
newimg = img.extent(cols, rows)
newimg.write("#{RAILS_ROOT}#{path}/#{name}.png")
}
Which is working OK, but the smaller images are in the top left of the new image, not centred.
I was looking at the gravity setting, it seems to be what I need, but I can't work out how to specify it in the call?
Thanks in advance.
Check the implementation of the following carrierwave function
http://rubydoc.info/gems/carrierwave/0.5.1/CarrierWave/RMagick#resize_and_pad-instance_method
This is a version of the above method by using only RMagick dependency
require 'RMagick'
include Magick
module Converter
def self.resize_and_pad(img, new_img_path, width, height, background=:transparent, gravity=::Magick::CenterGravity)
img.resize_to_fit!(width, height)
new_img = ::Magick::Image.new(width, height)
if background == :transparent
filled = new_img.matte_floodfill(1, 1)
else
filled = new_img.color_floodfill(1, 1, ::Magick::Pixel.from_color(background))
end
# destroy_image(new_img)
filled.composite!(img, gravity, ::Magick::OverCompositeOp)
# destroy_image(img)
# filled = yield(filled) if block_given?
# filled
filled.write new_img_path
end
end
The extent() method takes two more parameters, x & y offsets, which is where the image will be placed within the extent. If you're asking extent for a 100x100 image, for example, and your original is only 50x50, you'd do img.extent(100, 100, 25, 25) -- which would set the image to start at offset 25,25 (thus centering it).
NOTE: There's some issue with extent expecting to use negative offset values (in which case you'd want to do -25, -25) -- check this:
why is the behavior of extent (imagemagick) not uniform across my machines?

Rails Paperclip Plugin - Style Options for Resizing

So, I want to resize images to a FIXED width, but proportional height.
I have been trying a wide range of operators:
380x242#
380x242>
380!x242
380x242<
none of them have the desired effect. Any help? I want it to fill or resize to the 380 width, then resize / shrink the height by the same factor it used to shrink or resize the image to 380 wide.
Try using 380x
This should resize width to 380px and keep original aspect ratio.
For all available options for resizing images go here: http://www.imagemagick.org/script/command-line-processing.php?ImageMagick=lj6pre8q2iautc3ch6nuph1fc2#geometry
"#" is an argument used by Paperclip to know whether or not you expect the pic to be cropped. Using "100x100#" will scale and crop the picture exactly to that size. %#!<> are arguments in the Geometry String used by ImageMagick. One can use the following ImageMagick geometry strings for resizing images:
Ignore Aspect Ratio ('!')
Only Shrink Larger ('>')
Only Enlarge Smaller ('<')
Fill Given Area ('^')
Percentage Resize ('%')
Pixel Count Limit ('#')
According to the ImageMagick documentation for Image Geometry the geometry argument can be
scale% Height and width both scaled by specified percentage
scale-x%xscale-y% Height and width individually scaled by specified percent
width Height automagically selected to preserve aspect ratio
xheight Width automagically selected to preserve aspect ratio
widthxheight Maximum values of height and width given, ratio preserved
widthxheight^ Minimum values of width and height given, ratio preserved
widthxheight! Width and height emphatically given, ignore original ratio
widthxheight> Change only if an image dimension exceeds a specified dim.
widthxheight< Change only if both image dimensions exceed specified dim.
you can use , :show => '786>x447' for fixed width and prorortional height
The resizing options are limited but you can also use paperclip custom processors to resize images dynamically.
Railscasts has a good example of using a custom processor for paperclip, though his example allows a user to crop an image.
http://railscasts.com/episodes/182-cropping-images
You can calculate the height yourself:
newHeight = oldHeight * 380 / oldWidth

Resources