Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

resize without distorting (crop and pad) #88

Closed
dmarcelino opened this issue Dec 13, 2014 · 8 comments
Closed

resize without distorting (crop and pad) #88

dmarcelino opened this issue Dec 13, 2014 · 8 comments
Assignees
Milestone

Comments

@dmarcelino
Copy link

Hi @EyalAr, I've started using lwip today and so far I'm enjoying it a lot, thanks! My suggestions:

.resizeCrop()

The main reason I picked up lwip was for generating thumbnails which I think is a common use (e.g. #85). For that it's really useful to be able to resize and crop the image to the desired size. So I would like to suggest a:
.resizeCrop() or extending .resize() so it receives an options parameter that would allow to specify how to resize, e.g.: default | crop | pad.

Below is how I'm achieving this in my helper method:

  var widthRatio =  width / image.width();
  var heightRatio = height / image.height();
  var ratio = Math.max(widthRatio, heightRatio);

  image
    .batch()
    .scale(ratio)
    .crop(width, height)
    .exec(callback);

.resizePad()

Similar idea to resize and crop but, instead of cropping, padding the image with the desired color. I've also wrote a helper method for this but would be comfortable if lwip had native support. This suggestion may be the same request as Issue #68.

My helper method:

  var padX = 0;
  var padY = 0;
  var ratio;
  var widthRatio =  width / image.width();
  var heightRatio = height / image.height();

  if(widthRatio < heightRatio){
    ratio = widthRatio;
    var heightBeforePad = Math.floor(ratio * image.height());
    padY = (height - heightBeforePad) / 2;
  } else {
    ratio = heightRatio;
    var widthBeforePad = Math.floor(ratio * image.width());
    padX = (width - widthBeforePad) / 2;
  }

  image
    .batch()
    .scale(ratio)
    .pad(Math.ceil(padX), Math.ceil(padY), Math.floor(padX), Math.floor(padY), color)
    .exec(callback);

resizeProportional()

Just like resizePad() except it doesn't really pad. It produces an image that fits the desired size without distorting, cropping or padding.

  var widthRatio =  width / image.width();
  var heightRatio = height / image.height();
  var ratio = Math.min(widthRatio, heightRatio);

  image
    .batch()
    .scale(ratio)
    .exec(callback);

Using helper methods for these is fine but I think lots of people would like to have support for these straight out from lwip. Anyway, lwip is a great tool, regards.

@EyalAr
Copy link
Owner

EyalAr commented Dec 14, 2014

@dmarcelino thanks for this detailed proposal!

Those functionalities are definitely useful.

I'm wondering if it would be better to extend the existing resize( ... ) API, or to create two new methods as you suggested.

Any thoughts?

Thanks!

@EyalAr EyalAr changed the title Feature proposal: resize without distorting (crop and pad) resize without distorting (crop and pad) Dec 14, 2014
@EyalAr EyalAr added this to the v0.0.6 milestone Dec 14, 2014
@dmarcelino
Copy link
Author

Hi @EyalAr, thanks for considering my suggestions.

I believe the most elegant option would be to extend resize like:
image.resize(width, height, inter, params, callback)

The params would be optional and it would have several options, like:

  • method {String}: defaults to "default". Possible values:
    • "default" - Resizes the image to the specified size. Image may become distorted.
    • "proportional" - Resizes the image proportionally. One side of the image may be smaller than the inputted width or height.
    • "crop" - Resizes the image keeping it's proportion and cropping any excess.
    • "pad" - Resizes the image keeping it's proportion and padding any empty space with color.
  • color {String / Array / Object}: Optional Color of the padding used in method: "pad". See colors specification.

The text and options can certainly be improved but I think they describe what I'm aiming at.

PS: meanwhile I've added another helper method to by toolkit, resizeProportional(), I've included it in my original post above as it also explains the proportional option I've added.

@EyalAr
Copy link
Owner

EyalAr commented Dec 16, 2014

@dmarcelino
On second thought, perhaps it would be better to implement separate methods. I don't want to clutter resize with extra functionality.

I propose the following API additions (terminology borrowed from css):

  1. image.contain(width, height, color, inter, callback) - Contain the image in a canvas of size (width, height) with background color. The image will be resized to the largest possible size such that it's contained inside the canvas.
    • width, height - canvas' dimensions
    • color - canvas' color
    • inter - resize interpolation method
  2. image.cover(width, height, inter, callback) - Use the image to cover a canvas of size (width, height). The image will be resized to the smallest possible size such that both its dimensions are bigger than the canvas's dimensions. Margins of the image exceeding the canvas will be discarded.
    • width, height - canvas' dimensions
    • inter - resize interpolation method

Regarding resizeProportional - basically I think scale can suffice. It's trivial to find the correct scale...

@dmarcelino
Copy link
Author

On second thought, perhaps it would be better to implement separate methods. I don't want to clutter resize with extra functionality.

I thought that much, I think that's reasonable.

image.contain(width, height, color, inter, callback)
image.cover(width, height, inter, callback)

Good idea to borrow the terminology from CSS, I think those will do just fine.

Regarding resizeProportional - basically I think scale can suffice. It's trivial to find the correct scale...

Agreed.

EyalAr added a commit that referenced this issue Dec 17, 2014
EyalAr added a commit that referenced this issue Dec 18, 2014
@EyalAr EyalAr mentioned this issue Dec 18, 2014
@EyalAr EyalAr self-assigned this Dec 18, 2014
This was referenced Dec 18, 2014
@EyalAr EyalAr closed this as completed Dec 24, 2014
@dmarcelino
Copy link
Author

Nice! Thank you.

@EyalAr
Copy link
Owner

EyalAr commented Dec 25, 2014

Thanks for the suggestions and the discussion!

@rob2d
Copy link

rob2d commented Nov 17, 2015

would be nice to have a proportional resize regardless of the trivialities of it. We programmers live to remove these :)

@Bug-Reaper
Copy link

Yea came here because I needed proportional re-size. The behavior of contain is non-intuitive (I've never encountered a contain option that pads width + height) in CSS for example contain will shrink the image AND maintain aspect ratio, I believe this is the most common expected behavior.

While scale does work here, it'd be better to either make contain work as a resize-proportional (or add the option for such) and/or add a resize proportional method that maintains aspect ratio given a max width/height.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants