Jump to content

Help needed calculating aspect ratio


rockstock

Recommended Posts

Hi. Firstly I must apologise for my complete lack of PHP and mathematical ability!

 

I've acquired some code that aims to return pixel dimensions according to the aspect ratio of an original image. So where I set my prices, I have specified a maximum width and height for each price option. The code works in that it's displaying the dimensions where I want them, but the maths seems off. In the attached screenshot, 'Original' is the correct dimensions, but the others that are calculated from this do not conform to the original's ratio. In this example, the widths are what I've specified in my pricing, so the heights are what have been calculated.

 

Below is the code I was supplied, I'd be very grateful if someone could tell me what's wrong with the maths here.

 

private $rockstock_original_image_size = null;

private function rockstock_get_original_image_size( $post_id, $attachment_id ) {       if ( is_null( $this->rockstock_original_image_size ) ) {
               $this->rockstock_original_image_size = Sell_Media()->images->get_original_image_size( $post_id, $attachment_id );       return $this->rockstock_original_image_size;
private function rockstock_correct_width( $post_id, $attachment_id, $width, $height ) {       $original_size = $this->rockstock_get_original_image_size( $post_id, $attachment_id );       if ( $original_size['original']['width'] > $original_size['original']['height'] ) return $width;       if ( $original_size['original']['height'] > $original_size['original']['width'] ) return ceil($width * $height / $original_size['original']['height'] );       return $this->rockstock_correct_square( $width, $height );

}

private function rockstock_correct_height( $post_id, $attachment_id, $width, $height ) {       $original_size = $this->rockstock_get_original_image_size( $post_id, $attachment_id );       if ( $original_size['original']['width'] > $original_size['original']['height'] ) return ceil($height * $width / $original_size['original']['width'] );       if ( $original_size['original']['height'] > $original_size['original']['width'] ) return $height;       return $this->rockstock_correct_square( $width, $height );

}

private function rockstock_correct_square( $width, $height ) {       if ( $width >= $height ) return $height;       return $width;
}

 

post-203980-0-43681500-1490783010_thumb.png

Link to comment
Share on other sites

There might be more wrong to this than you think.

 

How are you using these functions? Where are $width and $height coming from? Are you trying to constrain the image to a maximum or minimum dimension? Width and height at the same time, or just one and the other is whatever it is?

Link to comment
Share on other sites

That's only the part that does the calculation. Another section is used to replace some text displayed by the plugin. The entire solution is working, it's just not coming up with the correct pixel dimension. For example, look at 'small' in the screenshot - height should be around 500px. This was designed to accommodate images of any ratio and spit out text displaying pixel dimensions in the same ratio as the original image.

 

Therefore, I think you can ignore all of the code and assume it works, except for the bit that does the pixel calculation - it's spitting out a pixel ratio that's not the same as the original.

 

Sorry, I don't know PHP at all, I just assumed somebody could look at the maths part and say 'yeah, the calculation should look like this to return the same aspect ratio of the original'

Link to comment
Share on other sites

I'm not going to go through your code and try to retro-write changes to do what you are asking. Instead, I will provide the logic that you can try and implement. As I understand it you have an original image and you need to resize it based on a maximum width and a maximum height - but you need to do so while maintaining the correct aspect ratio. So, unless the source image is the same ratio as the target sizes one dimension will be set to the target max and the other will be less than the target dimension.

 

I have a script somewhere that does this for multiple file types and generates the new files, but I can't find it right now. So, I'll provide the logic to determine the new image size. There is an easy mathematical way to do this by comparing the ratios of the current sizes and the target sizes and using the minimum ratio as the resize percentage

<?php
 
//Set max sizes for output
$outputMaxWidth  = 200;
$outputMaxHeight = 200;
 
//Get the width & height of current image
$src_info = @getimagesize($filename);
list($sourceWidth, $sourceHeight) = $src_info;
 
//Determine the resize percentage based on the minimum of the source/target ratios
$resizePerc = min(($outputMaxWidth/$imageWidth), ($outputMaxHeight/$imageHeight));
 
//Calculate the output sizes using the resize percent
$outputWidth  = round($sourceWidth  * $resizePerc, 0);
$outputHeight = round($sourceHeight * $resizePerc, 0);
 
?>

EDIT: Renamed a couple of variables due to a copy/paste error

Link to comment
Share on other sites

Therefore, I think you can ignore all of the code and assume it works, except for the bit that does the pixel calculation

The code doesn't calculate an aspect ratio: it calculates a width and height. Obviously one or more calculations are wrong, but I didn't (still don't) precisely know what you want it to do.

 

Sorry, I don't know PHP at all, I just assumed somebody could look at the maths part and say 'yeah, the calculation should look like this to return the same aspect ratio of the original'

I can tell you that the aspect ratio is wrong. What I can't tell you is what you need to do to fix it because I don't know what the correct behavior is supposed to be.

 

Are you resizing based only on a desired width? A desired height? A maximum for both the width and height (which is what Psycho posted)? A minimum width and height?

 

:psychic:

 

All of those use different, albeit similar calculations. I didn't think it was worth the time to write out all the possible answers because I thought getting clarification with first post would be quick, but obviously it was more difficult than I thought.

Link to comment
Share on other sites

I'm sorry, I guess this is all a bit beyond me. I know what I want to achieve but I don't really understand what's represented in the code. I'll try to describe my situation clearer but if it still makes no sense, please don't waste your time on this...

 

I have a plugin that allows me to set prices based on maximum pixel dimensions. The problem with this plugin is that it displays the exact dimensions I've entered to the customer. This is a problem because, to account for various ratios of upright and landscape, I've had to enter equal (or square) dimensions (e.g. 1000x1000px) but I want the customer to see the pixel dimensions of the correct ratio.  So I asked someone to alter the plugin to display this. Because the 'Original' (shown in the screenshot) is known and correct, it simply takes that value and replaces the values of the other sizes (which otherwise would display as 6000x6000, 4000x4000, 1920x1920 and 900x900 respectively) based on whichever dimension is the longer.  What I've been provided with does work but it displays an incorrect ratio as shown in the screenshot (e.g. the height of 'Small' should be something close to 500px if it were the same ratio as the original).

 

I still don't know I'm making any sense so please don't waste your time on this if that's the case.

 

Here's the other part of the code I was supplied, I didn't think it was relevant to the question which is why I left it out:

 

$rockstock_width = $prices[ $i ]['width'];

       $rockstock_height = $prices[ $i ]['height'];       $prices[ $i ]['width'] = $this->rockstock_correct_width( $post_id, $attachment_id, $rockstock_width, $rockstock_height );       $prices[ $i ]['height'] = $this->rockstock_correct_height( $post_id, $attachment_id, $rockstock_width, $rockstock_height );
Link to comment
Share on other sites

Let me restate what I think your problem is with an example or two and you can confirm if my understanding is correct.

 

There is an image with variable dimensions. You want to create a select list that has options for the original size and additional smaller sizes. Those smaller sizes will maintain the correct aspect ratio of the original and adhere to some maximum value to be used for one of the dimensions.

 

e.g. The original image is 1,000W x 2,000H (ratio is .5)

 

You want one of the smaller options to have a maximum dimension of 800 (for width or height). Since the height is the longest dimension of the original, the smaller option will have a height of 900 and the width would be calculated as .5 * 900 = 450. So final dimension of this smaller option would be: 450W X 900H (ratio is still .5)

Link to comment
Share on other sites

That sounds correct. This is simply replacing what the plugin natively displays to the frontend and it is getting the original dimensions from what is already displayed, as this is correct.  The functionality is working perfectly except that it hasn't calculated the ratio correctly.

 

It is not trying to resize an image, nor even get the original dimensions from the image itself, as they are already known.

 

This is why I thought it'd only require a quick look at the mathematical part by someone who understands what they're looking at.

Link to comment
Share on other sites

Well, that code is quite a mess in my opinion. Way over complicated and, as I said, I can't see how it is used - there is other code at play. Hell, if the author had at lease included SOME comments it would probably be easy. I've looked through the functions you've posted several times and I don't see HOW they are used to create the calculations.

 

But, here is my attempt based on what I *think* it is doing.

 

 

<?php
 

 
//This functions would not work as posted, I modified to what I think it was supposed to be
private function rockstock_get_original_image_size( $post_id, $attachment_id ) {
    if ( is_null( $this->rockstock_original_image_size ) )
    {
        $this->rockstock_original_image_size = Sell_Media()->images->get_original_image_size( $post_id, $attachment_id );
    }
    return $this->rockstock_original_image_size;
}
private function rockstock_correct_width( $post_id, $attachment_id, $width, $height ) {
    $original_size = $this->rockstock_get_original_image_size( $post_id, $attachment_id );
    $resizePerc = $this->getResizePerc($original_size['original'], $width, $height)
    return $resizePerc * $original_size['original']['height'];
}
private function rockstock_correct_height( $post_id, $attachment_id, $width, $height ) {
    $original_size = $this->rockstock_get_original_image_size( $post_id, $attachment_id );
    $resizePerc = $this->getResizePerc($original_size['original'], $width, $height)
    return $resizePerc * $original_size['original']['height'];
}
//This function no longer used in the above functions
//If not used anywhere elses, this can be removed
private function rockstock_correct_square( $width, $height ) {
       if ( $width >= $height ) return $height;
       return $width;
}
//New function to get the resize percentage based on original and target sizes
private function getResizePerc($original, $maxWidth, $maxHeight) {
    return min(($maxWidth/$original['width']), ($maxHeight/$original['height']));
}

 
?>
Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.