Skip to content

Instantly share code, notes, and snippets.

@earth3300
Last active October 26, 2019 15:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save earth3300/58c30d2a3e58afcaba907213a5fc6f46 to your computer and use it in GitHub Desktop.
Save earth3300/58c30d2a3e58afcaba907213a5fc6f46 to your computer and use it in GitHub Desktop.
Image processor in PHP (Copy, rename, resize, resolution).
<?php
/**
* EC01 Image Printer
*
* Capabilities: resize, rename and adjust resolution.
*
* @package Earth3300\EC01
* @version 0.9.0.2019.10.25
* @author Clarence J. Bos <cbos@tnoep.ca>
* @copyright Copyright (c) 2018, Clarence J. Bos
* @license https://www.gnu.org/licenses/gpl-3.0.en.html GPL v3.0
* @link https://gist.github.com/earth3300/58c30d2a3e58afcaba907213a5fc6f46
*
* File: printer.image.php
* Created: 2019-10-18
* Updated: 2019-10-25
* Time: 09:30 EDT
* ID: ENG-ON-001
*/
// Notes: Working on image resource in (1 per sized image).
namespace Earth3300\EC01;
if( ! defined( 'NDA' ) )
{
define('NDA',true);
}
/**
* Prints an Image Files
*/
class ImagePrinter
{
/** @var array Default options. */
protected $opts = [
'this' => [
'file' => 'printer.image.php',
'title' => 'EC01 Image Printer',
'date' => [
'created' => '2019-10-18',
],
],
'page' => [
'title' => 'EC01 Image Printer',
],
'initials' => 'brs',
'dir' => [
'in' => '/0/m/gall/2019/001/sel',
'out' => '/0/m/gall/2019/001',
],
'match' => '/*.{png,jpg}',
'image' => [
'dpi' => [
'lo' => 96,
'md' => 180,
'hi' => 300,
],
'dim' => [
'web' => [
'sm' => [ 'w' => -1, 'h' => 135, ], // 240
'md' => [ 'w' => -1, 'h' => 225, ], // 400
'lg' => [ 'w' => -1, 'h' => 450, ], // 800
'xl' => [ 'w' => -1, 'h' => 1080, ], // 1920
],
],
'aspect' => [
'16:9' => [ 'int' => 1.7778, 'use' => 1, ],
'4:3' => [ 'int' => 1.3333, 'use' => 0, ],
'1:1' => [ 'int' => 1.0000, 'use' => 0, ],
],
'priority' => [
'type' => [
'dim' => 1,
'aspect' => 0,
],
'dim' => [
'w' => 0,
'h' => 1,
],
],
'class' => '',
],
'types' => [
[ 'name' => 'plate', 'use' => 1, ],
[ 'name' => 'bowl', 'use' => 1, ],
[ 'name' => 'vase', 'use' => 1, ],
[ 'name' => 'teapot', 'use' => 1, ],
],
'file' => [
'overwrite' => 0,
],
'files' => [
'max' => [
'use' => 1, // On/Off switch
'cnt' => 50, // Max limit for array.
],
],
'max' => [
'size' => 5000000, // Bytes
],
'write' => [
'root' => 0,
],
'message' => [
'na' => 'Not available.',
'write' => [
'denied' => 'Write permission denied.' ,
'success' => 'Write operation succeeded.',
'failure' => 'Write operation failed.',
],
],
'link' => 'https://gist.github.com/earth3300/...',
];
/**
* Init
*/
public function init()
{
if( $this->security() )
{
if( $this->authorize() )
{
$this->run();
}
}
}
/**
* Security
*/
private function security()
{
if ( '127.0.0.1' == $_SERVER['REMOTE_ADDR']
&& file_exists( __DIR__ . '/.security' ) )
{
return true;
}
else
{
return false;
}
}
/**
* Authorize
*
* @return bool|string
*/
private function authorize()
{
if( isset( $_GET['unlock'] ) )
{
return true;
}
else
{
exit( '<pre>Unauthorized.</pre>' );
}
}
/**
* Run
*
* Run, if authorized. The file respresents the item or items that need to
* be processed. In this case, the file is an array that contains information
* about the image or images that need to be processed, and the results
* thereof. The output from this command is valid HTML, which can be the
* inner part of a page which can be used elsewhere, or a complete HTML page
* that can be displayed as is.
*
* @return string $html
*/
private function run()
{
if( isset( $_GET['run'] ) )
{
// Initialize
$page = [];
$page = $this->getPaths( $page );
$page = $this->getItemTypes( $page );
// Get the environment variables (directory read/write, etc.).
$page = $this->getEnvData( $page );
// $page['items'] = [...];
$page = $this->getFiles( $page );
// Return the items, if checks passed, info to display.
if( $page = $this->preProcess( $page ) )
{
// Process the items, returning them.
$page = $this->process( $page );
// Post process, validation, and return the file.
$page = $this->postProcess( $page );
}
$page = $this->getEnvHTML( $page );
$page = $this->getMainHTML( $page );
if( 1 )
{
$page = $this->getPageHTML( $page );
}
if( 0 )
{
return $page;
}
else
{
echo $page['html']['page'];
}
}
else
{
echo '<pre>You wish to run the script?</pre>' . PHP_EOL;
}
}
/**
* Get
*
* A generic function to "get"
*/
private function get( $arr )
{
if( isset( $arr ) )
{
return $arr;
}
else
{
// do nothing.
}
}
/**
* Get the Paths to the Files to Process.
*
* Here, the $path array contains information about the input path. This is
* the directory to be processed.
*
* @param array $page
*
* @return array
*/
private function getPaths( $page )
{
$path = [];
$path['root'] = rtrim( $_SERVER['DOCUMENT_ROOT'], '/' );
$path['in'] = $path['root'];
$path['in'] .= $this->opts['dir']['in'];
$path['out'] = $path['root'];
$path['out'] .= $this->opts['dir']['out'];
$page['path'] = $path;
return $page;
}
/**
* Get Item Types
*
* Get the item types (types of physical entities).
*
* @param array $page
*
* @return array
*/
private function getItemTypes( $page )
{
$page['types'] = null;
if( isset( $this->opts['types'] ) )
{
$page['types'] = $this->opts['types'];
}
return $page;
}
/**
* Get the Environment Variables
*
* Get environment variables, particularly if the directories of interest
* are readable and writable. Do not change anything here.
*
* @param array $page
*
* @return array
*/
private function getEnvData( $page )
{
$env['path']['in'] = null;
$env['path']['out'] = null;
if( isset( $page['path']['in'] ) && isset( $page['path']['out'] ) )
{
$env['path']['in']['exists'] = file_exists( $page['path']['in'] );
$env['path']['out']['exists'] = file_exists( $page['path']['out'] );
$env['path']['in']['readable'] = is_readable( $page['path']['in'] );
$env['path']['out']['writable'] = is_writable( $page['path']['out'] );
clearstatcache();
}
$page['env'] = $env;
return $page;
}
/**
* Get the Files
*
* Get the file based on a match ( `/*.{png,jpg}`) using
* $pages = glob( $match, GLOB_BRACE );
*
* @param array $page
*
* @return array
*/
private function getFiles( $page )
{
$files = [];
if( isset( $page['path']['in'] ) && strlen( $page['path']['in'] ) > 0 )
{
if( isset( $page['types'] ) && count( $page['types'] ) > 0 )
{
foreach( $page['types'] as $cnt => $type )
{
if( $type['use'] )
{
$match = $page['path']['in'];
$match .= '/' . $type['name'];
$match .= $this->opts['match'];
$files[] = glob( $match, GLOB_BRACE );
}
}
}
}
$files = $this->flattenArray( $files );
$files = $this->chkArrayLength( $files );
// returns: [$cnt]['file']['in'];
$page['items'] = $files;
return $page;
}
/**
* Flatten Array
*
* Flatten the array, as necessary. This is a specialized function, which
* works when the important data is two levels down, but it needs to be
* all one level down. Adjust as necessary.
*
* @example $arr[]['file']['in'] = '/full/path/to/file.ext';
*
* @param array $files
*
* @return array
*/
private function flattenArray( $files )
{
$arr = [];
if( is_array( $files ) && count( $files ) > 0 )
{
foreach( $files as $cnt => $file )
{
if( is_array( $file ) )
{
foreach( $file as $cnt1 => $file1 )
{
$arr[]['in']['file'] = $file1;
}
}
}
}
return $arr;
}
/**
* Check Array Length
*
* @param array $files
*
* @return array
*/
private function chkArrayLength( $files )
{
if( is_array( $files ) && count( $files ) > 0 )
{
if( $this->opts['files']['max']['use'] )
{
$files = array_slice( $files, 0, $this->opts['files']['max']['cnt'] );
}
}
return $files;
}
/**
* Pre Process
*
* Excludes, Counts, Maximum, etc.
*
* @param array $page
*
* @return array
*/
private function preProcess( $page )
{
if( isset( $page['items'] ) && count( $page['items'] ) > 0 )
{
foreach( $page['items'] as $cnt => $item )
{
// $data...
if( $this->chkItem( $item ) )
{
// Do nothing.
}
else
{
unset( $page['items'][ $cnt ] );
}
}
}
$page['data']['in']['cnt'] = count( $page['items'] );
return $page;
}
/**
* Process
*
* @param array $page
*
* @return array
*/
private function process( $page )
{
// Set counter (actual).
$i = 0;
if( isset( $page['items'] ) && count ( $page['items'] ) > 0 )
{
foreach( $page['items'] as $cnt => $item )
{
// Extract as much information as we can from that item.
$page['items'][ $cnt ] = $this->getItemData( $page, $item, $cnt );
//Count of actually processed.
$i++;
}
// Set the count
$page['data']['in']['cnt'] = $i;
// Reset count;
$i = 0;
// May contain summary data
$page = $this->getDataInHTML( $page );
// Next
foreach( $page['items'] as $cnt => $item )
{
// Extract as much information as we can from that item.
$page['items'][ $cnt ] = $this->setItemData( $page, $item, $cnt );
//Count of actually processed.
$i++;
}
// Set the count
$page['data']['out']['cnt'] = $i;
// May contain summary data
$page = $this->getDataOutHTML( $page );
}
return $page;
}
/**
* Post Process
*
* Checking, validation, etc.
*
* @param array $page
*
* @return array
*/
private function postProcess( $page )
{
$resp = [];
if( count( $page['items'] ) > 0 )
{
foreach( $page['items'] as $cnt => $item )
{
if( $this->isCopy() )
{
$item = $this->copyFile( $item );
}
if( $this->isPrint() )
{
if( $this->chkDir( $item ) )
{
if( $this->authPrint( $item ) )
{
$item = $this->printImageDisk( $item );
}
}
}
$page['items'][$cnt] = $item;
}
}
return $page;
}
//
/**
* Get Item Data
*
* $item['intent'] (Intended use of the item).
* '' = direct
* 0 = large
* 1 = medium
* 2 = small
*
* @param array $item
* @param array $page
* @param int $cnt
*
* @return array
*/
private function getItemData( $page, $item, $cnt )
{
$item['in']['intent'] = 2; // large (~800px wide).
if( isset( $item['in']['file'] ) && is_string( $item['in']['file'] ) )
{
// pad with leading zeros (2)
$item['in']['cnt'] = sprintf( '%03d', $cnt + 1 );
$item['in'] = $this->getItemType( $item['in'] );
$item['in'] = $this->getMimeType( $item['in'] );
$item['in'] = $this->getItemName( $item['in'] );
$item['in'] = $this->getItemFileSize( $item['in'] );
$item['in'] = $this->getItemFileDates( $item['in'] );
$item['in'] = $this->getItemSrc( $page, $item['in'] );
$item['in'] = $this->getItemSerial( $item['in'] );
$item['in'] = $this->getItemID( $item['in'], $cnt );
$item['in'] = $this->getItemTitle( $item['in'] );
if( isset( $item['in']['mime']['main'] ) && 'image' == $item['in']['mime']['main'] )
{
// all image specific data should have a ['image'] key.
0 ? $item['in'] = $this->getExifData( $item['in'] ) : '';
1 ? $item['in'] = $this->getImageRescIn( $item['in'] ) : '';
1 ? $item['in'] = $this->getImageDimIn( $item['in'] ) : '';
0 ? $item['in'] = $this->getImageOrtIn( $item['in'] ) : '';
1 ? $item['in'] = $this->getImageResIn( $item['in'] ) : '';
1 ? $item['in'] = $this->getImageAspect( $item['in'] ) : '';
1 ? $item = $this->getImageAlt( $item ) : '';
1 ? $item = $this->getImageClass( $item ) : '';
1 ? $item = $this->getFileOutName( $page, $item ) : '';
1 ? $item = $this->getImageCaption( $item ) : '';
1 ? $item = $this->getImageSrcOut( $item ) : '';
1 ? $item['out']['image'] = $this->getImageHtmlOut( $item['out']['image'] ) : '';
// Gets the versions for the new images.
1 ? $item = $this->getImageDimOutWeb( $item ) : '';
echo "dim";
pre_dump( $item, 0 );
}
1 ? $item = $this->getImageHtmlSrcSet( $item ) : '';
}
return $item;
}
/**
* Set Item Data
*
* @param array $item
* @param array $page
* @param int $cnt
*
* @return array
*/
private function setItemData( $page, $item, $cnt )
{
// Basic check...
if( isset( $item['out']['file'] ) && is_string( $item['out']['file'] ) )
{
// pad with leading zeros (2)
1 ? $item['out']['cnt'] = sprintf( '%03d', $cnt + 1 ) : '';
0 ? $item['out'] = $this->setItemName( $item['out'] ) : '';
0 ? $item['out'] = $this->setSrcFromFile( $page, $item['out'] ) : '';
0 ? $item['out'] = $this->setItemSerial( $item['out'] ) : '';
0 ? $item['out'] = $this->setItemID( $item['out'], $cnt ) : '';
0 ? $item['out'] = $this->setItemTitle( $item['out'] ) : '';
0 ? $item['out'] = $this->setItemFileName( $page, $item['out'] ) : '';
0 ? $item['out'] = $this->setMimeType( $item['out'] ) : '';
0 ? $item['out'] = $this->setItemType( $item['out'] ) : '';
0 ? $item['out'] = $this->setItemFileSize( $item['out'] ) : '';
0 ? $item['out'] = $this->setItemFileDates( $item['out'] ) : '';
if( isset( $item['in']['mime']['main'] )
&& 'image' == $item['in']['mime']['main'] )
{
// Create a new image and change its resolution.
1 ? $item = $this->setImageResNew( $item ) : '';
0 ? $item['out'] = $this->setImageOrt( $item['out'] ) : '';
0 ? $item['out'] = $this->setAspectRatio( $item['out'] ) : '';
// This will create new images from the image out.
1 ? $item = $this->setImageDimByHeight( $item ) : '';
0 ? $item['out'] = $this->setImageURI( $item['out'] ) : '';
}
}
return $item;
}
/**
* Get Mime Type
*
* Get the item type and subtype.
*
* @param array $item
*
* @return array
*/
private function getMimeType( $data )
{
$data['mime']['main'] = null;
$data['mime']['sub'] = null;
$mime = mime_content_type( $data['file'] );
if( strpos( $mime, '/' ) !== false )
{
$ex = explode( '/', $mime );
$data['mime']['main'] = isset( $ex[0] ) ? $ex[0] : false;
$data['mime']['sub'] = isset( $ex[1] ) ? $ex[1] : false;
}
return $data;
}
/**
* Get Item Type
*
* Get the item type, based on the types available.
*
* @param array $item
*
* @return array
*/
private function getItemType( $data )
{
$data['prod']['type'] = null;
foreach( $this->opts['types'] as $type )
{
if( strpos( $data['file'], $type['name'] ) !== false )
{
$data['prod']['type'] = $type['name'];
break;
}
}
return $data;
}
/**
* Get Item Name Info
*
* Get item name, extension, source, etc.
*
* @return string
*/
private function getItemName( $data )
{
$data['path'] = null;
$data['namext'] = null;
$data['ext'] = null;
$data['name'] = null;
if( is_string( $data['file'] ) )
{
if( $path = pathinfo( $data['file'] ) )
{
$data['path'] = $path['dirname'];
$data['namext'] = $path['basename'];
$data['ext'] = $path['extension'];
$data['name'] = $path['filename'];
}
}
return $data;
}
/**
* Get the Item File Size
*
* Could be any type (image, audio, video, document, html, etc.).
*
* @param array $data
*
* @return array
*/
private function getItemFileSize( $data )
{
// Initialze.
$data['size']['int'] = null;
$data['size']['num'] = null;
$data['size']['text'] = null;
if ( isset( $data['file'] ) )
{
$data['size']['int'] = filesize( $data['file'] );
$data['size'] = $this->formatFileSize( $data['size']['int'] );
}
else
{
$data['size']['int'] = false;
$data['size']['num'] = false;
$data['size']['text'] = false;
}
return $data;
}
/**
* Format File Size
*
* @param int $int
*
* @return string
*/
private function formatFileSize( $int, $return = 0 )
{
// Initialize.
$size['num'] = null;
$size['text'] = null;
if ( is_int( $int ) )
{
// Format size in MB files 1 MB (1,000,000 kB) or over.
if ( $int >= 1000000 )
{
$size['num'] = number_format(
$int / 1000000, 3, ".", "," );
$size['text'] = $size['num'] . ' MB';
}
elseif( $int >= 1000 )
{
$size['num'] = number_format( $int / 1000, 1, ".", "," );
$size['text'] = $size['num'] . ' kB';
}
else
{
$size['num'] = $int;
$size['text'] = $size['num'] . ' B';
}
}
if ( 0 == $return )
{
return $size;
}
else
{
return $size['text'];
}
}
/**
* Get File Created and Modified Dates
*
* @param array $data
*
* @return array
*/
private function getItemFileDates( $data )
{
$data['ctime']['int'] = null;
$data['ctime']['text'] = null;
// File last modified.
$data['mtime']['int'] = null;
$data['mtime']['text'] = null;
if ( isset( $data['file'] ) )
{
$data['ctime']['int'] = filectime( $data['file'] );
$data['ctime']['text'] = date ("F d Y H:i:s", $data['ctime']['int'] );
$data['mtime']['int'] = filemtime( $data['file'] );
$data['mtime']['text'] = date ("F d Y H:i:s", $data['mtime']['int'] );
}
return $data;
}
/**
* Get the source from the file, checking for a preceding slash.
*
* @param array $data
* @param array $page
*
* @return array
*/
private function getItemSrc( $page, $data )
{
// Initialize
$data['src'] = null;
if( isset( $data['file'] ) && isset( $data['namext'] ) )
{
// Remove the root path from the full path.
$src = str_replace( $page['path']['root'], '', $data['file'] );
// Possible server inconsistency. Remove '/' and add again.
$data['src'] = '/' . ltrim( $src, '/' );
// The relative path from the site root to the directory.
$data['rel'] = str_replace( '/' . $data['namext'], '', $data['src'] );
}
else
{
// Source is not found, due to no 'file' being set.
$data['src'] = false;
}
return $data;
}
/**
* Get the Name and Title from the Available Data
*
* @param array $data
*
* @return array
*/
private function getItemTitle( $data )
{
$data['title'] = null;
if ( isset( $data['prod']['type'] ) )
{
$str = ucfirst( $data['prod']['type'] );
}
$data['title'] = $str;
return $data;
}
/**
* Get the Title from the Name
*
* @param array $data
*
* @return array
*/
private function getTitleFromName( $data )
{
// Initialize.
$str = '';
if ( isset( $data['name'] ) && strlen( $data['name'] ) > 0 )
{
$str = str_replace( '-', ' ', $data['name'] );
$str = strtoupper( $str );
}
return $str;
}
/**
* Get Image Resource
*
* Creates an image resource from the image file given.
*
* Can handle only jpg and png.
*
* @param array $data
*
* @return array
*/
private function getImageRescIn( $data )
{
if( isset( $data['file'] ) )
{
switch( $data['ext'] )
{
case 'jpg':
$data['image']['resc'] = imagecreatefromjpeg( $data['file'] );
break;
case 'png':
$data['image']['resc'] = imagecreatefrompng( $data['file'] );
break;
default:
$data['image']['resc'] = false;
break;
}
}
return $data;
}
/**
* Get the Image Source In
*
* This will return the first element in the array. The first element in the
* array will be the smallest image, when the images sizes are set to:
* 'small', 'medium' and 'large', respectively and in alphabetical order.
*
* @param array $data
*
* @return string
*/
private function getImageSrcIn( $data, $intent = null )
{
$str = '';
if( null !== $intent && isset( $data[ $intent ]['src'] ) )
{
$str = $data[ $intent ]['src'];
}
elseif( isset ( $data['intent'] ) && isset( $data[ $data['intent'] ] ) )
{
$str = $data[ $data['intent'] ]['src'];
}
elseif( isset ( $data['src'] ) )
{
$str = $data['src'];
}
elseif( isset( $data['rel'] ) && isset( $data['namext'] ) )
{
$str = $data['rel'] . '/' . $data['namext'];
}
else
{
// Do nothing.
}
$data['image']['src'] = $str;
return $data;
}
/**
* Get the Image Source Out
*
* Get the source elements for the base image and versions thereof.
*
* @param array $item
*
* @return array
*/
private function getImageSrcOut( $item )
{
$item['out']['image']['src'] = $item['out']['rel'];
$item['out']['image']['src'] .= '/' . $item['out']['name'];
$item['out']['image']['src'] .= '.' . $item['in']['ext'];
if ( isset( $item['out']['image']['ver'] ) )
{
foreach ( $item['out']['image']['ver'] as $key => $ver )
{
$img['src'] = null;
$img['src'] .= $item['out']['rel'];
$img['src'] .= '/' . $item['out']['name'];
$img['src'] .= '-' . $key;
$img['src'] .= '.' . $item['in']['ext'];
$img['html'] = sprintf( '<img src="%s"/>%s', $img['src'], PHP_EOL );
$html = sprintf( '<a href="%s"></a>', $img['html'], PHP_EOL );
// The (inner) source of the image.
$item['out']['image']['ver'][$key]['img']['src'] = $img['src'];
// The source in the 'img' element.
$item['out']['image']['ver'][$key]['img']['html'] = $img['html'];
// The image element wrapped in a link (<a href="..."></a>).
$item['out']['image']['ver'][$key]['href']['html'] = $img['html'];
//pre_dump( $item['out']['image']['ver'], 0 );
}
}
return $item;
}
/**
* Get the Image Img Element
*
* @param array $data
*
* @return array
*/
private function getImageImgEl( $data )
{
$data['image']['img'] = null;
if( isset( $data['image']['file'] ) )
{
$data['image']['img'] = sprintf(
'<img src="%s" />%s',
$data['image']['src'],
PHP_EOL
);
}
else
{
$data['image']['img'] = false;
}
return $data;
}
/**
* Get the Image Href Element
*
* @param array $data
*
* @return array
*/
private function getImageHrefIn( $data )
{
$data['image']['href'] = null;
if( isset( $data['image']['src'] ) )
{
$data['image']['href'] = sprintf(
'<a href="%s">%s</a>%s',
$data['image']['src'],
$data['image']['img'],
PHP_EOL
);
}
return $data;
}
/**
* Get the Image HTML (Out)
*
* The image source wrapped with the a href element. Has:
* id, data-id, class, src, alt and width and height attributes.
*
* @param array $image
*
* @return array
*/
private function getImageHtmlOut( $image )
{
$image['html'] = null;
if( isset( $image['src'] ) )
{
$str = '';
// original, renamed image...
$str .= sprintf( '<a href="%s">%s', $image['src'], PHP_EOL );
$str .= sprintf( '<img src="%s" />%s', $image['src'], PHP_EOL );
$str .= '</a>' . PHP_EOL;
$image['html'] = $str;
}
else
{
$image['html'] = false;
}
return $image;
}
/**
* Get the Image Source HTML
*
* The image source wrapped with the a href element. Has:
* id, data-id, class, src, alt and width and height attributes.
* No caption. NOT wrapped in a URL (link).
* Everything is optional, except the actual image source.
*
* @param array $image
*
* @return array
*/
private function getImageSrcHtml( $image )
{
$image['src']['html'] = null;
if( isset( $image['src'] ) )
{
$str = '';
$str .= '<img';
$str .= 0 ? sprintf( ' id="image-%s"', $image['id'] ) : '';
$str .= 0 ? sprintf( ' data-id="%s"', $image['id'] ) : '';
$str .= 0 ? sprintf( ' class="%s"', $image['class'] ) : '';
$str .= 1 ? sprintf( ' alt="%s"', $image['alt'] ) : '';
$str .= 1 ? ' ' . $image['dim']['attr'] : '';
$str .= sprintf( ' src="%s"', $image['src']['text'] );
$str .= ' />' . PHP_EOL;
$image['src']['html'] = $str;
}
else
{
$image['src']['html'] = false;
}
return $image;
}
/**
* Get the Image HTML Source Set
*
* A set of images which are displayed according to conditions set.
*
* <!-- show the larger version when the display is < 800px wide -->
* <picture>
* <source
* srcset="/media/image-800x600.jpg" media="(max-width: 799px)">
* <img src="/media/image-150x100.jpg" />
* </picture>
*
* @param array $item
* @param array $items
* @param array $page
*
* @return array
*/
private function getImageHtmlSrcSet( $item )
{
$item['out']['image']['html'] = null;
if( isset( $item['in']['image'] ) && isset( $item['out']['image'] ) )
{
$str = '';
$str .= sprintf( '<figure class="media image">%s', PHP_EOL );
// original, renamed image...
$str .= 1 ? sprintf( '<a href="%s">%s', $item['out']['src'], PHP_EOL ) : '';
$str .= 0 ? '<picture>' . PHP_EOL : '';
$str .= 0 ? '<source' . PHP_EOL : '';
$str .= 0 ? sprintf( 'srcset="%s"', $this->getImageSrcSet( $item, 2 ) ) : '';
$str .= 0 ? ' media="(max-width: 799px)">' . PHP_EOL : '';
$str .= '<img';
$str .= 0 ? sprintf( ' id="image-%s"', $item['out']['image']['id'] ) : '';
$str .= 0 ? sprintf( ' data-id="%s"', $item['out']['image']['id'] ) : '';
$str .= 1 && strlen( $item['out']['image']['class'] ) > 0 ? sprintf( ' class="%s"', $item['out']['image']['class'] ) : '';
$str .= 1 ? sprintf( ' src="%s"', $item['out']['image']['src'] ) : '';
$str .= 1 ? sprintf( ' alt="%s"', $item['out']['image']['alt'] ) : '';
$str .= 0 ? sprintf( ' onclick="newSlide(%s);return false;"', $item['out']['image']['id'] ) : '';
$str .= 1 ? ' ' . $item['out']['image']['dim']['attr'] : '';
$str .= ' />' . PHP_EOL;
$str .= 0 ? '</picture>' . PHP_EOL : '';
$str .= 1 ? '</a>' . PHP_EOL : '';
$str .= 1 ? $item['out']['image']['caption']['html'] : '';
$str .= '</figure>' . PHP_EOL;
$item['out']['image']['html'] = $str;
}
else
{
$item['out']['image']['html'] = false;
}
return $item;
}
/**
* Get Image Dimensions
*
* Assumes file exists.
*
* @link https://www.php.net/manual/en/function.exif-imagetype.php
*
* Index 2 (Type): 1 GIF, 2 JPEG, 3 PNG, 4 SWF, 5 PSD, 6 BMP, ..., 18 WEBP
*
* @param array $data
*
* @return array.
*/
private function getImageDimIn( $data )
{
$type = [ 1 => 'GIF', 2 => 'JPEG', 3 => 'PNG', 4 => 'SWF',
5 => 'PSD', 6 => 'BMP', 18 => 'WEBP', ];
// Set the values to null.
$data['image']['dim']['width'] = null;
$data['image']['dim']['height'] = null;
$data['image']['dim']['attr'] = null;
$data['image']['dim']['text'] = null;
$data['image']['type']['int'] = null;
$data['image']['type']['text'] = null;
if( isset( $data['mime']['main'] ) && 'image' == $data['mime']['main'] )
{
// Get the values, if available.
list (
$data['image']['dim']['width'],
$data['image']['dim']['height'],
$data['image']['type']['int'],
$data['image']['dim']['attr']
) = getimagesize( $data['file'] );
$data['image']['dim']['text'] = sprintf( '%sx%s',
$data['image']['dim']['width'], $data['image']['dim']['height'] );
$data['image']['type']['text'] = $type[ $data['image']['type']['int'] ];
}
else
{
$data['image']['dim']['width'] = false;
$data['image']['dim']['height'] = false;
$data['image']['dim']['attr'] = false;
$data['image']['dim']['text'] = false;
$data['image']['type']['int'] = false;
$data['image']['type']['text'] = false;
}
return $data;
}
/**
* Get Image Dimension(s) Out
*
* Calculates the one dimension based on the other and the aspect ratio.
* The image dimension will become the version key, as each image dimension
* will have information associated with it, that needs to follow it.
*
* @example w = h * a
*
* @example dimensions: sm, md, lg, xl
* @param array $data
*
* @return array.
*/
private function getImageDimOutWeb( $item )
{
if( isset( $item['in']['mime']['main'] ) && 'image' == $item['in']['mime']['main'] )
{
$item['out']['image']['dim']['text'] = $item['in']['image']['dim']['text'];
$item['out']['image']['dim']['attr'] = $item['in']['image']['dim']['attr'];
$item['out']['image']['alt'] = $item['in']['image']['alt'];
$item['out']['image']['class'] = $item['in']['image']['class'];
$sizes = $this->opts['image']['dim']['web'];
foreach ( $sizes as $key => $size )
{
$a = $item['in']['image']['aspect']['int'];
$item['out']['image']['ver'][$key]['w'] = (int)($size['h'] * $a );
$item['out']['image']['ver'][$key]['h'] = (int)$size['h'];
$item['out']['image']['ver'][$key]['text'] = sprintf(
'%sx%s',
$item['out']['image']['ver'][$key]['w'],
$item['out']['image']['ver'][$key]['h']
);
$item['out']['image']['ver'][$key]['attr'] = sprintf(
'width="%s" height="%s"',
$item['out']['image']['ver'][$key]['w'],
$item['out']['image']['ver'][$key]['h']
);
}
}
return $item;
}
/**
* Get Image Aspect Ratio
*
* Assumes file exists or image resource exists
*
* @example a = w / h
* @param array $data [int, text]
*
* @return array.
*/
private function getImageAspect( $data )
{
$data['image']['aspect']['int'] = null;
$data['image']['aspect']['text'] = null;
if( isset( $data['image']['dim']['width'] ) && isset( $data['image']['dim']['height'] ) )
{
$data['image']['aspect']['int'] = number_format(
$data['image']['dim']['width'] / $data['image']['dim']['height'], 3 );
$data['image']['aspect']['text'] = 'Aspect Ratio: '; $data['image']['aspect']['text'] .= $data['image']['dim']['width'];
}
else
{
$data['image']['aspect']['int'] = false;
$data['image']['aspect']['text'] = null;
}
return $data;
}
/**
* Get the Exif Data
*
* Get the exif data (and process as needed).
*
* @param array $data
*
* @return array
*/
private function getExifData( $data )
{
$data['exif']['data'] = null;
if( isset( $data['mime']['main'] ) && 'image' == $data['mime']['main'] )
{
$data['exif']['data'] = exif_read_data( $data['file'] );
}
else
{
$data['exif']['data'] = false;
}
return $data;
}
/**
* Get the Image Resolution Out
*
* Get the image resolution (if an image).
* Assume the file exists.
*
* @param array $data
*
* @return array
*/
private function getImageResIn( $data )
{
if( isset( $data['image']['resc'] ) )
{
$dpi = imageresolution( $data['image']['resc'] );
$data['image'] = $this->frmImageRes( $data['image'], $dpi );
}
return $data;
}
/**
* Format Image Resolution
*
* @param $image
*
* @return array
*/
private function frmImageRes( $image, $dpi = [])
{
$image['dpi']['text'] = null;
$image['dpi']['int'] = null; // filled, if both x and y are equal.
$image['dpi']['x'] = null;
$image['dpi']['y'] = null;
if( isset( $dpi[0] ) && isset( $dpi[1] ) )
{
$image['dpi']['x'] = $dpi[0];
$image['dpi']['y'] = $dpi[1];
if( $dpi[0] == $dpi[1] )
{
$image['dpi']['text'] = $dpi[0] . ' DPI';
$image['dpi']['int'] = $dpi[0];
}
else
{
$image['dpi']['text'] = false;
$image['dpi']['int'] = false;
}
}
return $image;
}
/**
* Get the Image Resolution Out
*
* Get the image resolution (if an image).
* Assume the file exists.
*
* @param array $data
*
* @return array
*/
private function getImageResOut( $item )
{
$dpi['lo'] = null;
$dpi['hi'] = null;
if( isset( $item['in']['mime']['main'] ) && 'image' == $item['in']['mime']['main'] )
{
if( isset( $this->opts['image']['dpi']['lo'] ) )
{
$dpi['lo'] = $this->opts['image']['dpi']['lo'];
$dpi['hi'] = $this->opts['image']['dpi']['hi'];
}
}
else
{
$dpi['lo'] = false;
$dpi['hi'] = false;
}
$item['out']['image']['dpi'] = $dpi;
return $item;
}
/**
* Get the Image DPI
*
* @example bytes 14-18 specify:
*
* @example byte 14: 01, X and Y density unit specifier (00: none, pixel ratios, 01: DPI,02: DPC)
* @example bytes 15-16: horizontal pixel density.
* @example byte 16-18: vertical pixel density
* @param array $data
*
* @return array
*/
private function getImageDPI( $data )
{
$dpi['x'] = null;
$dpi['y'] = null;
$dpi['squ'] = null;
if( isset( $data['file'] ) )
{
$file = fopen( $data['file'], 'r' );
$string = fread( $file, 20 );
fclose( $file );
$data = bin2hex( substr( $string, 14, 4 ) );
// These should be different.
$dpi['x'] = hexdec( substr( $data, 0, 4 ) );
// These should be different.
$dpi['y'] = hexdec( substr( $data, 0, 4 ) );
if( $dpi['x'] == $dpi['y'] )
{
$dpi['squ'] = true;
}
else {
$dpi['squ'] = false;
}
$dpi['text'] = $dpi['x'] . ' DPI';
}
$data['dpi'] = $dpi;
return $data;
}
/**
* Get the Image Class
*
* May be align-left, float-left, align-center, etc.
* May be the same for both input and output.
*
* @param array $item
*
* @return item
*/
private function getImageClass( $item )
{
if ( ! isset( $item['in']['image']['class'] ) )
{
$item['in']['image']['class'] = $this->opts['image']['class'];
$item['out']['image']['class'] = $item['in']['image']['class'];
}
return $item;
}
/**
* Get the Image Alt Text.
*
* May be the same as the name or title.
*
* @param array $image
*
* @return string
*/
private function getImageAlt( $item )
{
if ( isset( $item['in']['title'] ) && strlen( $item['in']['title'] ) > 0 )
{
$item['in']['image']['alt'] = $item['in']['title'];
$item['out']['image']['alt'] = $item['in']['image']['alt'];
}
return $item;
}
/**
* Get the Image Caption (HTML)
*
* @param array $item
*
* Need:
*
* Intent,
* Title,
* Dim: Width, Height,
* File Size
*
* @return array
*/
private function getImageCaption( $item )
{
$item['out']['image']['caption']['text'] = null;
$item['out']['image']['caption']['html'] = false;
if( isset( $item['in']['image'] ) && isset( $item['out']['image'] ) )
{
$text = '';
$html['open'] = '<figcaption class="text-center">';
$html['open'] .= '<small>(';
$text .= $item['in']['title'];
$text .= ' ' . $item['in']['image']['dim']['text'];
$text .= ' ' . $item['in']['size']['text'];
$html['close'] = ')</small>';
$html['close'] .= '</figcaption>' . PHP_EOL;
$item['out']['image']['caption']['text'] = $text;
$item['out']['image']['caption']['html'] = sprintf( '%s%s%s', $html['open'], $text, $html['close'] );
}
return $item;
}
/**
* Check Image Orientation
*
* @param array $data
*
* @return array
*/
private function chkImageOrt( $data )
{
$data['ort']['in'] = null;
$data['ort']['out'] = null;
if ( isset( $data['image']['resc'] ) && isset( $data['exif']['data']['Orientation'] ) )
{
$ort = $exif['Orientation'];
$data['ort']['in'] = $ort;
$data['ort']['out'] = $ort;
if ( $ort == 6 || $ort == 5 )
{
$data['image']['resc'] = imagerotate( $data['image']['resc'], 270, null );
$data['ort']['out'] = 270;
}
if ( $ort == 3 || $ort == 4 )
{
$data['image']['resc'] = imagerotate( $data['image']['resc'], 180, null );
$data['ort']['out'] = 180;
}
if ( $ort == 8 || $ort == 7 )
{
$data['image']['resc'] = imagerotate( $data['image']['resc'], 90, null );
$data['ort']['out'] = 90;
}
if ( $ort == 5 || $ort == 4 || $ort == 7 )
{
imageflip( $data['image']['resc'], IMG_FLIP_HORIZONTAL );
$data['ort']['out'] = 'flip_h';
}
}
return $data;
}
/**
* Set Scaled Images.
*
* @link https://www.php.net/manual/en/function.imagescale.php
*
* @example imagescale ( resource $data , int $new_width [, int
* $new_height = -1 [, int $mode = IMG_BILINEAR_FIXED ]] ) : resource
* @param array $data
* @param array $page
*
* @return array|false
*/
private function setScaledImages( $item )
{
/** Calls the function if it is available and is switched on. */
if ( $this->opts['images']['scale']
&& isset( $data['name'] )
&& null !== $data['name'] )
{
$cnt = 0;
$scaled = [];
$scaled['name'] = $data['name'];
$sizes = $this->opts['image']['sizes']['height'];
foreach ( $this->opts['images']['sizes']['height'] as $size => $item )
{
if ( $item['use'] )
{
// Initialize.
$scaled['resc'] = null;
$scaled['path'] = '';
// Extension
$scaled['ext'] = $this->opts['image']['ext'];
// Directory
$scaled['path'] = $data['path'] . '/' . $size;
// Name
$scaled['file'] = $scaled['path'] . '/' . $scaled['name'];
// Size and extension
$scaled['file'] .= '-' . $sizes[ $size ] . '.' . $scaled['ext'];
if( ! file_exists( $scaled['file'] ) )
{
if( isset( $data['image']['resc'] ) )
{
imageresolution( $data['image']['resc'], $this->opts['image']['res'] );
$scaled['resc'] = imagescale(
$data['image']['resc'], $data['width'], $data['height'] );
}
}
else
{
$data['exists'] = true;
}
}
}
}
return $data;
}
/**
* Print Image to Disk
*
* @param array $data
*
* @return null|bool
*/
private function printImageDisk( $item )
{
$data['resp'] = null;
if ( isset( $item['in']['image']['resc'] ) )
{
foreach( $item['out']['image']['dim']['lo'] as $dim )
{
if( 'png' == $item['in']['mime']['sub'] )
{
$data = $this->printImagePNG( $item['out'] );
}
else
{
$data = $this->printImageJPG( $item['out'] );
}
imagedestroy( $item['out']['image']['resc'] );
unset( $item['out']['image']['resc'] );
$item['out']['image']['resc'] = null;
}
return $data;
}
else
{
return false;
}
}
/**
* Convert JPG Quality Paramter to PNG
*
* The JPG quality parameter ranges from 0 to 100, with 100 being high.
* The PNG compression parameter ranges from 0 to 9, where 0 is no
* compression and 9 is maximum compression.
*
* @param array $data
*/
private function cnvQuaCmpJpgPng( $data )
{
// Low compression = higher file size.
$data['png']['cmp']['lo'] = null;
// High compression = lower file size.
$data['png']['cmp']['hi'] = null;
if( isset( $data['jpg']['qua']['hi'] ) )
{
$data['png']['cmp']['lo'] = $this->cnvQuaToCmp( $data['jpg']['qua']['hi'] );
$data['png']['cmp']['hi'] = $this->cnvQuaToCmp( $data['jpg']['qua']['lo'] );
}
return $data;
}
/**
* Convert JPG Quality to PNG Compression
*
* PNG Compression is the inverse of JPG quality and 1/10th of it.
*
* @param int $quality
*
* @return int
*/
private function cnvQuaToCmp( $quality = 100 )
{
return number_format( 1 / ( $quality / 10 ), 0 );
}
/**
* Put Image JPG
*
* Note differences between PNG and JPG.
* Quality: Hi 90 / Lo 75
*
* @param array $data
*
* @return null|bool
*/
private function printImageJPG( $data )
{
$data['resp'] = null;
header( 'Content-Type: image/jpeg' );
$data['resp']['out']['hi'] = imagejpeg( $data['image']['resc'], $data['file'], $data['dpi']['hi'] );
$data['resp']['out']['lo'] = imagejpeg( $data['image']['resc'], $data['file'], $data['dpi']['lo'] );
return $data;
}
/**
* Put Image PNG
*
* Note differences between PNG and JPG.
*
* @param array $data
*
* @return null|bool
*/
private function printImagePNG( $data )
{
$data['resp'] = null;
header( 'Content-Type: image/png' );
$data['resp']['out']['hi'] = imagepng( $data['image']['resc'], $data['file'], $data['res']['qua']['hi'] );
$data['resp']['out']['lo'] = imagepng( $data['image']['resc'], $data['file'], $data['res']['qua']['lo'] );
return $data;
}
//
/**
* Get Item Serial
*
* Assumes file exists.
*
* @param array $item
*
* @return array.
*/
private function getItemSerial( $item )
{
$item['serial'] = null;
if( isset( $item['ctime']['int'] ) )
{
$item['serial'] = $item['ctime']['int'];
}
return $item;
}
/**
* Get Item ID
*
* Assumes file exists.
*
* @param array $item
*
* @return array.
*/
private function getItemID( $item, $cnt )
{
$item['id'] = null;
if( isset( $item['ctime']['int'] ) )
{
$item['id'] = date('Y-m-j', $item['ctime']['int'] );
}
return $item;
}
//
/**
* Generates the file
*
* @param array $page
*
* @return string
*/
private function genFile( $page )
{
$page['text'] = '';
if( is_array( $page ) )
{
$page = $this->getPageHeader( $page );
$page = $this->getFileBodyPHP( $page );
$page = $this->getFileSize( $page );
$page = $this->getFileFooter( $page );
}
return $page;
}
/**
* Generate Specifications (Structural)
*
* @param array $page
*
* @return array
*/
private function genSpecs( $page, $data )
{
$str = '';
$strValue = '';
if( is_array( $data ) && count( $data ) > 0 )
{
foreach( $data as $selector => $properties )
{
if( 'type' == $selector || 'use' == $selector )
{
continue;
}
// always use a media selector to block out sections.
if( 'media' == $selector )
{
$str .= sprintf( '@media %s {%s', $properties, PHP_EOL );
}
else
{
if( is_array( $properties )
&& count( $properties ) > 0 )
{
$str .= sprintf( ' %s {%s', $selector, PHP_EOL );
foreach( $properties as $key => $value )
{
if( strlen( $value ) > 0 )
{
$str .= sprintf( ' %s: %s;%s', $key, $value, PHP_EOL );
}
}
$str .= ' }' . PHP_EOL;
$str .= PHP_EOL;
}
}
}
// Close media selector.
$str .= '}' . PHP_EOL;
}
$page['text'] .= $str;
return $page;
}
/**
* Get File Size
*
* @param array $page
*
* @return array
*/
private function getFileSize( $page )
{
$page['size'] = null;
if( isset( $page['text'] ) )
{
$page['size'] = strlen( $page['text'] );
}
return $page;
}
/**
* Optimize Image
*
* @param array $page
*
* @return array
*/
function optimizeImage( $page )
{
return $page;
}
/**
* isCopy
*
* Check if a copy should be performed
*
* @return bool
*/
private function isCopy()
{
if ( isset( $_GET['copy'] ) && isset( $_POST['safety'] ) )
{
return true;
}
else
{
return false;
}
}
/**
* Copy File
*
* @param array $item
*
* @return array
*/
private function copyFile( $item )
{
$resp = [];
if( isset( $data ) )
{
$resp[$cnt] = copy(
$data['file'],
$file['out']['file']
);
}
$page['data']['out']['resp'] = $resp;
}
/**
* isPrint
*
* Check if a print should be performed based on server variables set.
*
* @return bool
*/
private function isPrint()
{
if ( isset( $_GET['print'] ) && isset( $_POST['safety'] ) )
{
return true;
}
else
{
return false;
}
}
/**
* Check the Directory
*
* Exists and is Writable
*
* @link https://www.php.net/manual/en/function.is-writable.php
* is_writable(): The results of this function are cached. See
* clearstatcache() for more details.
*
* @param array $data
*
* @return array|false
*/
private function chkDir( $data )
{
if( isset( $data['path'] ) )
{
if ( ! is_dir( $data['path'] ) )
{
// chmod...
if( mkir( $data['path'] ) )
{
return true;
}
}
if( ! is_writable( $data['path'] ) )
{
// make writable (permissions).
}
// Check again
if( is_dir( $data['path'] ) && is_writable( $data['path'] ) )
{
return true;
}
else
{
return false;
}
}
else
{
exit( "Not set: item['out']['path']" );
}
}
/**
* Check Item
*
* A basic check here. Add if needed.
*
* @param string $item
*
* @return bool
*/
private function chkItem( $item )
{
if( is_array( $item ) && isset( $item['in']['file'] ) )
{
return true;
}
else
{
return false;
}
}
/**
* Get File Out Name
*
* @param array $page
*
* @return array
*/
private function getFileOutName( $page, $item )
{
if( $item['in'] = $this->chkFileInName( $item['in'] ) )
{
$data['name'] = $this->bldFileOutName( $item );
$data['file'] = $page['path']['out'];
$data['file'] .= '/' . $data['name'];
$data['file'] .= '.' . $item['in']['ext'];
$item['out']['name'] = $data['name'];
$item['out']['namext'] = $data['name'] . '.' . $item['in']['ext'];
$item['out']['path'] = $page['path']['out'];
$item['out']['file'] = $data['file'];
$item['out']['src'] = str_replace( $page['path']['root'], '', $data['file'] );
$item['out']['rel'] = str_replace( $page['path']['root'], '', $page['path']['out'] );
}
return $item;
}
/**
* Build File Out Name
*
* This does not check to ensure that the resolution (in DPI) given is
* the actual resolution of the image. The resolution used is web based.
*
* @param array $item
*
* @return string
*/
private function bldFileOutName( $item )
{
$str = '';
$str .= $this->opts['initials'];
$str .= '-' . $item['in']['prod']['type'];
$str .= '-' . date( 'Ym', $item['in']['mtime']['int'] );
$str .= '-' . $item['in']['cnt'];
$str .= '-' . $this->opts['image']['dpi']['lo'];
$str .= '-' . $item['in']['image']['dim']['text'];
return $str;
}
/**
* Check File Out Name
*
* @param array $item
*
* @return array|bool
*/
private function chkFileInName( $data )
{
if( isset( $this->opts['initials'] )
&& isset( $data['prod']['type'] )
&& isset( $data['ctime']['int'] )
&& isset( $data['image']['dim'] )
&& isset( $data['id'] )
)
{
return $data;
}
else
{
return false;
}
}
/**
* Get File Name
*
* Get (build) the (new) file name.
*
* @param array $file
*
* @return array
*/
private function getItemFileName( $page, $item )
{
}
/**
* Check if Print is Authorized.
*
* @param array $data
*
* @return array
*/
private function authPrint( $data )
{
if( isset( $data['file'] ) )
{
if( ! file_exists( $data['file'] ) || $this->opts['file']['overwrite'] )
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
/**
* Get Input Data
*
* @param array $page
*
* @return array
*/
private function getInputData( $page )
{
$str = '';
if( is_array( $page ) && count( $page ) > 0 )
{
// Count of the files.
$str .= isset( $page['data']['in']['cnt'] ) ?
sprintf( '<br>Files: %s<br>%s', $page['data']['in']['cnt'], PHP_EOL ) : '';
// Input file
$str .= isset( $page['file']['in'] ) ?
sprintf( '<br>Input: %s<br>%s', $page['file']['in'], PHP_EOL ) : '';
// Count of the data.
$str .= isset( $page['data'] ) && is_array( $page['data'] ) ?
sprintf( '<br>Count: %s<br>%s', count( $page['data'] ), PHP_EOL ) : '';
}
$page['text']['in'] .= $str;
return $page;
}
/**
* Create a New Image From the Original and Set its Resolution.
*
* Set the image resolution (if an image).
* Uses the image resource (not the file), for this.
* A new image resource is *NOT* created. Create a second image first, and
* then change the resolution on this, if the original needs to be retained.
*
* @param array $data
*
* @return array
*/
private function setImageResNew( $item )
{
$data['image']['dpi'] = null;
if( isset( $item['in']['image']['resc'] ) )
{
// Create a duplicate of the original FIRST.
$item['out']['image']['resc'] = $item['in']['image']['resc'];
// THEN change the resolution of this newly created image.
imageresolution( $item['out']['image']['resc'], $this->opts['image']['dpi']['lo']
);
}
else
{
$data['dpi'] = false;
}
// GET the NEW resolution from THAT image to ENSURE it worked.
$dpi = imageresolution( $item['out']['image']['resc'] );
// Format...
$item['out']['image'] = $this->frmImageRes( $item['out']['image'], $dpi );
return $item;
}
/**
* Set the Image Dimension By Height.
*
* Creates a *new* image resource from the given image resource. Since height
* is not the default initial parameter (width is), we have to calculate
* both height and width, as they both are then required if setting by
* height first.
*
* imagescale (
* resource $image,
* int $new_width
* [, int $new_height = -1
* [, int $mode = IMG_BILINEAR_FIXED ]]
* ) : resource
*
* @link https://www.php.net/manual/en/function.imagescale.php
*
* @param array $item
*
* @return array.
*/
private function setImageDim( $item )
{
if( isset( $item['in']['mime']['main'] ) && 'image' == $item['in']['mime']['main'] )
{
foreach( $item['out']['image']['dim'] as $key => $dim )
{
$item['out']['image'][$key]['resc'] = imagescale(
$item['in']['image']['resc'],
$dim['w'],
$dim['w']
);
}
}
return $item;
}
/*
"dim"]=>
array(4) {
["sm"]=>
array(2) {
["w"]=>
int(137)
["h"]=>
int(135)
}
*/
/**
* Image Crop Auto
*
* @link https://www.php.net/manual/en/function.imagecropauto.php
*
* color: Either an RGB color value or a palette index.
* Used only in IMG_CROP_THRESHOLD mode.
*
* @param $item
*
* @return
*/
private function cropImageAuto( $item )
{
$cropped_img_white = imagecropauto(
$original_img ,
IMG_CROP_THRESHOLD,
null,
16777215 // color (white0.
);
}
//
/**
* Page Header
*
* @param array $page
*
* @return array
*/
private function getPageHeader( $page )
{
// Initialize
$str = '';
$str .= '<?php' . PHP_EOL;
$str .= '/**' . PHP_EOL;
$str .= sprintf( ' * %s%s', $this->opts['page']['title'], PHP_EOL );
$str .= ' *' . PHP_EOL;
$str .= sprintf( ' * File: %s%s', $page['file']['name'], PHP_EOL );
$str .= $this->getTimeStamp();
$str .= $this->getIDStamp();
$str .= ' *' . PHP_EOL;
$str .= sprintf( ' * (By: %s)%s',
$this->opts['this']['file'], PHP_EOL );
$str .= ' */' . PHP_EOL;
$str .= 'namespace Earth3300\EC01;' . PHP_EOL;
$str .= PHP_EOL;
$str .= "if( ! defined( 'NDA' ) )" . PHP_EOL;
$str .= '{' . PHP_EOL;
$str .= " define( 'NDA', true );" . PHP_EOL;
$str .= '}' . PHP_EOL;
$str .= PHP_EOL;
$page['text'] = $str;
return $page;
}
/**
* File Header
*
* @return string
*/
private function getFileHeader( $page )
{
// Initialize
$str = '';
if( isset( $page['file']['name'] ) )
{
$str .= '/**' . PHP_EOL;
$str .= sprintf( ' * File: %s%s', $page['file']['name'], PHP_EOL );
$str .= sprintf( ' * Generated by: %s%s',
$this->opts['this']['file'], PHP_EOL );
$str .= ' *' . PHP_EOL;
$str .= $this->getTimeStamp();
$str .= $this->getIDStamp();
$str .= ' */' . PHP_EOL;
$str .= PHP_EOL;
}
$page['text'] = $str;
return $page;
}
/**
* Time Stamp (Including Created Date)
*
* @return string
*/
private function getTimeStamp()
{
$str = '';
$str .= sprintf( ' * Created: %s%s',
$this->opts['this']['date']['created'], PHP_EOL );
$str .= sprintf( ' * Updated: %s%s', date( 'Y-m-d' ), PHP_EOL );
$str .= sprintf( ' * Time: %s%s', date( 'H:i:s T' ), PHP_EOL );
return $str;
}
/**
* ID Stamp
*
* @return string
*/
private function getIDStamp()
{
$str = '';
$str .= ' * ID: ENG-ON-001' . PHP_EOL;
return $str;
}
/**
* File Footer
*
* For use at the end of the file as needed.
*/
private function getFileFooter( $page )
{
// Initialize
$str = '';
$str .= '/*';
$str .= ' End of File (';
$str .= $page['size'] . ' B). ';
$str .= '*/' . PHP_EOL;
$str .= PHP_EOL;
// Add this string to the end...
$page['text'] .= $str;
return $page;
}
/**
* Get the "Main" HTML
*
* Main Html. This may be written by a script that has semi-intelligent
* linguistic capabilities. It may require some interpretation. A knowledge
* of Eygtian heiroglyphs would be an asset.
*
* @param array $page
*
* @return array
*/
private function getMainHTML( $page )
{
$str = '';
$str .= '<main>' . PHP_EOL;
$str .= sprintf( '<h1>%s</h1>%s', $this->opts['this']['title'], PHP_EOL );
$str .= $this->getForm();
$str .= isset( $page['env']['html'] ) ? $page['env']['html'] : exit( "page['env']['html']" );
$str .= isset( $page['data']['in']['html'] ) ? $page['data']['in']['html'] : exit( "page['data']['in']['html']" );
$str .= isset( $page['data']['out']['html'] ) ? $page['data']['out']['html'] : exit( "page['data']['out']['html']" );
// $str .= isset( $page['data']['resp']['html'] ) ? $page['data']['resp']['html'] : exit( "page['data']['resp']['html']" );
if( isset( $_GET['display'] ) )
{
if( isset( $page['text'] ) )
{
$str .= '<pre>' . PHP_EOL;
$str .= $page['text'];
$str .= '</pre>' . PHP_EOL;
}
}
$str .= '</main>' . PHP_EOL;
$page['html']['main'] = $str;
return $page;
}
/**
* Get Section HTML
*
* Section Html. A specific section on the page.
*
* @param array $page
*
* @return array
*/
private function getSectionHTML( $page )
{
$str = '';
// Section used here.
$str .= '<section>' . PHP_EOL;
$str .= '</section>' . PHP_EOL;
return $str;
}
/**
* Get Form
*
* @return string
*/
private function getForm()
{
if( isset( $_GET['ctrls'] ) )
{
// Initialize
$str = '';
$str .= '<form action="" method="post">' . PHP_EOL;
$str .= '<div>' . PHP_EOL;
$str .= '<input type="checkbox" name="safety" id="safety" required> ' . PHP_EOL;
$str .= '<input type="submit" class="btn btn-primary" value="Run">' . PHP_EOL;
$str .= '</div>' . PHP_EOL;
$str .= '</form>' . PHP_EOL;
return $str;
}
else
{
return false;
}
}
/**
* Get Env HTML
*
* Wrap the environmental data in HTML for display.
*
* @param array $page
*
* @return array
*/
private function getEnvHTML( $page )
{
$page['env']['html'] = null;
$str = '';
if( is_array( $page ) && count( $page ) > 0 )
{
if( isset( $page['env'] ) )
{
$str .= '<section>' . PHP_EOL;
$str .= '<h3>Environment</h3>' . PHP_EOL;
$str .= sprintf( '<strong>Path In</strong>: %s<br>%s', $page['path']['in'], PHP_EOL );
$str .= sprintf( '<strong>Readable</strong>: %s<br>%s', $this->strBool( $page['env']['path']['in']['readable'] ), PHP_EOL );
$str .= sprintf( '<strong>Path Out</strong>: %s<br>%s', $page['path']['out'], PHP_EOL );
$str .= sprintf( '<strong>Writable</strong>: %s<br>%s', $this->strBool( $page['env']['path']['out']['writable'] ), PHP_EOL );
$str .= '</p>' . PHP_EOL;
$str .= '</section>' . PHP_EOL;
}
}
$page['env']['html'] = $str;
return $page;
}
/**
* String Bool
*
* @param bool
*
* @return string
*/
private function strBool( $boolean, $type = 0 )
{
$str = null;
$boolean = boolval( $boolean );
if( 0 == $type )
{
$str = $boolean ? 'Yes' : 'No';
}
elseif( 1 == $type )
{
$str = $boolean ? 'true' : 'false';
}
else
{
$str = $boolean ? '1' : '0';
}
return $str;
}
/**
* Get Data In HTML
*
* Further Process the Data In HTML, and add to it as necessary.
*
* @param array $page
*
* @return array
*/
private function getDataInHTML( $page )
{
$str = '';
if( is_array( $page ) && count( $page ) > 0 )
{
if( isset( $page['data']['in']['cnt'] ) )
{
$str .= '<section>' . PHP_EOL;
$str .= '<h3>Input</h3>' . PHP_EOL;
$str .= sprintf( 'Count: %s%s', $page['data']['in']['cnt'], PHP_EOL );
$str .= '<ol>' . PHP_EOL;
foreach( $page['items'] as $cnt => $item )
{
$str .= '<li>';
$str .= sprintf( '%s<br>%s', $item['in']['file'], PHP_EOL );
if( isset( $item['in'] ) )
{
$data = $item['in'];
$str .= sprintf( '&nbsp;%s &nbsp;%s &nbsp;%s',
$item['in']['size']['text'],
$data['image']['dim']['text'],
$data['image']['dpi']['text'] );
if( isset( $data['image']['exif']['data'] ) )
{
$str .= sprintf( ' &nbsp;%s &nbsp;%s',
$data['image']['exif']['data']['COMPUTED']['ApertureFNumber'],
$data['image']['exif']['data']['ExposureTime'] );
}
$str .= PHP_EOL;
}
$str .= '</li>' . PHP_EOL;
}
$str .= '</ol>' . PHP_EOL;
$str .= '</section>' . PHP_EOL;
}
}
$page['data']['in']['html'] = $str;
return $page;
}
/**
* Get Data Out HTML
*
* Further Process the Data Out HTML, and add to it as necessary.
*
* @param array $page
*
* @return array
*/
private function getDataOutHTML( $page )
{
$str = '';
$page['data']['out']['html'] = null;
if( is_array( $page ) && count( $page ) > 0 )
{
if( isset( $page['items'] ) && isset( $page['data']['out']['cnt'] ) )
{
$str .= '<section>' . PHP_EOL;
$str .= '<h3>Output</h3>' . PHP_EOL;
$str .= sprintf( 'Count: %s%s', $page['data']['out']['cnt'], PHP_EOL );
$str .= '<ol>' . PHP_EOL;
foreach( $page['items'] as $item )
{
$str .= '<li>' . $item['out']['file'] . '<br>' . PHP_EOL;
foreach( $item['out'] as $data )
{
echo "data out: ";
//$str .= '$item['out']['file'] . '<br>' . PHP_EOL;
}
}
$str .= '</ol>' . PHP_EOL;
$str .= '</section>' . PHP_EOL;
}
}
$page['data']['out']['html'] = $str;
return $page;
}
/**
* Get Response HTML
*
* @param array $page
*
* @return array
*/
private function getRespHTML( $page )
{
$page['data']['resp']['html'] = null;
$str = '';
$str .= '<section>' . PHP_EOL;
if( is_array( $page ) && count( $page ) > 0 )
{
// Count of the files.
$str .= isset( $page['files']['cnt'] ) ?
sprintf( '<br>Files: %s<br>%s', $page['cnt'], PHP_EOL ) : '';
// Length of the files.
$str .= isset( $page['resp']['html'] ) ?
sprintf( '<br>Resp: %s<br>%s', $page['resp']['html'], PHP_EOL ) : '';
}
$str .= '</section>' . PHP_EOL;
$page['data']['resp']['html'] .= $str;
return $page;
}
/**
* Wrap the HTML in Page HTML `<!DOCTYPE html>`, etc.
*
* Use basic settings. Assume no SEO necessary. Bootstrap CSS only.
*
* @param string $html
*
* @return string|bool
*/
private function getPageHTML( $page )
{
$str = '<!DOCTYPE html>' . PHP_EOL;
$str .= '<html lang="en-CA" class="dark">' . PHP_EOL;
$str .= '<head>' . PHP_EOL;
$str .= '<meta charset="UTF-8">' . PHP_EOL;
$str .= '<meta name="viewport" content="width=device-width, initial-scale=1"/>' . PHP_EOL;
$str .= sprintf( '<title>%s</title>%s',
$this->opts['this']['title'], PHP_EOL );
$str .= '<meta name="robots" content="noindex,nofollow" />' . PHP_EOL;
$str .= '<link rel=stylesheet href="/style.all.css">' . PHP_EOL;
$str .= '</head>' . PHP_EOL;
$str .= '<body>' . PHP_EOL;
$str .= $page['html']['main'];
$str .= '</html>' . PHP_EOL;
$page['html']['page'] = $str;
return $page;
}
} // End Class
if ( ! function_exists( 'pre_dump' ) ) {
/** Dumps a formatted string or array. */
function pre_dump( $arr, $continue = 1 ) {
if ( isset( $_GET['debug'] ) ) {
if (is_string( $arr ) ) {
$arr = str_replace( ['<','>'], ['&lt','&gt'], $arr );
}
echo "<pre>" . PHP_EOL;
var_dump( $arr );
if ( isset( $_GET['exit'] ) || ! $continue ) {
exit( '<br/>' . 'Done.' );
}
echo "</pre>" . PHP_EOL;
}
}
}
function ec01_image_printer()
{
$printer = new ImagePrinter();
return $printer->init();
}
ec01_image_printer();
/*
Notes:
@link https://stackoverflow.com/questions/40568272/
The ideal is to have the DPI of the device that created the image the same
as the device that displays it. No interpolation is necessary, so it is the
fastest way to display it. And every pixel in the source image is a 1-to-1
match with the pixel on the display device so it is very sharp with no
artifacts. It is just not a very practical ideal since you can't always
control what devices where used. Never practical when it was a scanner
or camera. Could be practical if it was made with a painting program since
you might favor the sharpness of the displayed image. That's however rapidly
fading as an option as well with hi res monitors becoming more common,
dealing with unpredictable window content size is pretty difficult.
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment