Means Report

The ramblings of some old dude.

HTMLy Blog Image Upload & Compression Upgrade

- Posted in Technical by

The software app that I use for content management is called HTMLy. It is a pretty basic blog and content management system. One thing I noticed while uploading images from my camera is that they are not compressed and rather large. The problem with that is that A. they take up a lot of space on my server and B. they are slow to load for the end users and C. takes more bandwidth and server resources to process. So I decided to fix that.

The version of HTMLy that I currently use is 3.1.1 and the file that I needed to modify is located in /system/includes/dispatch.php. The code is way down at about 690 lines. I have put this on the blog for anyone who would need to modify the code and for myself for future reference in case at some point I upgrade the software and break the code. The following code is it's replacement for the create_thumb function.

If you have any questions, comment below.

function create_thumb($src, $desired_width = null, $desired_height = null) {

    // GD required
    if (!extension_loaded('gd')) {
        return $src;
    }

    /* ===============================
       OPTIONS (adjust freely)
    =============================== */

    $OPTIMIZE_ORIGINAL = true;   // compress uploaded originals
    $JPEG_QUALITY      = 80;     // 70–85 recommended
    $PNG_COMPRESSION   = 6;      // 0–9 (higher = smaller)
    $WEBP_QUALITY      = 75;     // thumbnail quality
    $MAX_WIDTH         = 2000;   // resize originals larger than this (px)

    /* =============================== */

    static $optimized = [];

    $dir = 'content/images/thumbnails';

    if (!is_dir($dir)) {
        mkdir($dir, 0755, true);
    }

    $w = config('thumbnail.width');
    if (empty($w)) {
        $w = 500;
    }

    if (is_null($desired_width)) {
        $desired_width = $w;
    }

    $h = !is_null($desired_height) ? 'x' . $desired_height : null;

    $path = pathinfo($src, PATHINFO_FILENAME);
    $fileName = rawurldecode($path);
    $thumbFile = $dir . '/' . $fileName . '-' . $desired_width . $h . '.webp';

    if (file_exists($thumbFile)) {
        return site_url() . $thumbFile;
    }

    /* ===============================
       LOAD SOURCE IMAGE
    =============================== */

    $source_image = @imagecreatefromstring(file_get_contents($src));

    if ($source_image === false) {
        return $src;
    }

    $width  = imagesx($source_image);
    $height = imagesy($source_image);

    /* ===============================
       COMPRESS ORIGINAL IMAGE
    =============================== */

    if ($OPTIMIZE_ORIGINAL && !isset($optimized[$src])) {

        $optimized[$src] = true;

        $originalPath = str_replace(site_url(), '', $src);

        if (file_exists($originalPath)) {

            $info = @getimagesize($originalPath);

            // Resize overly large images
            if ($width > $MAX_WIDTH) {

                $newHeight = floor($height * ($MAX_WIDTH / $width));
                $resized = imagecreatetruecolor($MAX_WIDTH, $newHeight);

                imagealphablending($resized, false);
                imagesavealpha($resized, true);

                imagecopyresampled(
                    $resized,
                    $source_image,
                    0, 0, 0, 0,
                    $MAX_WIDTH,
                    $newHeight,
                    $width,
                    $height
                );

                imagedestroy($source_image);
                $source_image = $resized;

                $width  = imagesx($source_image);
                $height = imagesy($source_image);
            }

            if ($info) {

                switch ($info['mime']) {

                    case 'image/jpeg':
                        imagejpeg($source_image, $originalPath, $JPEG_QUALITY);
                        break;

                    case 'image/png':
                        imagepng($source_image, $originalPath, $PNG_COMPRESSION);
                        break;

                    case 'image/webp':
                        imagewebp($source_image, $originalPath, $JPEG_QUALITY);
                        break;
                }
            }
        }
    }

    /* ===============================
       CREATE THUMBNAIL
    =============================== */

    if (is_null($desired_height)) {
        $desired_height = floor($height * ($desired_width / $width));
    }

    $ratio  = max($desired_width / $width, $desired_height / $height);
    $crop_h = floor($desired_height / $ratio);
    $crop_x = floor(($width - $desired_width / $ratio) / 2);
    $crop_w = floor($desired_width / $ratio);

    $virtual_image = imagecreatetruecolor($desired_width, $desired_height);

    imagealphablending($virtual_image, false);
    imagesavealpha($virtual_image, true);

    imagecopyresampled(
        $virtual_image,
        $source_image,
        0, 0,
        $crop_x, 0,
        $desired_width,
        $desired_height,
        $crop_w,
        $crop_h
    );

    /* ===============================
       SAVE WEBP THUMBNAIL
    =============================== */

    imagewebp($virtual_image, $thumbFile, $WEBP_QUALITY);

    imagedestroy($virtual_image);
    imagedestroy($source_image);

    return site_url() . $thumbFile;
}

Add Comment

* Required information
1000
Captcha Image
Powered by Commentics

Comments

No comments yet. Be the first!