This topic is locked
[SOLVED]

Guide 91 – Reducing images while maintaining proportions

2/1/2025 12:10:14 PM
PHPRunner Tips and Tricks
fhumanes author

The problem of deformation when reducing the size of an image, especially when the image is vertical or has been taken on a mobile, is general in PHPRunner. This has occurred in all versions and I, at least, have reported it but, as far as I know, it has never been solved.

In my developments in React, I had to face the problem of reducing the images I took from my mobile phone and consulting on the Internet I saw how it was solved and so I applied it in my development.

This same problem has been posted on the Xlinesoft forum and seeing that many other developers have the same problem, I have been encouraged to do this exercise.

Objetive

Perform image size transformations while preserving their orientation and proportion, and then use them in PHPRunner or any other solution.

DEMO: https://fhumanes.com/resize/

CODE:

<?php
$dir = __DIR__.'/../'; // Path directory files

$size_image = 600;
$size_mini = 148;

// get information about uploaded files
$file_array = my_json_decode($values["imagen"]);
$file = $file_array[0]; // In the example, only 1 file is allowed

if ($file['thumbnail'] == Null ) { // If there is information is that the image has already become

// handle single input with single file upload
$uploadedFile = $file['name'];
$dataFile = array();

$dataFile['filename'] = $file['name'];
$dataFile['type'] = $file['type'];

$tempFile = tempnam(sys_get_temp_dir(), 'CO_'); // Create temporary file
copy($dir.$uploadedFile, $tempFile) ; // Copy File

// ++++++++++++++++++++++++++++++ Resize imagen +++++++++++++++++++++++++++++
list($width, $height) = getimagesize($tempFile);

// Get the image EXIF ​​data (if available)
if ($dataFile['type'] == 'image/jpeg') { // JPEG
$source = imagecreatefromjpeg($tempFile);
} else {
$source = imagecreatefrompng($tempFile);
}
$exif = exif_read_data($tempFile);

// Verify if EXIF ​​data contains guidance information
$orientation = $exif['Orientation'];
if ( $orientation <> null) {
// Rotate the image according to the EXIF ​​orientation
switch ($orientation) {
case 3:
// Rotate 180 degrees
$source = imagerotate($source, 180, 0);
break;
case 6:
// Rotate 90 degrees in a schedule
$source = imagerotate($source, 270, 0);
// Invierto $width, $height
$aux = $width;
$width = $height;
$height = $aux;
break;
case 8:
// Rotate 90 degrees in anti -Horary sense
$source = imagerotate($source, 90, 0);
// Invierto $width, $height
$aux = $width;
$width = $height;
$height = $aux;
break;
}
}
$thumbFile = tempnam(sys_get_temp_dir(), 'TH_'); // Crear fichero Temporal
$origFile = tempnam(sys_get_temp_dir(), 'CO_'); // Crear fichero Temporal
$percent1 = ($size_image)/$width; // Tamaño completo iamgen
$newwidth1 = $width * $percent1;
$newheight1 = $height * $percent1;
$percent2 = ($size_mini)/$width; // Tamaño thumbnail imagen
$newwidth2 = $width * $percent2;
$newheight2 = $height * $percent2;
$orig = imagecreatetruecolor($newwidth1, $newheight1);
$thumb = imagecreatetruecolor($newwidth2, $newheight2);

if ($dataFile['type'] == 'image/jpeg') { // JPEG
imagecopyresized($orig, $source, 0, 0, 0, 0, $newwidth1, $newheight1, $width, $height);
imagecopyresized($thumb, $source, 0, 0, 0, 0, $newwidth2, $newheight2, $width, $height);
imagejpeg($orig,$origFile);
imagejpeg($thumb,$thumbFile);
} else { // PNG
imagecopyresized($orig, $source, 0, 0, 0, 0, $newwidth1, $newheight1, $width, $height);
imagecopyresized($thumb, $source, 0, 0, 0, 0, $newwidth2, $newheight2, $width, $height);
imagepng($orig,$origFile);
imagepng($thumb,$thumbFile);

}
unlink($tempFile); // Eliminamos temporal

copy($origFile, $dir.$uploadedFile) ; // Copy File
// Name File thumbnail
$name_array = explode("/", $uploadedFile);
$last_name = $name_array[sizeof($name_array)-1];
$name_array = array_diff($name_array, array($last_name));
$last_name = 'th_'.$last_name;
$name_array[] = $last_name;
$name_thumbFile = implode('/',$name_array);
copy($thumbFile, $dir.$name_thumbFile) ; // Copy File

$file['size'] = filesize($origFile);
$file['thumbnail']= $name_thumbFile;
$ile['thumbnail_size']= filesize($dir.$name_thumbFile);

// update values of the field that stores file names
$file_array[0] = $file;
$values["imagen"] = my_json_encode($file_array);

unlink($origFile); // Eliminamos temporal
unlink($thumbFile); // Eliminamos temporal
}

If you are interested , continue reading the article at this link .

T
TOK 3/13/2025

In my case with PHPRunner-10.91 the problem was solved by correcting
web application's file RunnerAll.js where resizing is performed
by resizeImage function (on client's side).

You can apply correction directly in your existing application's RunnerAll.js file
or update the PHPRunner's source file Util.js for future applications.

Step 1: Locate the Affected File

The function is found in the following files:

Existing Web Application File:
<your_PHPRunner_app_on_server>\include\runnerJS\RunnerAll.js
PHPRunner Source File:
<your_PHPRunner10.91_installation_folder>\source\include\common\runnerJS\Util.js

Step 2: Find the Function

Search for "Runner.util.resizeImage" inside the file. You should find it like this:
Runner.util.resizeImage = function( imageSrc, imageSize, blobType, callbackFn )...

This function is responsible for resizing images, but contains
an error when handling portrait (taller-than-wide) images.

Step 3: Identify the Bug

The incorrect code is in the if statement handling aspect ratios:

if( whRatio >= 1 ) {
canvas.width = imageSize;
canvas.height = canvas.width / whRatio;
} else {
canvas.height = imageSize;
canvas.width = canvas.height / whRatio; // <--- WRONG
}

The issue is that canvas.width should be calculated using multiplication (*), not division (/).

Step 4: Apply the Fix

Modify the incorrect line as follows:

if( whRatio >= 1 ) {
canvas.width = imageSize;
canvas.height = canvas.width / whRatio;
} else {
canvas.height = imageSize;
canvas.width = canvas.height * whRatio; // <--- CORRECT
}

Step 5: Full Corrected Code

Here is the full corrected function:

/**
* Fit image to specified max width/height
*
* @param {Function} callbackFn - Called with the resized image blob
* @param {string} imageSrc - Image source URL
* @param {Number} imageSize - Maximum width or height in pixels
* @param {string} blobType - MIME type for the output blob
*/
Runner.util.resizeImage = function(imageSrc, imageSize, blobType, callbackFn) {
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
var img = new Image();

// Prevents "Tainted canvases may not be exported" error
img.crossOrigin = "Anonymous";

img.onload = function() {
var imgwidth = img.width;
var imgheight = img.height;

if (imgwidth <= imageSize && imgheight <= imageSize) {
canvas.width = imgwidth;
canvas.height = imgheight;
} else {
var whRatio = imgwidth / imgheight;
if (whRatio >= 1) {
canvas.width = imageSize;
canvas.height = canvas.width / whRatio;
} else {
canvas.height = imageSize;
canvas.width = canvas.height * whRatio; // <--- FIXED
}
}

ctx.drawImage(img, 0, 0, imgwidth, imgheight, 0, 0, canvas.width, canvas.height);

canvas.toBlob(function(blob) {
callbackFn(blob);
}, blobType);
};

img.src = imageSrc;
};

Additional Notes:
In my tested PHPRunner 11 version 11.0.14, this function is located in the file:
<Your_PHPRunner11_installation_folder>\app-11.0.14\resources\source\include\common\runnerJS\Util.js

fhumanes author 3/13/2025

thank you so much

fhumanes author 3/13/2025