Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best resize and or crop logic

I've come across this a few times and thought it would be good to put it out there. What's your best image resize and/or crop logic. The idea being that some method is called with a target image, dimensions and a crop flag - this would return or save off or whatever the desired image.

Mine is below. Converted from VB to C# so yes there'll be small bugs but logic is what we're looking at.

// INIT
// On/off
bool WeAreCropping = true;

// Get some dimensions
int TargetWidth = RequestedWidth;
int TargetHeight = RequestedHeight;
int SourceWidth = SourceImage.Width;
int SourceHeight = SourceImage.Height;
int ResizeWidth = TargetWidth;
int ResizeHeight = TargetHeight;

// GET RESIZE VALUES
// Are we cropping?
if (WeAreCropping) {

    // Get source and target aspect ratio
    double SourceAspectRatio = SourceWidth / SourceHeight;
    double TargetAspectRatio = TargetWidth / TargetHeight;

    // Compare aspect ratios to find out if we should we resize by 
    // width or height or nothing
    if (TargetAspectRatio < SourceAspectRatio) {
        ResizeWidth = TargetHeight / SourceHeight * SourceWidth;
    }
    else if (TargetAspectRatio > SourceAspectRatio) {
        ResizeHeight = TargetWidth / SourceWidth * SourceHeight;
    }
    else {
      // Same aspect ratio
    }


}
else {

    // If the target image is bigger than the source
    if (TargetWidth > SourceWidth && TargetHeight > SourceHeight) {
        TargetWidth = SourceWidth;
        TargetHeight = SourceHeight;
    }

    double Ratio = 0;

    // What ratio should we resize it by
    if (SourceWidth / TargetWidth > SourceHeight / TargetHeight) {
        Ratio = SourceWidth / TargetWidth;
    }
    else {
        Ratio = SourceHeight / TargetHeight;
    }

    ResizeWidth = Math.Ceiling(SourceWidth / Ratio);

    ResizeHeight = Math.Ceiling(SourceHeight / Ratio);
}

// TIME TO DO SUMFINK
// Resize the image using ResizeWidth and ResizeHeight
// Do it

if (WeAreCropping) {
    // Crop the resized image at the center TargetWidth and TargetHeight
    // Do it
}

I suspect this could be much more elegant so maybe you could do better.

like image 239
Maleks Avatar asked Oct 26 '09 18:10

Maleks


1 Answers

I'd say you should utilize standard geometry types like Rectangle and Size. Then you should probably also support a use case, when the caller wants to fit the image in some larger rectangle, but still wants to keep the original image sizes ratio.

One way to implement the resizing you can find here.

like image 173
Max Galkin Avatar answered Sep 23 '22 08:09

Max Galkin