Simple Version
Create a version of the imagecache scale action where the "Allow upscaling" checkbox changes to be a 3 value radio button:

  1. Never
  2. If within x pixels of specified size
  3. Always

Where x is a text input field. If the uploaded image dimensions fall within x of the specified size then the image should be upscaled to be the specified dimensions.

General Version
Allow the definition of a number of preset image sizes (x and or y dimensions). With each size allow an inner and outer snap radius. The inner snap radius allows the image to be upscaled to that preset size and the outer snap radius allows it to be downscaled. When processing an image:

  1. If the image size does not fall within the snap radius of any preset size leave it unaltered
  2. If the image falls within the snap radius of one preset size scale it to fit within the bounding box of that size
  3. If the image falls within more than 1 snap radius determine the closest size and scale it to fit within that size
  4. The outer snap radius of the largest size is considered to be infinite

Comments

dman’s picture

Ouch.
I can see where you are going with this (pretty clear description) but what a headache!

- It'll need to support both scale and scale+crop
- the radiuses you mention are probably overkill, if it can be done with maths instead
- What I can't figure is how to deal with snapping of both width and height, or cases where one but not another dimension is given. Really flaky heuristics.

In the actual case, you probably just want to switch between two (maybe three) presets, so probably be best to use customactions, some code specific to your actual task, and pass off to a chosen preset the way that the aspect switcher does. :-/

yellek’s picture

You can see the problem I am trying to solve on http://www.hopevalleyuc.org.au/content/women-hope. On that page the image is floated left and set not to scale up. I want to guarantee a minimum width for the text whilst still having it wrap around the image if the image is small enough. The simple version of the feature would do this.

Width and height won't be too bad if you calculate the "distance" from an ideal size by adding the absolute values of the x and y differences in size. Also I'm probably more interested in scaling than cropping as if you can crop the image the situation I am trying to solve becomes less of a problem.

yellek’s picture

I've had a bit of a think about how the algorithm would work and, as I'm not a PHP developer, I present it here in pseudo code.

boolean function within_snap(image, boundingBox, insideSnap, outsideSnap) {
    if (((image.x >= (boundingBox.x - insideSnap)) 
        && (image.x <= (boundingBox.x + outsideSnap)))
        || ((image.y >= (boundingBox.y - insideSnap)) 
        && (image.y <= (boundingBox.y + outsideSnap)))) {
        return true 
    } else {
        return false
    }
}

int function distance(image, boundingBox) {
    return abs(image.x - boundingBox.x) + abs(image.y - boundingBox.y)
}

for each boundingBox {
    if (within_snap(image, boundingBox, insideSnap, outsideSnap) {
        scale = true
        add bounding box to candidateList
    }
}

if (scale) {
    for each boundingBox in candidateList {
        add distance(image, boundingBox) to distanceList
    }
    scale image to fit inside boundingBox with max distance in distanceList
}

I'm not so hot on the UI side so a UI to capture the bounding boxes as well as the inside and outside snap would have to be devised.

Does this algorithm seem feasible?

fietserwin’s picture

Version: » 7.x-1.x-dev

Assigning a version. If we implement it, it will be in 7.x-1.x.

fietserwin’s picture

Issue summary: View changes
Status: Active » Closed (won't fix)

I guess this is:
- To specific
- To much detail to specify (cluttered UI)
- Relatively easy done with a custom action that fills the data for a resize/scale effect and calls that effect.

So tagging as won't fix.