Implicit conversion from float [numner] to int loses precision

I’m generating a bunch of images using resize() and crop() and passing them to srcset() but sometimes the images aren’t generated and I’m getting this error:

Is there any way to avoid this and have the images generate in some way and avoid subpixel values?

What’s your code that’s causing this?

It’s based on this: Responsive images | Kirby CMS

Here’s the full code (still WIP)

<?php
/* SETTINGS */
$ratios = [
    "1/1" => [1080, 1080],
    "2/1" => [1920, 960],
    "16/9" => [1920, 1080],
    "10/8" => [1920, 1536],
    "21/9" => [1920, 824],
    "7/5" => [1920, 1372],
    "4/3" => [1920, 1440],
    "5/3" => [1920, 1152],
    "3/2" => [1920, 1280],
    "3/1" => [1920, 640],
    "2/3" => [1280, 1920],
    "5/6" => [1600, 1920],
];
$sizes = [
    12 => ['100vw', '100vw', '100vw'],
    11 => ['100vw', '100vw', '100vw'],
    10 => ['100vw', '90vw', '90vw'],
    9 => ['100vw', '80vw', '80vw'],
    8 => ['100vw', '75vw', '75vw'],
    7 => ['100vw', '60vw', '60vw'],
    6 => ['100vw', '50vw', '50vw'],
    5 => ['100vw', '40vw', '40vw'],
    4 => ['100vw', '33vw', '33vw'],
    3 => ['100vw', '25vw', '25vw'],
    2 => ['100vw', '20vw', '20vw'],
    1 => ['100vw', '10vw', '10vw'],
];
$size = $sizes[$span];

$breakpoints = "(min-width: 75em)".$size[2].",
                (min-width: 60em)".$size[1].",
                (min-width: 44em)".$size[0].",
                100vw";
/* CHECK FOR AUTO HEIGHT */
if($ratio != 'auto'){
    $crop = $ratios[$ratio];
    $imageCropped = $image->crop($crop[0]/2,$crop[1]/2);
    $auto = false;
} else {
    $imageCropped = $image->resize(1920);
    $crop = [$imageCropped->width(), $imageCropped->height()];
    $auto = true;
}
if($image->extension() != 'svg'):
if($imageCropped): ?>
    <picture>
        <source
            srcset="<?= $image->srcset(
                [
                    '300w'  => ['width' => $crop[0]/6, 'height' => $crop[1]/6, 'crop' => true, 'format' => 'webp'],
                    '600w'  => ['width' => $crop[0]/4, 'height' => $crop[1]/4, 'crop' => true, 'format' => 'webp'],
                    '900w'  => ['width' => $crop[0]/2, 'height' => $crop[1]/2, 'crop' => true, 'format' => 'webp'],
                    '1200w' => ['width' => $crop[0], 'height' => $crop[1], 'crop' => true, 'format' => 'webp'],
                    '1920w' => ['width' => $crop[0]*2, 'height' => $crop[1]*2, 'crop' => true, 'format' => 'webp'],
                ]
            )?>"
            sizes="<?= $breakpoints ?>"
            type="image/webp"
        >
        <img
            alt="<?= $image->alt() ?>"
            src="<?= $imageCropped->url() ?>"
            srcset="<?= $image->srcset(
                [
                    '300w'  => ['width' => $crop[0]/6, 'height' => $crop[1]/6, 'crop' => true],
                    '600w'  => ['width' => $crop[0]/4, 'height' => $crop[1]/4, 'crop' => true],
                    '900w'  => ['width' => $crop[0]/2, 'height' => $crop[1]/2, 'crop' => true],
                    '1200w' => ['width' => $crop[0], 'height' => $crop[1], 'crop' => true],
                    '1920w' => ['width' => $crop[0]*2, 'height' => $crop[1]*2, 'crop' => true],
                ]
            )?>"
            sizes="<?= $breakpoints ?>"
            width="<?= $imageCropped->width() ?>"
            height="<?= $imageCropped->height() ?>"
        >
    </picture>
<?php
endif;
else: ?>
<img src="<?= $image->url() ?>" alt="<?= $image->alt() ?>" width="<?= $image->width() ?>" height="<?= $image->height() ?>">
<?php endif ?>

And the snippets can look like this:

<?php snippet('image', ['image' => $image, 'ratio' => 'auto', 'span' => 4]); ?>
<?php snippet('image', ['image' => $image, 'ratio' => '16/9', 'span' => 12]); ?>

Some of your calculations (for example, division by 6) return floats, so you need to cast them to integers before passing them to the crop method, as crop() expects integer values as parameters.

So I just prefix any calculations with (int) like this?

'300w'  => ['width' => (int)$crop[0]/6, 'height' => (int)$crop[1]/6, 'crop' => true, 'format' => 'webp'],

Nope, that only applies the cast to the first value, you need to put the division result within parentheses to cast the result to int:

(int)($crop[0]/6)

Excellent, thank you!