Skip to content

Instantly share code, notes, and snippets.

@695Multimedia
Last active July 22, 2018 21:27
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 695Multimedia/7117003 to your computer and use it in GitHub Desktop.
Save 695Multimedia/7117003 to your computer and use it in GitHub Desktop.
ImageUtil is a PHP class for intelligently resizing images.** cropScale: Given a 640 x 480 image and 240 x 240 target dimension, the image will first be scaled to 320 x 240, then center-cropped to 240 x 240. (compares scale factor of both dimensions and picks closest value to original then center-crops the other)** fitScale: The same image and t…
<?
require('ImageUtil.class.php');
$imageUtil = new ImageUtil();
$imageUtil->loadImage('path/to/photo.jpg');
// center-crop image to 310x50
$imageUtil->crop(310,50,'center','center');
// other sizing/cropping examples:
// crop image to 310x50 starting from x:80, y:100
// $imageUtil->crop(310,50,80,100);
// crop-scale image into 200x200. This mode will always result in output exactly the size spec'd
// $imageUtil->cropScale(200,200);
// fit-scal image into 200X200. This mode will result in image no larger than 200x200, but if source image not square,
// the shorter dimension will be less than spec'd
// $imageUtil->fitScale(200,200);
// uses defaults to write output to browser (format: jpeg, quality: 75%)
$imageUtil->writeImage();
// other write examples
// write 60% quality jpeg to file
// $imageUtil->writeImage('path/to/output.jpg',ImageUtil::JPEG,60);
// write 90% quality png to browser
// $imageUtil->writeImage(NULL,ImageUtil::PNG,90);
// write gif to file (GIF writes ignore quality setting)
// $imageUtil->writeImage('path/to/output.gif',ImageUtil::GIF);
?>
<?php
/*
*------------------------------------------------------------
* BMP Image functions
*------------------------------------------------------------
* By JPEXS
*/
/*
*------------------------------------------------------------
* ImageBMP
*------------------------------------------------------------
* - Creates new BMP file
*
* Parameters: $img - Target image
* $file - Target file to store
* - if not specified, bmp is returned
*
* Returns: if $file specified - true if OK
if $file not specified - image data
*/
function imagebmp($img,$file="",$RLE=0)
{
$ColorCount=imagecolorstotal($img);
$Transparent=imagecolortransparent($img);
$IsTransparent=$Transparent!=-1;
if($IsTransparent) $ColorCount--;
if($ColorCount==0) {$ColorCount=0; $BitCount=24;};
if(($ColorCount>0)and($ColorCount<=2)) {$ColorCount=2; $BitCount=1;};
if(($ColorCount>2)and($ColorCount<=16)) { $ColorCount=16; $BitCount=4;};
if(($ColorCount>16)and($ColorCount<=256)) { $ColorCount=0; $BitCount=8;};
$Width=imagesx($img);
$Height=imagesy($img);
$Zbytek=(4-($Width/(8/$BitCount))%4)%4;
if($BitCount<24) $palsize=pow(2,$BitCount)*4;
$size=(floor($Width/(8/$BitCount))+$Zbytek)*$Height+54;
$size+=$palsize;
$offset=54+$palsize;
// Bitmap File Header
$ret = 'BM'; // header (2b)
$ret .= int_to_dword($size); // size of file (4b)
$ret .= int_to_dword(0); // reserved (4b)
$ret .= int_to_dword($offset); // byte location in the file which is first byte of IMAGE (4b)
// Bitmap Info Header
$ret .= int_to_dword(40); // Size of BITMAPINFOHEADER (4b)
$ret .= int_to_dword($Width); // width of bitmap (4b)
$ret .= int_to_dword($Height); // height of bitmap (4b)
$ret .= int_to_word(1); // biPlanes = 1 (2b)
$ret .= int_to_word($BitCount); // biBitCount = {1 (mono) or 4 (16 clr ) or 8 (256 clr) or 24 (16 Mil)} (2b)
$ret .= int_to_dword($RLE); // RLE COMPRESSION (4b)
$ret .= int_to_dword(0); // width x height (4b)
$ret .= int_to_dword(0); // biXPelsPerMeter (4b)
$ret .= int_to_dword(0); // biYPelsPerMeter (4b)
$ret .= int_to_dword(0); // Number of palettes used (4b)
$ret .= int_to_dword(0); // Number of important colour (4b)
// image data
$CC=$ColorCount;
$sl1=strlen($ret);
if($CC==0) $CC=256;
if($BitCount<24)
{
$ColorTotal=imagecolorstotal($img);
if($IsTransparent) $ColorTotal--;
for($p=0;$p<$ColorTotal;$p++)
{
$color=imagecolorsforindex($img,$p);
$ret.=inttobyte($color["blue"]);
$ret.=inttobyte($color["green"]);
$ret.=inttobyte($color["red"]);
$ret.=inttobyte(0); //RESERVED
};
$CT=$ColorTotal;
for($p=$ColorTotal;$p<$CC;$p++)
{
$ret.=inttobyte(0);
$ret.=inttobyte(0);
$ret.=inttobyte(0);
$ret.=inttobyte(0); //RESERVED
};
};
if($BitCount<=8)
{
for($y=$Height-1;$y>=0;$y--)
{
$bWrite="";
for($x=0;$x<$Width;$x++)
{
$color=imagecolorat($img,$x,$y);
$bWrite.=decbinx($color,$BitCount);
if(strlen($bWrite)==8)
{
$retd.=inttobyte(bindec($bWrite));
$bWrite="";
};
};
if((strlen($bWrite)<8)and(strlen($bWrite)!=0))
{
$sl=strlen($bWrite);
for($t=0;$t<8-$sl;$t++)
$sl.="0";
$retd.=inttobyte(bindec($bWrite));
};
for($z=0;$z<$Zbytek;$z++)
$retd.=inttobyte(0);
};
};
if(($RLE==1)and($BitCount==8))
{
for($t=0;$t<strlen($retd);$t+=4)
{
if($t!=0)
if(($t)%$Width==0)
$ret.=chr(0).chr(0);
if(($t+5)%$Width==0)
{
$ret.=chr(0).chr(5).substr($retd,$t,5).chr(0);
$t+=1;
}
if(($t+6)%$Width==0)
{
$ret.=chr(0).chr(6).substr($retd,$t,6);
$t+=2;
}
else
{
$ret.=chr(0).chr(4).substr($retd,$t,4);
};
};
$ret.=chr(0).chr(1);
}
else
{
$ret.=$retd;
};
if($BitCount==24)
{
for($z=0;$z<$Zbytek;$z++)
$Dopl.=chr(0);
for($y=$Height-1;$y>=0;$y--)
{
for($x=0;$x<$Width;$x++)
{
$color=imagecolorsforindex($img,ImageColorAt($img,$x,$y));
$ret.=chr($color["blue"]).chr($color["green"]).chr($color["red"]);
}
$ret.=$Dopl;
};
};
if($file!="")
{
$r=($f=fopen($file,"w"));
$r=$r and fwrite($f,$ret);
$r=$r and fclose($f);
return $r;
}
else
{
echo $ret;
};
};
/*
*------------------------------------------------------------
* ImageCreateFromBmp
*------------------------------------------------------------
* - Reads image from a BMP file
*
* Parameters: $file - Target file to load
*
* Returns: Image ID
*/
function imagecreatefrombmp($file)
{
global $CurrentBit, $echoMode;
$f=fopen($file,"r");
$Header=fread($f,2);
if($Header=="BM")
{
$Size=freaddword($f);
$Reserved1=freadword($f);
$Reserved2=freadword($f);
$FirstByteOfImage=freaddword($f);
$SizeBITMAPINFOHEADER=freaddword($f);
$Width=freaddword($f);
$Height=freaddword($f);
$biPlanes=freadword($f);
$biBitCount=freadword($f);
$RLECompression=freaddword($f);
$WidthxHeight=freaddword($f);
$biXPelsPerMeter=freaddword($f);
$biYPelsPerMeter=freaddword($f);
$NumberOfPalettesUsed=freaddword($f);
$NumberOfImportantColors=freaddword($f);
if($biBitCount<24)
{
$img=imagecreate($Width,$Height);
$Colors=pow(2,$biBitCount);
for($p=0;$p<$Colors;$p++)
{
$B=freadbyte($f);
$G=freadbyte($f);
$R=freadbyte($f);
$Reserved=freadbyte($f);
$Palette[]=imagecolorallocate($img,$R,$G,$B);
};
if($RLECompression==0)
{
$Zbytek=(4-ceil(($Width/(8/$biBitCount)))%4)%4;
for($y=$Height-1;$y>=0;$y--)
{
$CurrentBit=0;
for($x=0;$x<$Width;$x++)
{
$C=freadbits($f,$biBitCount);
imagesetpixel($img,$x,$y,$Palette[$C]);
};
if($CurrentBit!=0) {freadbyte($f);};
for($g=0;$g<$Zbytek;$g++)
freadbyte($f);
};
};
};
if($RLECompression==1) //$BI_RLE8
{
$y=$Height;
$pocetb=0;
while(true)
{
$y--;
$prefix=freadbyte($f);
$suffix=freadbyte($f);
$pocetb+=2;
$echoit=false;
if($echoit)echo "Prefix: $prefix Suffix: $suffix<BR>";
if(($prefix==0)and($suffix==1)) break;
if(feof($f)) break;
while(!(($prefix==0)and($suffix==0)))
{
if($prefix==0)
{
$pocet=$suffix;
$Data.=fread($f,$pocet);
$pocetb+=$pocet;
if($pocetb%2==1) {freadbyte($f); $pocetb++;};
};
if($prefix>0)
{
$pocet=$prefix;
for($r=0;$r<$pocet;$r++)
$Data.=chr($suffix);
};
$prefix=freadbyte($f);
$suffix=freadbyte($f);
$pocetb+=2;
if($echoit) echo "Prefix: $prefix Suffix: $suffix<BR>";
};
for($x=0;$x<strlen($Data);$x++)
{
imagesetpixel($img,$x,$y,$Palette[ord($Data[$x])]);
};
$Data="";
};
};
if($RLECompression==2) //$BI_RLE4
{
$y=$Height;
$pocetb=0;
/*while(!feof($f))
echo freadbyte($f)."_".freadbyte($f)."<BR>";*/
while(true)
{
//break;
$y--;
$prefix=freadbyte($f);
$suffix=freadbyte($f);
$pocetb+=2;
$echoit=false;
if($echoit)echo "Prefix: $prefix Suffix: $suffix<BR>";
if(($prefix==0)and($suffix==1)) break;
if(feof($f)) break;
while(!(($prefix==0)and($suffix==0)))
{
if($prefix==0)
{
$pocet=$suffix;
$CurrentBit=0;
for($h=0;$h<$pocet;$h++)
$Data.=chr(freadbits($f,4));
if($CurrentBit!=0) freadbits($f,4);
$pocetb+=ceil(($pocet/2));
if($pocetb%2==1) {freadbyte($f); $pocetb++;};
};
if($prefix>0)
{
$pocet=$prefix;
$i=0;
for($r=0;$r<$pocet;$r++)
{
if($i%2==0)
{
$Data.=chr($suffix%16);
}
else
{
$Data.=chr(floor($suffix/16));
};
$i++;
};
};
$prefix=freadbyte($f);
$suffix=freadbyte($f);
$pocetb+=2;
if($echoit) echo "Prefix: $prefix Suffix: $suffix<BR>";
};
for($x=0;$x<strlen($Data);$x++)
{
imagesetpixel($img,$x,$y,$Palette[ord($Data[$x])]);
};
$Data="";
};
};
if($biBitCount==24)
{
$img=imagecreatetruecolor($Width,$Height);
$Zbytek=$Width%4;
for($y=$Height-1;$y>=0;$y--)
{
for($x=0;$x<$Width;$x++)
{
$B=freadbyte($f);
$G=freadbyte($f);
$R=freadbyte($f);
$color=imagecolorexact($img,$R,$G,$B);
if($color==-1) $color=imagecolorallocate($img,$R,$G,$B);
imagesetpixel($img,$x,$y,$color);
}
for($z=0;$z<$Zbytek;$z++)
freadbyte($f);
};
};
return $img;
};
fclose($f);
};
/*
* Helping functions:
*-------------------------
*
* freadbyte($file) - reads 1 byte from $file
* freadword($file) - reads 2 bytes (1 word) from $file
* freaddword($file) - reads 4 bytes (1 dword) from $file
* freadlngint($file) - same as freaddword($file)
* decbin8($d) - returns binary string of d zero filled to 8
* RetBits($byte,$start,$len) - returns bits $start->$start+$len from $byte
* freadbits($file,$count) - reads next $count bits from $file
* RGBToHex($R,$G,$B) - convert $R, $G, $B to hex
* int_to_dword($n) - returns 4 byte representation of $n
* int_to_word($n) - returns 2 byte representation of $n
*/
function freadbyte($f)
{
return ord(fread($f,1));
};
function freadword($f)
{
$b1=freadbyte($f);
$b2=freadbyte($f);
return $b2*256+$b1;
};
function freadlngint($f)
{
return freaddword($f);
};
function freaddword($f)
{
$b1=freadword($f);
$b2=freadword($f);
return $b2*65536+$b1;
};
function RetBits($byte,$start,$len)
{
$bin=decbin8($byte);
$r=bindec(substr($bin,$start,$len));
return $r;
};
$CurrentBit=0;
function freadbits($f,$count)
{
global $CurrentBit,$SMode;
$Byte=freadbyte($f);
$LastCBit=$CurrentBit;
$CurrentBit+=$count;
if($CurrentBit==8)
{
$CurrentBit=0;
}
else
{
fseek($f,ftell($f)-1);
};
return RetBits($Byte,$LastCBit,$count);
};
function RGBToHex($Red,$Green,$Blue)
{
$hRed=dechex($Red);if(strlen($hRed)==1) $hRed="0$hRed";
$hGreen=dechex($Green);if(strlen($hGreen)==1) $hGreen="0$hGreen";
$hBlue=dechex($Blue);if(strlen($hBlue)==1) $hBlue="0$hBlue";
return($hRed.$hGreen.$hBlue);
};
function int_to_dword($n)
{
return chr($n & 255).chr(($n >> 8) & 255).chr(($n >> 16) & 255).chr(($n >> 24) & 255);
}
function int_to_word($n)
{
return chr($n & 255).chr(($n >> 8) & 255);
}
function decbin8($d)
{
return decbinx($d,8);
};
function decbinx($d,$n)
{
$bin=decbin($d);
$sbin=strlen($bin);
for($j=0;$j<$n-$sbin;$j++)
$bin="0$bin";
return $bin;
};
function inttobyte($n)
{
return chr($n);
};
//***************************************************************************
//***************************************************************************
//END BMP FUNCTIONS
//***************************************************************************
//***************************************************************************
?>
<?php
/**
** Written by Steven Settlemyre
** http://sixninefive.com
**
** class: ImageUtil
** description: Utility class for scaling and cropping images
*/
class ImageUtil{
public $dstImg;
public $srcImg;
public $width;
public $height;
public $srcImgProps;
const CROP_SCALE = "cropScale";
const FIT_SCALE = "fitScale";
const CROP = "crop";
const JPEG = "jpeg";
const GIF = "gif";
const PNG = "png";
// shortcut method. kinda...
public function resize($newWidth='',$newHeight='',$mode='cropScale'){
switch($mode){
case self::FIT_SCALE:
$this->fitScale($newWidth,$newHeight);
break;
case self::CROP:
$this->crop($newWidth,$newHeight,'center','center');
break;
case self::CROP_SCALE:
default:
$this->cropScale($newWidth,$newHeight);
break;
}
}
// will resize an image to fit within the given dimensions while preserving aspect ratio
// Example: source dimensions - 600x200
// target dimensions - 300x300
// result dimensions - 300x100 (scaled by .5)
public function fitScale($newWidth,$newHeight){
// get sizes of source image
$src_w = imagesx($this->srcImg);
$src_h = imagesy($this->srcImg);
// see which way to scale
$scale = min($newWidth/$src_w,$newHeight/$src_h);
// if image larger than dimensions
if($scale <= 1){
$tmp_w = $src_w*$scale;
$tmp_h = $src_h*$scale;
// if dimensions larger than image (dont scale up)
}else{
$tmp_w = $src_w;
$tmp_h = $src_h;
}
$this->dstImg = imagecreatetruecolor($tmp_w,$tmp_h);
imagecopyresampled($this->dstImg,$this->srcImg,0,0,0,0,$tmp_w,$tmp_h,$src_w,$src_h);
}
// will resize image to fill the target space with best fit, cropping the larger dimension
public function cropScale($newWidth,$newHeight){
// get sizes of source image
$src_w = imagesx($this->srcImg);
$src_h = imagesy($this->srcImg);
// see which way to scale
$scale = max($newWidth/$src_w,$newHeight/$src_h);
$tmp_w = $src_w*$scale;
$tmp_h = $src_h*$scale;
$tmp = imagecreatetruecolor($tmp_w,$tmp_h);
$this->dstImg = imagecreatetruecolor($newWidth,$newHeight);
// resize the image preserving aspect ratio
imagecopyresampled($tmp,$this->srcImg,0,0,0,0,$tmp_w,$tmp_h,$src_w,$src_h);
// crop the resized image to the target dimensions
imagecopyresampled($this->dstImg,$tmp,0,0,intval(($tmp_w-$newWidth)/2),intval(($tmp_h-$newHeight)/2),$newWidth,$newHeight,$newWidth,$newHeight);
}
// will center-crop image to target dimensions
public function crop($newWidth,$newHeight,$x = 'center',$y = 'center'){
// get sizes of source image
$src_w = imagesx($this->srcImg);
$src_h = imagesy($this->srcImg);
if($x == 'center'){
$x = ($src_w-$newWidth)/2;
}else if(is_numeric($x)){
$x = intval($x);
}else{
$x = 0;
}
if($y == 'center'){
$y = ($src_h-$newHeight)/2;
}else if(is_numeric($y)){
$y = intval($y);
}else{
$y = 0;
}
// see which way to scale
$this->dstImg = imagecreatetruecolor($newWidth,$newHeight);
// crop the image to the target dimensions
imagecopy($this->dstImg,$this->srcImg,0,0,$x,$y,$newWidth,$newHeight);
}
public function loadImage($filename){
// get image properties
$this->srcImgProps = @getimagesize($filename) or die("Failed reading $filename");// or $this->warningImage('creation');
// read in source image
switch($this->srcImgProps[2]){
case 1:
$this->srcImg = @imagecreatefromgif($filename) or $this->warningImage('creation');
break;
case 2:
$this->srcImg = @imagecreatefromjpeg($filename) or $this->warningImage('creation');
break;
case 3:
$this->srcImg = @imagecreatefrompng($filename) or $this->warningImage('creation');
break;
case 6:
case 15:
$this->srcImg = @imagecreatefrombmp($filename) or $this->warningImage('creation');
break;
default:
$this->warningImage('creation');
}
return(true);
}
public function warningImage($warning='?'){
$white = imagecolorallocate($this->dstImg, 255, 255, 255);
$red = imagecolorallocate($this->dstImg, 255,0,0);
imagefilledrectangle($this->dstImg,0,0,$this->width,$this->height,$white);
imagestring($this->dstImg,5,10,10,$warning,$red);
}
public function writeImage($outFile = NULL, $format = 'jpeg', $quality = 75){
$quality = intval(max(0,min(100,$quality)));
if ($format == ImageUtil::JPEG) {
if(!$outFile){
header ("Content-type: image/jpeg");
}
imagejpeg($this->dstImg,$outFile,$quality);
}else if($format == ImageUtil::GIF){
if(!$outFile){
header ("Content-type: image/gif");
}
imagegif($this->dstImg,$outFile);
}else if($format == ImageUtil::PNG){
if(!$outFile){
header ("Content-type: image/png");
}
imagejpeg($this->dstImg,$outFile,$quality);
}
}
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment