Search

Hi all, in the last project I've made, I came across the fact JIT dont resize images inside determined size without crop.

Maybe I did something wrong, but after all, I wrote some messy code that works for this need.

add background on line 162 (ok, this will change natural behavior of MODE_FIT, thats why I call this "messy code"):

// Mode 4: Image fit resize
elseif(preg_match_all('/^4/([0-9]+)/([0-9]+)/([a-fA-F0-9]{3,6}/)?(?:(0|1)/)?(.+)$/i', $string, $matches, PREG_SET_ORDER)){
$param->mode = 4;
$param->width = $matches[0][1];
$param->height = $matches[0][2];
$param->background = trim($matches[0][3],'/');
$param->external = (bool)$matches[0][4];
$param->file = $matches[0][5];
}

and on line 365:

case MODE_FIT:
$src_w = $image->Meta()->width;
$src_h = $image->Meta()->height;

$dst_w = $param->width;
$dst_h = $param->height;

if($param->height == 0) {
$ratio = ($src_h / $src_w);
$dst_w = $param->width;
$dst_h = round($dst_w * $ratio);
}

else if($param->width == 0) {
$ratio = ($src_w / $src_h);
$dst_h = $param->height;
$dst_w = round($dst_h * $ratio);
}

$src_r = ($src_w / $src_h);
$dst_r = ($dst_w / $dst_h);

if ($src_h <= $dst_h && $src_w <= $dst_w){
$image->applyFilter('resizefit', array($src_w, $src_h));
break;
} else {
$image->applyFilter('resizefit', array($dst_w, $dst_h, $param->background));
break;
}

break;

Check the file attached for filter resizefit.

Use case: For exemple, {$root}/image/4/100/100/ffffff/uploads/image.jpg A image with 200x70px will fit in 100x100, in this case, the filter will adjust width to 100px and proportional scale for height, but the result image will verticaly center the original image inside 100px and fill extra height with white color.

I was not able to set positioning of original image in the result. =[

If this is useful for someone, I will appreciate the help on cleanup the code.

<?php

    require_once(realpath(dirname(__FILE__).'/../') . '/class.imagefilter.php');

    Class FilterResizefit extends ImageFilter{

        public static function run($res, $width=NULL, $height=NULL, $background_fill = null){

            $src_w = Image::width($res);
            $src_h = Image::height($res);

            if(!empty($width) && !empty($height)) {
                $ratio = ($dst_h / $dst_w);
                if ($background_fill != null) {
                    $dst_x = $dst_w = $width;
                    $dst_y = $dst_h = $height;
                    if (($src_w / $dst_w) > ($src_h / $dst_h)) {
                        $ratio = $src_w / $dst_w;
                    } else {
                        $ratio = $src_h / $dst_h;
                    }
                    $dst_w = $src_w / $ratio;
                    $dst_h = $src_h / $ratio;
                    $dst_x = ( $dst_x - $dst_w ) / 2;
                    $dst_y = ( $dst_y - $dst_h ) / 2;
                } else {
                   $dst_w = $width;
                   $dst_h = $height;
                }
            }

            elseif(empty($height)) {
                $ratio = ($dst_h / $dst_w);
                $dst_w = $width;
                $dst_h = $height = round($dst_w * $ratio);
            }

            elseif(empty($width)) {
                $ratio = ($dst_w / $dst_h);
                $dst_h = $height;
                $dst_w = $width = round($dst_h * $ratio);
            }

            $dst = imagecreatetruecolor($width, $height);

            if ($background_fill != null ) self::__fill($res, $dst, $background_fill);
            else self::__fill($res, $dst);

            imagecopyresampled($dst, $res, $dst_x, $dst_y, 0, 0, $dst_w, $dst_h, $src_w, $src_h);

            if(is_resource($res)) {
                imagedestroy($res);
            }

            return $dst;

        }
    }

Not sure if I'm missing something here, but I think JIT already has built-in support for the results you want to achieve.

Have you tried Mode 3: Resize Canvas?

Example:

/image/3/100/70/5/ffffff/0/uploads/...

Edit:

Ok, got it now. The second example shows it pretty well...

/image/3/100/70/5/ffffff/0/uploads/...

Suggestions:

Your usecase seems pretty common to me, the mode you implemented should definitely be provided by JIT.

However, I can imagine devs having a hard time understanding the (often very subtle) differences between the different modes, so we should figure out how to name and explain them a little better on the site (maybe with example images)?

For some reasons that I dont check yet, other cases doesnt working right now, like when original image is smaller than result (on both width and height). The idea is adjust to fit without crop and without enlarge more than original size.

exemple: /image/4/500/700/ffffff/uploads/... dont work =[

but /image/4/50/700/ffffff/uploads/... or /image/4/500/70/ffffff/uploads/... is working as expected...

Yeah.. Illustrative examples seems a good option. I'll sketch something here about this. Any ideas are very welcome.

The Modes descriptions are already good for understanding, I think, but as you said, there are very subtle differences.

Hi symphonists, please coment this preview.png

This is just an humble simulator, not shure when got some time to finish.

The html prototype (yet whitout actions) on GitHub

This is not a extension ;) only a possible utility...

Attachments:
preview.jpg

Create an account or sign in to comment.

Symphony • Open Source XSLT CMS

Server Requirements

  • PHP 5.3-5.6 or 7.0-7.3
  • PHP's LibXML module, with the XSLT extension enabled (--with-xsl)
  • MySQL 5.5 or above
  • An Apache or Litespeed webserver
  • Apache's mod_rewrite module or equivalent

Compatible Hosts

Sign in

Login details