Hello :) https://blog.samyapp.com Wed, 20 Apr 2016 09:04:51 +0000 en-US hourly 1 https://wordpress.org/?v=4.8.7 102402223 Redirect requests for missing wordpress uploads to another server using NGINX https://blog.samyapp.com/redirect-requests-for-missing-wordpress-uploads-to-another-server-using-nginx/ https://blog.samyapp.com/redirect-requests-for-missing-wordpress-uploads-to-another-server-using-nginx/#respond Wed, 20 Apr 2016 08:58:48 +0000 https://blog.samyapp.com/?p=453 When working on a copy of a live WordPress website it can be handy not to have to duplicate the uploaded files in wp-content/uploads, whilst still allowing the creation of new uploads during testing and development without affecting the production website. The configuration below can be added inside a server{} block inside an NGINX configuration […]

The post Redirect requests for missing wordpress uploads to another server using NGINX appeared first on Hello :).

]]>
When working on a copy of a live WordPress website it can be handy not to have to duplicate the uploaded files in wp-content/uploads, whilst still allowing the creation of new uploads during testing and development without affecting the production website.

The configuration below can be added inside a server{} block inside an NGINX configuration file to redirect any requests for files in wp-content/uploads that don’t exist back to the live server, www.example.com.

server {

# ... other server configuration... 

    # Match anything in wp-content/uploads and if it doesn't exist, use the rule for @prod_serv
    location ~ "^(.*)/wp-content/uploads/(.*)$" {
        try_files $uri @prod_server;
    }

    # Send a temporary http redirect to the browser, redirecting the request to 
    # For a permanent redirect change the status code below from 302 to 301
    location @prod_serv {
        return 302 $scheme://www.example.com$request_uri;
    }

# ... rest of the server config below ...
}

This solution was based on the information at http://wordpress.stackexchange.com/a/215189 and https://www.nginx.com/blog/creating-nginx-rewrite-rules/ .

The post Redirect requests for missing wordpress uploads to another server using NGINX appeared first on Hello :).

]]>
https://blog.samyapp.com/redirect-requests-for-missing-wordpress-uploads-to-another-server-using-nginx/feed/ 0 453
Remove all rounded corners from Bootstrap 3 using Less https://blog.samyapp.com/remove-rounded-corners-from-bootstrap/ https://blog.samyapp.com/remove-rounded-corners-from-bootstrap/#respond Tue, 10 Nov 2015 14:42:33 +0000 https://blog.samyapp.com/?p=444 A Bootstrap 3 design I am working on requires square rather than the default rounded css corners. The quick and easy solution involves overriding the values of only 5 Less variables in my own Less variables file: [crayon-5bf3303c169d5030378902/] There are a lot of other variables in Bootstrap for setting various border radius’, but all of them use one […]

The post Remove all rounded corners from Bootstrap 3 using Less appeared first on Hello :).

]]>
A Bootstrap 3 design I am working on requires square rather than the default rounded css corners. The quick and easy solution involves overriding the values of only 5 Less variables in my own Less variables file:

@border-radius-base:    0;
@border-radius-large:   0;
@border-radius-small:   0;
@pager-border-radius:   0;
@badge-border-radius:   0;

There are a lot of other variables in Bootstrap for setting various border radius’, but all of them use one of the above values by default, with the exception of .img-circle – although .img-circle without rounded corners seems an odd idea.

// Perfect circle
.img-circle {
  border-radius: 50%; // set radius in percents
}

For quick reference, here are the other Bootstrap 3 variables (copied straight from Bootstrap’s variables.less) that can be used to customise border-radius in your Less-based web designs together with their default values:

@border-radius-base:        4px;
@border-radius-large:       6px;
@border-radius-small:       3px;

// Allows for customizing button radius independently from global border radius
@btn-border-radius-base:         @border-radius-base;
@btn-border-radius-large:        @border-radius-large;
@btn-border-radius-small:        @border-radius-small;

//** Default `.form-control` border radius
// This has no effect on `<select>`s in some browsers, due to the limited stylability of `<select>`s in CSS.
@input-border-radius:            @border-radius-base;
//** Large `.form-control` border radius
@input-border-radius-large:      @border-radius-large;
//** Small `.form-control` border radius
@input-border-radius-small:      @border-radius-small;

@navbar-border-radius:             @border-radius-base;

@nav-pills-border-radius:                   @border-radius-base;

@pager-border-radius:                  15px;

@alert-border-radius:         @border-radius-base;

//** Variable for setting rounded corners on progress bar.
@progress-border-radius:      @border-radius-base;

//** List group border radius
@list-group-border-radius:      @border-radius-base;

@panel-border-radius:         @border-radius-base;

//** Thumbnail border radius
@thumbnail-border-radius:     @border-radius-base;

@badge-border-radius:         10px;

 

The post Remove all rounded corners from Bootstrap 3 using Less appeared first on Hello :).

]]>
https://blog.samyapp.com/remove-rounded-corners-from-bootstrap/feed/ 0 444
Ripping high quality mp3s from audio cds on Ubuntu https://blog.samyapp.com/ripping-high-quality-mp3s-from-audio-cds-on-ubuntu/ https://blog.samyapp.com/ripping-high-quality-mp3s-from-audio-cds-on-ubuntu/#respond Wed, 09 Jul 2014 13:34:23 +0000 https://blog.samyapp.com/?p=4 I’m using abcde with the ~/.abcde.conf file below. I think the only change I made to the configuration file was the LAMEOPTS for 320kbs bitrate and the outputtype to mp3: [crayon-5bf3303c1708c817935986/] Usage: cd into the folder to store the mp3s, and type abcde. Answer the questions it asks and if necessary fill in any missing […]

The post Ripping high quality mp3s from audio cds on Ubuntu appeared first on Hello :).

]]>
I’m using abcde with the ~/.abcde.conf file below. I think the only change I made to the configuration file was the LAMEOPTS for 320kbs bitrate and the outputtype to mp3:

# MP3:
LAMEOPTS="-k -h -ms -b320"

OUTPUTTYPE=mp3

Usage: cd into the folder to store the mp3s, and type abcde. Answer the questions it asks and if necessary fill in any missing album / artist / track info, then wait. It will create a folder named after the artist and album in the current directory, and save each ripped mp3 in the format mp3.

# System defaults for abcde version 2.2.x
# Nothing in this file is uncommented by default.
# 
# If you wish to override these system-wide settings, create your own
# .abcde.conf file in your home directory.

# CDDB options

# If you wish to use a different CDDB server, edit this line.
# If you just wanted to use a proxy server, just set your http_proxy
# environment variable - wget will use it correctly.
#CDDBURL="http://freedb.freedb.org/~cddb/cddb.cgi"

# The CDDB protocol level.
# Right now 5 is latin1 output and 6 is UTF8 encoding.
#CDDBPROTO=6

# The CDDB protocol requires hello information, including a valid username
# and hostname. If you feel paranoid about giving away such info, edit this
# line - the format is username@hostname.
#HELLOINFO="`whoami`@`hostname`"

# This controls the email address CDDB changes are submitted to.
#CDDBSUBMIT=freedb-submit@freedb.org

# The following options control whether or not fetched CDDB entries
# are cached locally in $CDDBLOCALDIR
#CDDBCOPYLOCAL="n"
#CDDBLOCALDIR="$HOME/.cddb"
#CDDBLOCALRECURSIVE="n"

# If NOSUBMIT is set to y, then abcde will never prompt asking if you
# wish to submit your edited cddb file.
#NOSUBMIT=n

# If NOCDDBQUERY is set to y, then abcde will never even try to access
# the CDDB server; running abcde will automatically drop you into a
# blank cddb file to edit at your leisure.  This is the same as the
# -n option.  NOCDDBQUERY=y implies NOSUBMIT=y.
#NOCDDBQUERY=n

# Select here if you want to use the locally stored CDDB entries.
# This is useful if you do a lot of editing to those CDDB entries. 
# Also, other tools like Grip store CDDB entries under $HOME/.cddb,
# so they can be reused when ripping CDs.
#CDDBUSELOCAL="n"

# List, separated with a comma, the fields we want the parsing function to
# output. Defaults to YEAR and GENRE, for a complete list of fields provided by
# CDDB.
# The fields are not case sensitive. Actually, "y,g" will work as fine as "Y,G"
# or "YEAR, GENRE"
#SHOWCDDBFIELDS=year,genre

# Specify the style of encoder to use here - 
# oggenc, vorbize - for OGGENCODERSYNTAX
# lame, gogo, bladeenc, l3enc, xingmp3enc, mp3enc - for MP3ENCODERSYNTAX
# flac - the only supported for FLACENCODERSYNTAX at the moment
# speexenc - the only encoder for SPEEXENCODERSYNTAX
# mppenc - encoder for MPPENCODERSYNTAX
# default is a valid option for oggenc, lame, flac, speexenc and mppenc.
# Currently this affects the default location of the binary, the variable
# to pick encoder command-line options from, and where the options are
# given.
#MP3ENCODERSYNTAX=default
#OGGENCODERSYNTAX=default
#FLACENCODERSYNTAX=default
#SPEEXENCODERSYNTAX=default
#MPPENCODERSYNTAX=default
#AACENCODERSYNTAX=default

# Specify the syntax of the normalize binary here - so far only 'normalize'
# is supported.
#NORMALIZERSYNTAX=default

# CD reader program to use - currently recognized options are 'cdparanoia',
# 'icedax', 'cdda2wav', 'dagrab', 'cddafs' (Mac OS X only) and 'flac'.
#CDROMREADERSYNTAX=cdparanoia

# CUE reader syntax for the CUE reader program to use.
# abcde supports 2 CUE modes: 'mkcue' and 'abcde.mkcue' so you can set the
# MKCUE variable accordingly. The 'abcde.mkcue' uses an internal
# implementation, without the need of an external program.
#CUEREADERSYNTAX=default

# Specify the program to convert a CUE sheet back to a CD disc ID for CDDB queries.
# Select between '/path/to/cue2discid' (provided as an example) or
# 'abcde.cue2discid', implemented internaly.
#CUE2DISCID=abcde.cue2discid

# Keep the wav files after encoding. Set it to "y" and remove "clean" from
# the list of default actions, since we purge the temp directory as default.
#KEEPWAVS=n

# Track padding: force abcde to pad tracks using 0, so every song uses a two
# digit entry. If set to "y", even a single song encoding outputs a file like
# 01.my_song.ext
#PADTRACKS=n

# Define if you want abcde to be non-interactive.
# Keep in mind that there is no way to deactivate it right now in the command
# line, so setting this option makes abcde to be always non-interactive.
#INTERACTIVE=n

# Specify 'nice'ness of the encoder, the CD reader and the distmp3 proc.
# This is a relative 'nice'ness (that is, if the parent process is at a
# nice level of 12, and the ENCNICE is set to 3, then the encoder will
# run with an absolute nice value of 15. Note also, that setting these
# to be empty will result in some default niceness increase (4 in tcsh
# and 10 using the bsdutils' nice).
#ENCNICE=10
#READNICE=10
#DISTMP3NICE=10

# Paths of programs to use
#LAME=lame
#TOOLAME=toolame
#GOGO=gogo
#BLADEENC=bladeenc
#L3ENC=l3enc
#XINGMP3ENC=xingmp3enc
#MP3ENC=mp3enc
#VORBIZE=vorbize
#OGGENC=oggenc
#FLAC=flac
#SPEEXENC=speexenc
#MPPENC=mppenc
#AACENC=faac

#ID3=id3
#ID3V2=id3v2
#CDPARANOIA=cdparanoia
#CDDA2WAV=icedax
#CDDAFS=cp
#CDDISCID=cd-discid
#CDDBTOOL=cddb-tool
#EJECT=eject
#MD5SUM=md5sum
#DISTMP3=distmp3
#VORBISCOMMENT=vorbiscomment
#METAFLAC=metaflac
#NORMALIZE=normalize-audio
#CDSPEED=eject
#VORBISGAIN=vorbisgain
#MKCUE=mkcue
#MKTOC=cdrdao
#DIFF=diff

# Options to call programs with:

# If HTTPGET is modified, the HTTPGETOPTS options should also be defined 
# accordingly. If HTTPGET is changed, the default options will be set,
# if HTTPGETOPTS is empty or not defined.
#HTTPGET=wget
# for fetch (FreeBSD): HTTPGETOPTS="-q -o -"
# for wget: HTTPGETOPTS="-q -nv -O -"
# for curl (MacOSX): HTTPGETOPTS="-f -s"
#HTTPGETOPTS="-q -O -"

# MP3:
LAMEOPTS="-k -h -ms -b320"
#TOOLAMEOPTS=
#GOGOOPTS=
#BLADEENCOPTS=
#L3ENCOPTS=
#XINGMP3ENCOPTS=
#MP3ENCOPTS=

# Ogg:
#VORBIZEOPTS=
#OGGENCOPTS=

# FLAC:
#FLACOPTS="-f"

# Speex:
#SPEEXENCOPTS=

# MPP/MP+ (Musepack):
# For the encoder options take a look at the manpage. Set them like this:
# MPPENCOPTS='--xtreme' if you wish to set more options then:
# MPPENCOPTS='--xtreme --skip 20 --fade 10'
#MPPENCOPTS=

# M4A/AAC
#AACENCOPTS=

#ID3OPTS=
#ID3V2OPTS=
#CDPARANOIAOPTS=
#CDDA2WAVOPTS=
#CDDAFSOPTS="-f"
#CDDBTOOLOPTS=
#EJECTOPTS=
#DISTMP3OPTS=
#NORMALIZEOPTS=
#CDSPEEDOPTS="-x"
#CDSPEEDVALUE=""
#MKCUEOPTS=""
#MKTOCOPTS=""
#DIFFOPTS=""
#VORBISCOMMENTOPTS="-R"
#METAFLACOPTS="--no-utf8-convert"
#DIFFOPTS=""

# Actions to take
# Comma-separated list of one or more of the following:
#  cddb,cue,read,normalize,encode,tag,move,playlist,clean,default
#   encode implies read
#   normalize implies read
#   tag implies cddb,read,encode
#   move implies cddb,read,encode,tag
#   playlist implies cddb
# An action can be added to the "default" action by specifying it along with
# "default", without having to repeat the default ones:
#  ACTIONS=default,playlist
# The default action list (referenced as "default") is defined in the following
# comment:
#ACTIONS=cddb,read,encode,tag,move,clean

# CD device you want to read from
# It can be defined as a singletrack flac file, but since it might change from
# file to file it makes little sense to define it here.
#CDROM=/dev/cdrom
# If we are using the IDE bus, we need CDPARANOIACDROMBUS defined as "d"
# If we are using the ide-scsi emulation layer, we need to define a "g"
#CDPARANOIACDROMBUS="d"

# If you'd like to make a default location that overrides the current
# directory for putting mp3's, uncomment this.
#OUTPUTDIR=`pwd`

# Or if you'd just like to put the temporary .wav files somewhere else
# you can specify that here
#WAVOUTPUTDIR=`pwd`

# OUTPUTTYPE can be either "ogg", "mp3", "flac" or "spx", or a combination
# of them separated with ",": "ogg,mp3".
OUTPUTTYPE=mp3

# Output filename format - change this to reflect your inner desire to
# organize things differently than everyone else :)
# You have the following variables at your disposal:
# OUTPUT, GENRE, ALBUMFILE, ARTISTFILE, TRACKFILE, and TRACKNUM.
# Make sure to single-quote this variable. abcde will automatically create
# the directory portion of this filename.
# NOTICE: OUTPUTTYPE has been deprecated in the OUTPUTFORMAT string.
# Since multiple-output was integrated we always append the file type
# to the files. Remove it from your user defined string if you are getting
# files like ".ogg.ogg".
#OUTPUTFORMAT='${ARTISTFILE}-${ALBUMFILE}/${TRACKNUM}.${TRACKFILE}'

# Like OUTPUTFORMAT but for Various Artists discs.
#VAOUTPUTFORMAT='Various-${ALBUMFILE}/${TRACKNUM}.${ARTISTFILE}-${TRACKFILE}'

# Like OUTPUTFORMAT and VAOUTPUTFORMAT but for the ONEFILE rips.
#ONETRACKOUTPUTFORMAT=$OUTPUTFORMAT
#VAONETRACKOUTPUTFORMAT=$VAOUTPUTFORMAT

# Define how many encoders to run at once. This makes for huge speedups
# on SMP systems. Defaults to 1. Equivalent to -j.
#MAXPROCS=2

# Support for systems with low disk space:
# n:    Default parallelization (read entire CD in while encoding)
# y:    No parallelization (rip, encode, rip, encode...)
#LOWDISK=n

# If set to y, enables batch mode normalization, which preserves relative
# volume differences between tracks of an album. 
#BATCHNORM=n

# Enables nogap encoding when using the 'lame' encoder.
#NOGAP=y

# Set the playlist file location format. Uses the same variables and format
# as OUTPUTFORMAT. If the playlist is specified to be in a subdirectory, it
# will be created for you and the playlist will reference files from that
# subdirectory.
#PLAYLISTFORMAT='${ARTISTFILE}-${ALBUMFILE}.${OUTPUT}.m3u'
# If you want to prefix every filename in a playlist with an arbitrary
# string (such as 'http://you/yourstuff/'), use this option
#PLAYLISTDATAPREFIX=''

#Like PLAYLIST{FORMAT,DATAPREFIX} but for Various Artists discs:
#VAPLAYLISTFORMAT='${ARTISTFILE}-${ALBUMFILE}.${OUTPUT}.m3u'
#VAPLAYLISTDATAPREFIX=''

#This will give the playlist CR-LF line-endings, if set to "y".
#(some hardware players insist on CR-LF line-endings)
#DOSPLAYLIST=n

# Custom filename munging:
# By default, abcde will do the following to CDDB data to get a useful
# filename:
# * Translate colons to a space and a dash for Windows compatibility
# * Eat control characters, single quotes, and question marks
# * Translate spaces and forward slashes to underscores
# To change that, redefine the mungefilename function.
# mungefilename receives the CDDB data (artist, track, title, whatever)
# as $1 and outputs it on stdout.
#mungefilename ()
#{
#  echo "$@" | sed s,:, -,g | tr  / __ | tr -d '"?[:cntrl:]
#}

# Custom genre munging:
# By default we just transform uppercase to lowercase. Not much of a fancy
# function, with not much use, but one can disable it or just turn the first
# Uppercase.
#mungegenre ()
#{
#  echo $CDGENRE | tr "[:upper:]" "[:lower:]"
#}


# Custom pre-read function
# By default it does nothing.
# You can set some things to get abcde function in better ways:
# * Close the CD tray using eject -t (if available in eject and supported by 
#   your CD device.
# * Set the CD speed. You can also use the built-in options, but you can also 
#   set it here. In Debian, eject -x and cdset -x do the job.
# KEEP IN MIND that executables included in pre_read must be in your $PATH or
# you have to define them with full /path/to/binary
# Uncomment and substitute the ":" with your commands.
#pre_read ()
#{
#:
#}

# Custom post-read function
# By default it does nothing.
# You can set some things to get abcde function in better ways:
# * Store a copy of the CD TOC.
# KEEP IN MIND that executables included in post_read must be in your $PATH or
# you have to define them with full /path/to/binary
# Uncomment and substitute the ":" with your commands.
#post_read ()
#{
#:
#}

# post_encode
# By default it does nothing.
# You can set some things to get abcde function in better ways:
# * Move the resulting directory over the network
# * Compare results with a previously made run, for tests
# KEEP IN MIND that executables included in post_encode must be in your $PATH or
# you have to define them with full /path/to/binary
# Uncomment and substitute the ":" with your commands.
#post_encode ()
#{
#:
#}

# If you'd like to have abcde eject the cdrom after all the tracks have been
# read, uncomment the following line.
#EJECTCD=y

# To encode on the remote machines foo, bar, baz, quux, and qiix, as well as
# on the local machine (requires distmp3 to be installed on local machine and
# distmp3host to be installed and running on all remote machines - see README)
#REMOTEHOSTS=foo,bar,baz,quux,qiix

# Set to obtain some information about actions happening in the background
# Useful if you have a slow network or CDDB servers seem unresponsive.
#EXTRAVERBOSE=n

The post Ripping high quality mp3s from audio cds on Ubuntu appeared first on Hello :).

]]>
https://blog.samyapp.com/ripping-high-quality-mp3s-from-audio-cds-on-ubuntu/feed/ 0 4
Extract images from a zip archive https://blog.samyapp.com/extract-images-from-a-zip-archive/ https://blog.samyapp.com/extract-images-from-a-zip-archive/#respond Wed, 17 Sep 2008 16:26:25 +0000 https://blog.samyapp.com/?p=137 For my second example of using my image thumbnailer I’ve thrown together a little script which accepts a zip archive upload containing images and generates and returns to the browser a new zip archive containing a thumbnail for each image in the original. Source code download at the end of this page. zip2thumb.php [crayon-5bf3303c172c0803135123/] Download […]

The post Extract images from a zip archive appeared first on Hello :).

]]>
For my second example of using my image thumbnailer I’ve thrown together a little script which accepts a zip archive upload containing images and generates and returns to the browser a new zip archive containing a thumbnail for each image in the original.

Form to upload a zip file containing images

Form to upload a zip file containing images

After processing a new zip is sent to the browser containing thumbnails

After processing a new zip is sent to the browser containing thumbnails


Source code download at the end of this page.

zip2thumb.php

<?php
require_once dirname(__FILE__) . '/paGdThumbnail.php';

$thumb_width = 150;
$thumb_height = 150;
$thumb_quality = 75;
$thumb_method = 'crop';
$thumb_bgColour = array(0,0,0);

// give us lots of time
set_time_limit(0);

// use to store error messages in.
$error = '';

$errors = array(
	UPLOAD_ERR_INI_SIZE => 'The uploaded file exceeds the upload_max_filesize directive in php.ini.',
	UPLOAD_ERR_FORM_SIZE => 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.',
	UPLOAD_ERR_PARTIAL => 'The uploaded file was only partially uploaded.',
	UPLOAD_ERR_NO_FILE => 'No file was uploaded.',
	UPLOAD_ERR_NO_TMP_DIR => 'Missing a temporary folder.',
	UPLOAD_ERR_CANT_WRITE => 'Failed to write file to disk.',
	UPLOAD_ERR_EXTENSION => 'File upload stopped by extension.'
);

// get url to link to thumbs
$pathinfo = pathinfo($_SERVER['SCRIPT_NAME']);
$download_url = 'http://'.$_SERVER['HTTP_HOST'] . '/' . $pathinfo['dirname'] . '/thumbs.zip';

// has the form been submitted?
if( isset($_POST['submit']) ){

	// was a file submitted?
	if( isset($_FILES['zip']) ){
		// any errors?
		if( !$_FILES['zip']['error'] ){
			// security check
			if( is_uploaded_file($_FILES['zip']['tmp_name']) ){
				// is it a zip file?
				if( preg_match('#.zip$#i', $_FILES['zip']['name']) ){

					// get the thumbnail options from the form
					$thumb_width = (int)$_POST['thumb_width'];
					$thumb_height = (int)$_POST['thumb_height'];
					$thumb_method = $_POST['thumb_method'];

					// create a zip archive object
					$zip = new ZipArchive();
					if( $zip->open($_FILES['zip']['tmp_name']) ){
						$output_name = 'thumbs.zip';
						// create output archive
						$output = new ZipArchive();
						if( $output->open($output_name, ZipArchive::OVERWRITE ) ){

							// loop through all the files in the archive
							for( $i = 0; $i < $zip->numFiles; $i++){
								$entry = $zip->statIndex($i);
								// is it an image?	
								if( $entry['size'] > 0 && preg_match('#.(jpg|gif|png)$#i', $entry['name'] ) ){
									$file = $zip->getFromIndex($i);
									if( $file ){
										$image = imagecreatefromstring($file);
										if( $image ){
											$thumb = paGdThumbnail($image, $thumb_width, $thumb_height, $thumb_method, $thumb_bgColour);
											imagedestroy($image);
											if( $thumb ){
												ob_start();
												imagejpeg($thumb,null,$thumb_quality);
												imagedestroy($thumb);
												$thumb_data = ob_get_clean();
												$output->addFromString(preg_replace('#.(jpg|gif|png)$#i', '_t.jpg', $entry['name']), $thumb_data);
											}
										}
									}
								}
							}
							$output->close();
						}
						$zip->close();
						header("Location: $download_url");
						exit();
					}
				}
				else{

				}
			}
		}
		// display an error message
		else{
			$error = $errors[$_FILES['zip']['error']];
		}

	}

}

?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Zip to Thumbnails :p</title>
</head>
<body>
	<h2>Upload a zip archive containing images in jpeg, png or gif format.</h2>
	<p>You will receive a zip archive containing a thumbnail for each image in the original archive.</p>
	<p>Select the thumbnail width, height and method using the form below.</p>
<?php if( $error ){ ?>
	<h3 style="color: red;"><?php echo $error?></h3>
<?php } ?>
	<form action="<?php echo $_SERVER['SCRIPT_NAME']?>" method="post" enctype="multipart/form-data">
		<input type="file" name="zip" />
		Width: <input type="text" name="thumb_width" value="<?php echo $thumb_width?>" size="4" />
		Height: <input type="text" name="thumb_width" value="<?php echo $thumb_width?>" size="4" />
		<select name="thumb_method">
			<option value="crop">Crop</option>
			<option value="scale"<?php if( $thumb_method == 'scale' ) echo ' selected="selected" '?>>Scale</option>
		</select>
		<input type="submit" name="submit" value="Create Thumbnails" />
	</form>
</body>
</html>

Download from GitHub.

The post Extract images from a zip archive appeared first on Hello :).

]]>
https://blog.samyapp.com/extract-images-from-a-zip-archive/feed/ 0 137
Create thumbnails for all images in a directory https://blog.samyapp.com/create-thumbnails-for-all-images-in-a-directory/ https://blog.samyapp.com/create-thumbnails-for-all-images-in-a-directory/#comments Wed, 17 Sep 2008 16:24:53 +0000 https://blog.samyapp.com/?p=134 This is a simple script to demonstrate using my image resizing function . It scans the directory you place it in for any images, generates a thumbnail for each image, then outputs html to display the thumbnails as links to each image. It requires php 5.1+ as it uses the Directory Iterator to get the […]

The post Create thumbnails for all images in a directory appeared first on Hello :).

]]>
This is a simple script to demonstrate using my image resizing function
. It scans the directory you place it in for any images, generates a thumbnail for each image, then outputs html to display the thumbnails as links to each image.

It requires php 5.1+ as it uses the Directory Iterator to get the files in the directory. If you’d like to see a version compatible with earlier versions of php leave a comment below.

For each file it checks that:

  1. It is a jpeg, png or gif image (or at least has that file extension)
  2. The filename doesn’t end in "_t.jpg" (as this is what is uses for naming the thumbnails)


Download from GitHub.
It then checks if a thumbnail exists with the same name and if one doesn’t (or the image file has been modified more recently) it attempts to create a thumbnail and save it in the current directory with the same name as the image, but with "_t.jpg" at the end of the name.

It pretty simple and meant more as an example for the resizing function, but would be quite easy to extend to show the image in the page with links to the previous and next image for example.

The code below needs the image resizing function to work which needs to be in the same directory. You can copy and paste or download both in a zip.

index.php

<?php

// thumbnail configuration
$thumb_width = 75;
$thumb_height = 75;
$thumb_method = 'crop';
$thumb_bgColour = null;//array(255,255,240);
$thumb_quality = 60;

// Let script run for as long as it needs to when creating thumbnails.
// Some web hosts won't let you use this function. In that case you'll need
// to comment it out and just refresh the script until it has thumbnailed all the images.
set_time_limit(0);

// include the thumbnail function
require_once dirname(__FILE__) . '/paGdThumbnail.php';

// get the path to the current directory
$path = dirname(__FILE__);

// get the url for the images
$path_info = pathinfo($_SERVER['SCRIPT_NAME']);
$url = $path_info['dirname'];

// create an array to store image names in.
$images = array();

$dir = new DirectoryIterator($path);

/*
 Loop through the directory, finding all images that aren't thumbnails.
 For each image:
	- if it doesn't already have a thumbnail, or the thumbnail is older than the image,
		create a thumbnail.
	- get info about the image
	- add the image to our images array
*/
foreach( $dir as $entry ){
	if( $entry->isFile() ){
		if( preg_match('#^(.+?)(_t)?.(jpg|gif|png)#i', $entry->getFilename(), $matches) ){

			list( ,$name, $is_a_thumb, $extension) = $matches;

			// if its not a thumbnail
			if( !$is_a_thumb ){
				// does a valid thumbnail exist?
				$has_thumb = false;
				$thumb_file = $path . '/' . $matches[1] . '_t.jpg';
				if( file_exists($thumb_file) && filemtime($thumb_file) > filemtime($entry->getPathname()) ){
					$has_thumb = true;
				}
				else{
					// no thumbnail, so we shall create one!

					// create a gd image. reading the contents of the image file into a string, then
					// using imagecreatefromstring saves having to check the filetype and which 
					// imagecreatefrom(jpeg/gif/png) function to use
					$image = imagecreatefromstring(file_get_contents($entry->getPathname()));

					if( $image ){
						// create the thumbnail
						$thumb = paGdThumbnail($image, $thumb_width, $thumb_height, $thumb_method, $thumb_bgColour);
						// free the image resource
						imagedestroy($image);
						if( $thumb ){
							// save the thumbnail
							if( imagejpeg($thumb, $thumb_file, $thumb_quality) ){
								$has_thumb = true;
							}
							// free the memory used by the thumbnail image
							imagedestroy($thumb);
						}
					}
				}
				if( $has_thumb ){
					$images[$entry->getFilename()] = $name;
				}
			}
		}
	}
}

// sort the images array so always in the same order
ksort($images);

// end or processing, now display the gallery
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Thumbnails :p</title>
<style type="text/css">
<!--
#thumbs{
	position: relative;
}

#thumbs div{
	float: left;
	width: <?php echo $thumb_width + 30?>px;
	height: <?php echo $thumb_height + 30?>px;
	text-align: center;
}

#thumbs a:link img, #thumbs a:visited img{
	border: 1px solid #acacac;
	padding: 5px;
}

#thumbs a:hover img{
	border: 1px solid black;
}

-->
</style>
</head>
<body>
<div id="thumbs">
<?php foreach( $images as $imagename => $name ){ ?>

	<div>
		<a href="<?php echo $url . '/' . $imagename?>" title="Full Size"><img src="<?php echo $url . '/' . $name . '_t.jpg'?>"  /></a>
	</div>

<?php }?>
</div>
<div id="pb">
	powered by <a href="https://blog.samyapp.com/">a simple php image thumbnail script</a>
</div>
</body>
</html>

The post Create thumbnails for all images in a directory appeared first on Hello :).

]]>
https://blog.samyapp.com/create-thumbnails-for-all-images-in-a-directory/feed/ 2 134
Image Resizing with php https://blog.samyapp.com/image-resizing-with-php/ https://blog.samyapp.com/image-resizing-with-php/#respond Wed, 17 Sep 2008 16:23:58 +0000 https://blog.samyapp.com/?p=131 One of the great things about php is its built in support for the gd image library which makes creating thumbnails from images quite trivial, although you still need to calculate the correct dimensions if you want your thumbs to be resized proportionally. Here’s a function that takes a gd image, a maximum width and […]

The post Image Resizing with php appeared first on Hello :).

]]>
One of the great things about php is its built in support for the gd image library which makes creating thumbnails from images quite trivial, although you still need to calculate the correct dimensions if you want your thumbs to be resized proportionally.

Here’s a function that takes a gd image, a maximum width and / or maximum height and returns a new thumbnail image that fits into these sizes. The function can either scale the image proportionally so the whole image fits completely into the new size, or scale and crop the original so that the thumbnail is exactly the maximum width and height.


Download from GitHub.

If either the maximum width or maximum height is 0 or null then the function calculates these proportionally which is useful if you want all thumbnails a certain width and height and don’t care about the other dimension.

You can also specify an rgb background colour which will force the thumbnail to be exactly $max_width x $max_height with any space at the left and right (or top and bottom depending on whether the source image is portrait or landscape) filled in with the background colour.

I’ve written a couple of scripts to show usage of this function below – one creates thumbnails for every image in the same directory as the script, then generates html to show these. The other extracts images from a zip archive through a standard form upload and creates and returns a zip archive containing generated thumbnails.

You can copy and paste the code, or download the zip file containing all three scripts.

paGdThumbnail.php

<?php

function paGdThumbnail($image, $max_width, $max_height, $method = 'scale', $bgColour = null)
{
	// get the current dimensions of the image
	$src_width = imagesx($image);
	$src_height = imagesy($image);

	// if either max_width or max_height are 0 or null then calculate it proportionally
	if( !$max_width ){
		$max_width = $src_width / ($src_height / $max_height);
	}
	elseif( !$max_height ){
		$max_height = $src_height / ($src_width / $max_width);
	}

	// initialize some variables
	$thumb_x = $thumb_y = 0;	// offset into thumbination image

	// if scaling the image calculate the dest width and height
	$dx = $src_width / $max_width;
	$dy = $src_height / $max_height;
	if( $method == 'scale' ){
		$d = max($dx,$dy);
	}
	// otherwise assume cropping image
	else{
		$d = min($dx, $dy);
	}
	$new_width = $src_width / $d;
	$new_height = $src_height / $d;
	// sanity check to make sure neither is zero
	$new_width = max(1,$new_width);
	$new_height = max(1,$new_height);

	$thumb_width = min($max_width, $new_width);
	$thumb_height = min($max_height, $new_height);

	// if bgColour is an array of rgb values, then we will always create a thumbnail image of exactly
	// max_width x max_height
	if( is_array($bgColour) ){
		$thumb_width = $max_width;
		$thumb_height = $max_height;
		$thumb_x = ($thumb_width - $new_width) / 2;
		$thumb_y = ($thumb_height - $new_height) / 2;
	}
	else{
		$thumb_x = ($thumb_width - $new_width) / 2;
		$thumb_y = ($thumb_height - $new_height) / 2;
	}

	// create a new image to hold the thumbnail
	$thumb = imagecreatetruecolor($thumb_width, $thumb_height);
	if( is_array($bgColour) ){
		$bg = imagecolorallocate($thumb, $bgColour[0], $bgColour[1], $bgColour[2]);
		imagefill($thumb,0,0,$bg);
	}

	// copy from the source to the thumbnail
	imagecopyresampled($thumb, $image, $thumb_x, $thumb_y, 0, 0, $new_width, $new_height, $src_width, $src_height);
	return $thumb;
}

The post Image Resizing with php appeared first on Hello :).

]]>
https://blog.samyapp.com/image-resizing-with-php/feed/ 0 131
A Simple PHP Contact Form https://blog.samyapp.com/a-simple-php-contact-form/ https://blog.samyapp.com/a-simple-php-contact-form/#comments Tue, 16 Sep 2008 17:47:20 +0000 https://blog.samyapp.com/?p=122 This is a simple php contact form / feedback form script I through together as an introduction to php for a friend. Rather than write a tutorial I’ve heavily commented the code. Hope its useful to somebody. WARNING – This was written a long time ago, and does not reflect current PHP best practice! [crayon-5bf3303c18c81668808950/] […]

The post A Simple PHP Contact Form appeared first on Hello :).

]]>
This is a simple php contact form / feedback form script I through together as an introduction to php for a friend.

Rather than write a tutorial I’ve heavily commented the code. Hope its useful to somebody.

WARNING – This was written a long time ago, and does not reflect current PHP best practice!

<?php

/*
    Turn on php's error / warning reporting system to show EVERY error message, 
    notice and warning. This is helpful for debugging scripts. see www.php.net/error_reporting

    On an active website you might turn this down or off so that if an error occurs
    you don't give the visitor any information about how your site works that might
    be of use to an attacker.
*/
    
error_reporting( E_ALL);

/*

 A simple php contact form

 This script displays an html page containing a form and when that form is submitted
 the script processes the submitted values and sends them as an email.

 It's a pretty simple script, but introduces a lot of the commonly used topics in php.

 I'd recommend skimming over the w3schools tutorials on php before trying to understand this,
 or flipping between this and them. http://w3schools.com/php/default.asp

 ps, this stuff in between the slash-asterisk....asterisk-slash is a comment

 You can also have single line comments that begin with // 

 So its basically the same as java for comments

 Also it makes it easier to edit / view php code if the text editor you use has syntax highlighting 
 (using different colours for variable names, comments, etc.)

 I use htmlkit (the free version 292) http://www.chami.com/html-kit/download/ 
 but have heard good things about notepad++ http://notepad-plus.sourceforge.net/uk/site.htm

 If you want an easy to setup php / apache / mysql package try http://www.en.wampserver.com/
*/

// first initialize some variables that will be used to hold the values in
// the contact form. Doing this enables us to redisplay the values the user
// enters in case they leave some fields blank and we ask them to complete
// everything...
// Note that all variable names in php begin with the dollar sign $
// see http://uk2.php.net/language.variables for more info about variables in php

// the email address the submission will be sent to
// put your own address here
// the example.com domain name is reserved specifically for use in tutorials and examples
// like this one.
$my_email = 'youremailhere@example.com';

$name = '';    // will just hold the person's name
$subject = 'Hello';    // will hold the subject of their email. We give a default value of "Hello"
$email = "";    // the email address
$message = "";    // their message
// note above that php can either use two double quotes or two single quotes to enclose a string
// the difference is that strings using double quotes can contain other variables
// eg. if we had $somestring = "$subject World"; (using the $subject variable above, then
// $somestring would contain 'Hello World'. 

$submitted = false;    // we will set this to "true" if the user successfully submits the form

$errors = array();    // create an empty array to hold any error messages we may want

/*
 Here we check if the user has submitted the form.
 http://www.w3schools.com/php/php_post.asp and http://www.w3schools.com/php/php_get.asp 
 provide a bit of info on what the GET and POST methods are used for.

 These are a simple but *extremely* important concept for php programming as they are how scripts 
 get input / data from the user.
*/

// if the user has submitted the form (by pressing the "Send" submit button, then the value
// of this button will be in the $_POST array with the key / name 'send'
//
// php arrays are similar to java hashmaps, but with a much simpler syntax to use them.
// see the php manual http://uk3.php.net/manual/en/language.types.array.php or 
// w3schools http://www.w3schools.com/php/php_arrays.asp
// php array article for why it is written $arrayname['keyname']
if( isset( $_POST['send'] ) ){  // isset is a function that tests if a variable is "set", that is "defined"

    // get the form values for each variable we want
    // the trim() function just removes any extra white space (spaces, tabs, etc) from the variable
    $name = trim( $_POST['name'] );
    $subject = trim( $_POST['subject'] );
    $email = trim( $_POST['email'] );
    $message = trim( $_POST['message'] );

    // check that the user has filled in everything by ensuring they have at least typed *something* in
    // each field. The minimum required length is hard-coded below.

    // check the name is at least 2 characters long.
    // strlen() is a function that checks the length of a string,
    if( strlen($name) < 2 ){
        // name too short, lets inform the user.
        // in php you assign something to the end of an array
        // by using the [] empty square brackets 
        $errors[] = 'You must enter your name';
    }

    // check the length of the subject and message
    if( strlen($subject) < 2 ){
        $errors[] = 'Please enter a subject for your message';
    }
    if( strlen($message) < 5 ){
        $errors[] = "You haven't written a message :(";
    }

    // we should do some better validation of the email address to make sure it is a real
     // one but here i'm just using a simple regular expression to check it looks sorta ok
    // regular expressions are very useful and powerful but take a while to get your head around
    // the pattern below basically matches any string that: see http://uk3.php.net/manual/en/book.pcre.php for info on regular expressions

    // i) begins with one or more of the letters a-z, the numbers 0-9, _ . or -
    // ii) followed by the @ sign
    // iii) followed by one or more letters, numbers _ . or -
    // iv) followed by another ., followed by one or more letters
    // eg. someone   @   example  .com
    //     (i)  (ii)   (iii)    (iv)

    if( !preg_match('/^[a-z0-9_.-]+@[a-z0-9_.-]+.[a-z]+/i', $email) ){
        $errors[] = "How can I reply to you if you don't give me a valid email address?????";
    }

    /* one last but important step is to check the user submitted values aren't a spammer
      trying to hijack our form to send spam emails on their behalf. This isn't something
        I'm going to go into in any detail here, but is important to know about:
     
        for more information see: 
            http://www.thesitewizard.com/php/protect-script-from-email-injection.shtml
            http://www.phpit.net/article/php-security-3-example-exploits/

        We use a simple regular expression to only allow the letters a-z, numbers 0-9 and
        a few bits of punctuation in our email address, name and subject fields.
        Basically we don't let the user submit anything that might be dodgy, although this
        does mean we can't have submissions using characters that aren't in the english language.
        Which might suck a bit.
    */
    $testRegEx = '/^[a-z0-9!"():;@#/\.,<>_ -]*$/i';
    if( !preg_match($testRegEx, $name) || !preg_match($testRegEx, $email) || !preg_match($testRegEx,$subject) ){
        $errors[] = 'Your name, email address or subject contained invalid characters. Please re-enter.';
    }

    // if we have found any errors then we don't want to send the email
    // we can tell if there are any errors by checking the number of entries in
    // our $errors array.
    // In php you check the size / number of items in an array using the count() function
    if( count( $errors ) == 0){

        // no errors, send the email using php's mail($to, $subject, $message, $headers) function
        // first we create two more strings $full_subject and $full_message which
        // will contain slightly modified versions of the original

        // we prepend 'Contact form submission' to the user's subject, so when it shows up in our
        // email client we know it came from our form
        // Notice that php concatenates strings using the period . not a + like in java.
        $full_subject = 'Contact form submission: ' . $subject;

        $full_message = "$name sent the following message at " . date('H:i:s') . ' on ' . date('l jS F Y'). " from ip address {$_SERVER['REMOTE_ADDR']}nn";
        $full_message .=$message;

        // ok should probably explain what the two lines above do :0)
        // "$name sent..." places the contents of the $name variable into the string
        // date('H:i:s') gets the current time in the format 12:01:54 (hours:minutes:seconds)
        // date('l jS F Y') gets the current date in the format "wednesday 16th July 2008"
        // see www.php.net/date for more info (and note that you can access php info quickly at
        // php.net by placing what you are looking for after the domain name, eg. php.net/arrays php.net/strings

        // the {$_SERVER['REMOTE_ADDR']} imbeds the ip address of the current user into the string as well.
        // $_SERVER is an array containing info from the server. array entries can be embedded in strings by
        // surrounding them with curly brackets {...}

        $full_email = "$name <$email>";

        // the $headers parameter to the mail() command adds some important headers to the email, such as from and reply-to addresses.
        $headers = "From: $full_emailrnReply-To: $full_emailrnErrors-To: $my_email";

        // on your home pc, the mail function may not be able to work ok and will output an error.
        if( mail($my_email, $full_subject, $full_message, $headers) ){
            $submitted = true;    // we use this variable later to decide whether to show the form or a thank-you message
        }
        else{    // if mail() failed then we have a server configuration error...
            $errors[] = 'Sorry, due to server issues your message could not be sent. Please try talking to me instead :p';
        }

    }
}

/*
 thats's most of the code, now we come out of php mode and add
 an html page containing a simple form.

 we mix a bit of php with it to check:
 1) has the form been submitted? if so then just display a message, no form
 2) if displaying the form, are there any errors? if so, display them
 3) we output / echo / print any values the user has already submitted for the form
 4) we echo the uri of this script into the form's action="" parameter so that the form
    submits back to this page

 A couple of notes about a couple of functions used below:

 htmlspecialchars() takes a string and returns the same string with any characters that have special meaning in
 html converted to display properly.

 nl2br() Converts any newline characters in the string to html <br /> line break tags (because html just treats newlines as
 spaces.

 echo is a php function that prints the values of its parameters to the screen. You could also use print()

*/
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Contact Us</title>
</head>
<body>
<?php

// if the form has been successfully submitted, just display a message showing what was sent:
if( $submitted ){

?>
    <h1>Thank You!</h1>
    <p>Thank you for contacting us. The following message was sent from <?php echo htmlspecialchars($name)?>, <?php echo htmlspecialchars($email)?>:</p>
    <p>Subject: <?php echo htmlspecialchars($subject)?></p>
    <p>Message: <?php echo nl2br(htmlspecialchars($message))?></p>
<?php

}
else{ // otherwise display the form

?>
    <h1>Contact Us :)</h1>
<?php
    if( count( $errors ) ){
?>
    <div style="font-weight: bold; color: red;">
        <h2>Please correct the following errors and resubmit the form:</h2>
<?php
        foreach( $errors as $error ){
            echo '<p>' . htmlspecialchars($error) . '</p>';
        }
?>
    </div>
<?php

    }    // end of test for error messages

?>
    <form action="<?php echo $_SERVER['SCRIPT_NAME']?>" method="post">
        <br />
        Your Name: <input type="text" name="name" value="<?php echo htmlspecialchars($name)?>" />
        <br />
        Your Email: <input type="text" name="email" value="<?php echo htmlspecialchars($email)?>" />
        <br />
        Subject: <input type="text" name="subject" value="<?php echo htmlspecialchars($subject)?>" />
        <br />
        Message: <textarea name="message" cols="60" rows="20"><?php echo htmlspecialchars($message)?></textarea>
        <br />
        <input type="submit" name="send" value="Send Message" />
    </form>

<?php

}    // end of the if statement that checks if the form has been successfully submitted

?>

</body>
</html>

Feel free to send me some feedback on this if you found it useful :0)

The post A Simple PHP Contact Form appeared first on Hello :).

]]>
https://blog.samyapp.com/a-simple-php-contact-form/feed/ 1 122