Archive for the ‘Programming’ Category

Slimbox2 Lightbox clone with automatic image resizing

Saturday, October 15th, 2011

I recently moved from Lightbox 2 to Slimbox2, whilst it is a little outdated, Slimbox2 offers many advantages;

  • jQuery language – no need for Prototype/Scriptaculous
  • page doesn’t need to be loaded completely before being run
  • has its own API

Unfortunately, it is missing automatic image resizing, which I love.

With the help of Example 9 on Neil’s Slimbox Examples, I have managed to hack together this feature which I am happy about.

Modified Slimbox2 with auto resize JavaScript
Modified Slimbox2 with auto resize CSS

Example in the below Image Map;

Test Images

1024x768 768x1024 800x600 600x800 640x480 480x640 320x240 240x320

Related posts:

  1. Photoshop VBScript to automatically resize images

Online RSVP form and database with PHP, JavaScript and MySQL

Friday, September 30th, 2011

Requirements

Recently, I needed an online RSVP system for a reception I was hosting, all the options out there didn’t meet my requirements;

  • Customisable and able to self-host
  • No need for tracking codes/numbers to be sent with invitation
  • Able to RSVP additional guests
  • Able to modify an existing RSVP

Implementation

As usual, I decided to implement my own online RSVP solution, which has the following functionality;
  • PHP/JavaScript front-end
  • MySQL back-end
  • Sleek CSS (borrowed from WordPress)
  • Client-side checking with JavaScript
  • Server-side checking with PHP
  • Very basic submission viewing in HTML, wasn’t a real requirement as I could browse the database with phpMyAdmin, but it was good to have some visibility without the need of logging in

Installation

  • You will need PHP installed and a MySQL database.
  • Import the following SQL query to create a RSVP table with required fields.
  • Create a folder on your web hosting.
  • Extract the following zip file contents to this newly created folder.
  • Edit rsvp.php and configure your database settings, including database name, user name, password and host.
  • If using the optional email confirmation, configure the email from address and email body contents.
  • On your website, create an iframe to show the RSVP form.
Testing
  • Navigate to rsvp.php and submit a test response.
  • Navigate to res.php and confirm you can see your test response.
  • Alternatively, view the MySQL table directly (with phpMyAdmin)
Downloads

Improvements

Two small things I would have added, known after it’s use;

  • Client-side checking for ‘and’ in the full name field, few guests still tried to add themselves and their partner in that field.
  • Improved response email that would be addressed to all guests not just the first name.

Related posts:

  1. Dynamic Google Maps circle markers/icons with PHP
  2. RSS feed aggregator/combiner in PHP
  3. Dynamic Google Maps markers/icons with PHP

VBA/VB6 functions to return folder or file type and date modified.

Friday, September 2nd, 2011

Here are two quick functions;

The first getType takes in a path of a folder or file and returns the type.

Function getType(ByRef path As String) As String
    On Error Resume Next
    Dim res As Long
    res = GetAttr(path)
    If Err.Number = 0 Then
        If res And vbDirectory Then
            getType = "folder"
        Else
            getType = "file"
        End If
    Else
        getType = "error"
    End If
End Function

The second function getDate takes in a folder or path and returns the date modified. getDate references getType.

Function getDate(ByRef path As String) As Double
    Select Case getType(path)
        Case "file"
            getDate = CreateObject("scripting.filesystemobject").getfile(path).datelastmodified
        Case "folder"
            getDate = CreateObject("scripting.filesystemobject").getfolder(path).datelastmodified
    End Select
End Function

Related posts:

  1. Rigid file manipulation functions for VBA/VBS
  2. VB6/VBA functions to convert binary string to Base64 string
  3. Generic file selection window function in VBA

VB6/VBA functions to convert binary string to Base64 string

Tuesday, August 16th, 2011

Here are some functions to convert a binary string, to a byte array, to a Base64 string and then back to a byte array and binary string. Run tester to see it in action, enjoy.

Private Function encodeBase64(ByRef arrData() As Byte) As String
    Dim objXML As MSXML2.DOMDocument
    Dim objNode As MSXML2.IXMLDOMElement

    Set objXML = New MSXML2.DOMDocument

    Set objNode = objXML.createElement("b64")
    objNode.DataType = "bin.base64"
    objNode.nodeTypedValue = arrData
    encodeBase64 = objNode.Text

    Set objNode = Nothing
    Set objXML = Nothing
End Function

Private Function decodeBase64(ByVal strData As String) As Byte()
    Dim objXML As MSXML2.DOMDocument
    Dim objNode As MSXML2.IXMLDOMElement

    Set objXML = New MSXML2.DOMDocument
    Set objNode = objXML.createElement("b64")
    objNode.DataType = "bin.base64"
    objNode.Text = strData
    decodeBase64 = objNode.nodeTypedValue

    Set objNode = Nothing
    Set objXML = Nothing
End Function

Function bin2Byte(ByVal s As String) As Byte()
    Dim bitsIn As Long
    bitsIn = 8

    Dim i As Long
    'pad with zeros
    If Len(s) Mod bitsIn <> 0 Then
        For i = 1 To bitsIn - Len(s) Mod bitsIn
            s = "0" & s
        Next i
    End If

    i = Len(s)
    Dim bytes() As Byte
    Dim byteCount As Long
    byteCount = -1
    Dim sByte As String
    Do While LenB(s) > 0
        byteCount = byteCount + 1
        ReDim Preserve bytes(byteCount)

        sByte = Mid$(s, Len(s) - bitsIn + 1)
        'sByte = Mid$(s, 1, bitsIn)
        For i = 0 To 7 Step 1
            bytes(byteCount) = bytes(byteCount) + CLng(Mid$(sByte, 8 - i, 1)) * 2 ^ i
        Next i
        s = Mid$(s, 1, Len(s) - bitsIn)
        's = Mid$(s, bitsIn + 1)
    Loop
    bin2Byte = bytes
End Function

Function byte2Bin(ByRef bytes() As Byte) As String
    Dim i As Long, j As Long
    Dim bin As String
    For i = 0 To UBound(bytes)
        bin = Space$(8)

        For j = 0 To 7
            If bytes(i) And 2 ^ j Then
                Mid(bin, 8 - j, 1) = "1"
            Else
                'Mid(bin, 8 - j, 1) = "0"
            End If
        Next j

        byte2Bin = bin & byte2Bin
    Next i
    byte2Bin = LTrim$(byte2Bin)
    byte2Bin = Replace(byte2Bin, " ", "0", 1, -1, vbBinaryCompare)
End Function

Sub tester()
    'note we can't add any 0 padding to the test binary string
    Dim bin As String
    bin = "111101000001100010101"
    Dim binOut As String
    binOut = byte2Bin(decodeBase64(encodeBase64(bin2Byte(bin))))

    MsgBox binOut = bin
End Sub

Thanks to Tim Hastings for the Base64 functions.

Related posts:

  1. Base64/sexatrigesimal encoding/decoding in VBA/VB6/Visual Basic
  2. Decimal to Binary functions in Visual Basic
  3. Optimizing/faster String Concatenation in VBA

Photoshop VBScript to automatically resize images

Saturday, June 25th, 2011

Decided to learn Photoshop VBScripting, don’t know why I didn’t do this sooner, I now have scripts to automatically generate my blog thumbnails (as below), and add little Google Maps markers on them (see here).

A few constants to change in the script (edit with Notepad);

  • RESIZEWIDTH – thumbnail width
  • RESIZEHEIGHT – thumbnail height
  • IGNOREVERTICAL – should vertical (portrait0 images be ignored (I like to do these manually as I crop them to landscape)
  • SUFFIX – thumbnail suffix

To run it, simply place the script in your image folder (make sure to take a backup) and execute the file.
auto-resize-images-v0.1.vbs

Public Const RESIZEWIDTH = 150
Public Const RESIZEHEIGHT = 113

Public Const IGNOREVERTICAL = True
Public Const SUFFIX = "-th"

Dim spath
spath = Mid(WScript.ScriptFullName, 1, InStrRev(WScript.ScriptFullName, "\", -1, vbBinaryCompare))

Dim fso
Set fso = CreateObject("Scripting.FileSystemObject")

Dim foldero
Set foldero = fso.GetFolder(spath)

Dim fileo
Dim sfile

For Each fileo In foldero.Files
    'only modify jpg files
    sfile = fileo.Name
    If InStrRev(sfile, ".jpg", -1, vbTextCompare) = Len(sfile) - 3 Then
        resize spath & sfile
    End If
Next

MsgBox "Complete."

Sub resize(sfilename)

    Set WshShell = WScript.CreateObject("WScript.Shell")
    Set colProcessList = GetObject("Winmgmts:").ExecQuery("Select * from Win32_Process")

    Dim found
    found = False

    For Each objProcess In colProcessList
        If StrComp(objProcess.Name, "photoshop.exe", vbTextCompare) = 0 Then
            found = True
            Exit For
        End If
    Next

    Dim appRef
    If found Then
        Set appRef = GetObject(, "Photoshop.Application")
    Else
        Set appRef = CreateObject("Photoshop.Application")
    End If

    Do While appRef.documents.Count
       appRef.activeDocument.Close 2 'dont' save
    Loop

    Dim originalRulerUnits
    originalRulerUnits = appRef.Preferences.RulerUnits
    appRef.Preferences.RulerUnits = 1 'pixels

    Dim docRef
    Set docRef = appRef.Open(sfilename)

    Dim modified
    modified = False

    If docRef.Width >= docRef.Height Then 'horizontal photo
            If docRef.Width <> RESIZEWIDTH Then 'proceed if not already resized
                docRef.ResizeImage RESIZEWIDTH 'preserves aspect ratio
                modified = True
            End If
    Else 'verticle photo
        If Not IGNOREVERTICAL Then 'proceed
            If docRef.Height <> RESIZEHEIGHT Then 'proceed if not already resized
                docRef.ResizeImage , RESIZEHEIGHT 'preserves aspect ratio
                modified = True
            End If
        End If
    End If

    If modified Then 'only save if the image was modified
        Dim jpgSaveOptions
        Set jpgSaveOptions = CreateObject("Photoshop.JPEGSaveOptions")
        jpgSaveOptions.Quality = 8

        'calculate the new file name
        Dim newfilename
        newfilename = Mid(sfilename, 1, Len(sfilename) - 4) & SUFFIX & ".jpg"

        docRef.SaveAs newfilename, jpgSaveOptions, True, 2 'for psLowercase
    End If

    docRef.Close 2 'dont' save

    appRef.Preferences.RulerUnits = originalRulerUnits

End Sub

Related posts:

  1. Simple Ping function VBScript
  2. Rigid file manipulation functions for VBA/VBS
  3. VBA automatically saves Excel 2003 Workbook in compatibility mode as Excel 2007 Workbook

Ultimate Google Maps XML JavaScript function

Wednesday, March 16th, 2011

I believe I have come up with the most versatile Google Maps function. Parameters are Dev ID name (devid), XML location (xml), zoom and map type (zoom).

To use it you will need to do the following;

Script header:

<script type='text/javascript' src='http://maps.google.com/maps/api/js?sensor=false'></script>

DIV in the body:

<div id='map484524264' style='width: 450px; height: 345px'></div>
<script type='text/javascript'>
google.maps.event.addDomListener(window,'load', function() {thydzikgm('map484524264','http://thydzik.info/example2.xml',-1,'ROADMAP');});
</script>

XML in the following form:

<markers>
<!-- Marker Z has no html to show nonclickability-->
<marker lat="-31.9554" lng="115.85859"  icon="Z" color="c89bff"/>
<marker lat="-32.053128" lng="115.745869" html="Fremantle"  icon="1" color="6b98ff"/>
<!-- Standard marker with html-->
<marker lat="-32.036036" lng="115.92724" html="Lynwood&lt;br&gt;Residence of the author" color="ffed5c"/>
<marker lat="-31.963013" lng="115.836239" html="Kings Park" icon="KP" color="97ec7d"/>
<!-- Character marker with html that includes link-->
<marker lat="-31.956659" lng="115.869906" html="&lt;a href=&quot;http://perthmint.com.au&quot; rel=&quot;nofollow&quot;&gt;Perth Mint&lt;/a&gt;" icon="$" color="ffffff"/>
<!-- Example of two lines-->
<line colour="#0000FF" width="2" opacity="0.75">
	<point lat="-32.027579" lng="115.751266" />
	<point lat="-31.987404" lng="115.769463" />
	<point lat="-31.957697" lng="115.852203" />
	<point lat="-31.963814" lng="115.879326" />
	<point lat="-32.026415" lng="115.942154" />
</line>
<points colour="#FF0000" width="4" opacity="0.75">
	<point lat="-32.053128" lng="115.745869" />
	<point lat="-31.963013" lng="115.836239" />
	<point lat="-31.9554" lng="115.85859" />
	<point lat="-31.956659" lng="115.869906" />
	<point lat="-32.036036" lng="115.92724" />
</points>
</markers>

And the JavaScript code:

function thydzikgm(devid, xml, zoom, type) {
	var bounds = new google.maps.LatLngBounds();

	var map = new google.maps.Map(document.getElementById(devid));
	eval("map.setMapTypeId(google.maps.MapTypeId."+type+")");

	var icons = []; //initiate array of icons
	var infowindow = new google.maps.InfoWindow();
	var shadow = new google.maps.MarkerImage("https://chart.googleapis.com/chart?chst=d_map_pin_shadow", new google.maps.Size(40, 37), null, new google.maps.Point(10, 37));
	var size = new google.maps.Size(21, 34);
    jQuery.get(xml, function(data) {
		jQuery(data).find("marker").each(function() {
			var lat = jQuery(this).attr("lat");
			var lng = jQuery(this).attr("lng");
			if (lat && lng) {
				var latlng = new google.maps.LatLng(parseFloat(lat),parseFloat(lng));
				bounds.extend(latlng);

				var text = (jQuery(this).attr("icon") || "").replace("Marker.png","").substring(0, 2) || "%e2%bc%80"; //closest to a default dot symbol
				var colour = jQuery(this).attr("colour") || jQuery(this).attr("color") || "ff776b"; //google default red colour
				var key = text+colour; //text can never be a hex colour
				if (!icons[key]) {
					icons[key] = new google.maps.MarkerImage("https://chart.googleapis.com/chart?chst=d_map_pin_letter&chld="+text+"|"+colour+"|000000&.png", size);
				}
				var marker = new google.maps.Marker({
					position: latlng,
					icon: icons[key],
					map: map,
					shadow: shadow
				});

				var html = jQuery(this).attr("html");
				if (html) {
					var xml_path = xml.substr(0,xml.lastIndexOf("/")+1);
					html = html.replace(html.match(/href='(?!(http|ftp))/ig), "href='"+xml_path);
					html = html.replace(html.match(/href="(?!(http|ftp))/ig), 'href="'+xml_path);
					html = html.replace(html.match(/src='(?!(http|ftp))/ig), "src='"+xml_path);
					html = html.replace(html.match(/src="(?!(http|ftp))/ig), 'src="'+xml_path);
					google.maps.event.addListener(marker, 'click', function() {
						infowindow.setContent(html);
						infowindow.open(map, marker);
					});
				} else {
					marker.setClickable(false);
				}
			}
		});
		jQuery.each(["line","points"], function() {
			jQuery(data).find(String(this)).each(function() {
				var latlng_arr = [];
				var colour = jQuery(this).attr("colour") || jQuery(this).attr("color") || "0000ff";
				if (colour.charAt(0)!=="#") {
					colour = "#"+colour;
				}

				jQuery(this).find("point").each(function() {
					var lat = jQuery(this).attr("lat");
					var lng = jQuery(this).attr("lng");
					if (lat && lng) {
						var latlng = new google.maps.LatLng(parseFloat(lat),parseFloat(lng));
						bounds.extend(latlng);
						latlng_arr.push(latlng);
					}
				});
				var line = new google.maps.Polyline({
					path: latlng_arr,
					strokeColor: colour,
					strokeOpacity: parseFloat(jQuery(this).attr("opacity") || "0.75"),
					strokeWeight: parseFloat(jQuery(this).attr("width") || "4")
				});
				line.setMap(map);
			});
		});
		map.fitBounds(bounds);

		if (zoom !== -1) {
			var listener = google.maps.event.addListener(map, "idle", function() {
				map.setZoom(zoom);
				google.maps.event.removeListener(listener);
			});
		}
		google.maps.event.addListener(map, 'click', function() {
			infowindow.close(map);
		});
    }, "xml");
}

Example map

Related posts:

  1. thydzikGoogleMap v1.5 – an inline Google map plugin for WordPress
  2. Dynamic Google Maps circle markers/icons with PHP
  3. Dynamic Google Maps markers/icons with PHP

Dynamic Google Maps circle markers/icons with PHP

Saturday, March 5th, 2011

A while back I posted on how to create dynamic Google maps markers which allow for any colour and any text in the classic Google map style.

Recently, I have had a need to do the same with circular markers. It uses the ‘Image Smooth Arc‘ function provided by Ulrich Mierendorff.

Similarly, I provide a little demo of some PHP code that does this that I quickly whipped up. Here are some example markers:
DefaultAZ110PQ69%BEΩ$
(Have a look at the image name)

Now that gets a little boring, how about some color:
DefaultAZ110PQ69%BEΩ$
(Again, have a look at the image name)

Again, you will need to download the modified arial font and host it in the same directory.

Have a look at the PHP source code below:

<?php
	include ("imageSmoothArc_optimized.php");

	$color = $_GET['color'];
	if (!$color) {$color = "ff776b";} //default google map color
	$color = str_replace("#", "", $color);
	$string = $_GET['text'];

	$font = realpath('arial.ttf');

	//unfortunately we still must do some offsetting
	switch (ord(substr($string,0,1))) {
		case 49: //1
			$offset = -2;
			break;
		case 55: //7
			$offset = -1;
			break;
		case 65: //A
			$offset = 1;
			break;
		case 74: //J
			$offset = -1;
			break;
		case 84: //T
			$offset = 1;
			break;
		case 99: //c
			$offset = -1;
			break;
		case 106: //j
			$offset = 1;
			break;
	}
	if (strlen($string) == 1) {
		$fontsize = 10.5;
	} else if (strlen($string) == 2) {
		$fontsize = 9;
	} else {
		$fontsize = 10.5;
		$offset = 0; //reset offset
		$string = chr(149);
	}

	$bbox = imagettfbbox($fontsize, 0, $font, $string);
	$width = $bbox[2] - $bbox[0] + 1;
	$height = $bbox[1] - $bbox[7] + 1;

	$im = imagecreatetruecolor(20, 20);

	//add the alpha
	$trans_colour = imagecolorallocatealpha($im, 0, 0, 0, 127);
	imagefill($im, 0, 0, $trans_colour);

	imageAlphaBlending($im, true);
	imageSaveAlpha($im, true);

	$bord_ellipse = array (0, 0, 0, 0);
	imageSmoothArc($im, 9, 10, 17, 17, $bord_ellipse, 0, 2*M_PI); //x, y, width, hegiht

	$fill_ellipse = array (hexdec(substr($color,0,2)), hexdec(substr($color,2,2)), hexdec(substr($color,4,2)), 0);
	imageSmoothArc($im, 9, 10, 16, 16, $fill_ellipse, 0, 2*M_PI); //x, y, width, hegiht

	$black = imagecolorallocate($im, 0, 0, 0);
	imagettftext($im, $fontsize, 0, 11 - $width/2 + $offset, 9 + $height/2, $black, $font, $string);

	header("Content-type: image/png");
	imagepng($im);
	imagedestroy($im);
?>

Related posts:

  1. Dynamic Google Maps markers/icons with PHP
  2. thydzik Google Map v1.4.7 – inline WordPress Google Maps
  3. thydzikGoogleMap – an inline Google map plugin for WordPress

Simple Ping function VBScript

Monday, November 15th, 2010

I was after a ping function that met the following constraints;

  • Didn’t use GetObject.
  • Didn’t display any command (cmd) prompt.
  • Didn’t use a temporary files.

Here is what I found;

<br />
Function ping(node)<br />
    Set WshShell = CreateObject(&quot;WScript.Shell&quot;)<br />
    ping = Not CBool(WshShell.Run(&quot;ping -n 1 &quot; &amp; node, 0, True))<br />
End Function<br />

I was looking at a way to timeout the ping function after 1 second using Threading but this didn’t quite make it so simple. Whilst ping offers a timeout value if you ping an incorrect hostname it will hang for a little while.

Related posts:

  1. Generic file selection window function in VBA
  2. Visual Basic 6 – quickest way to find first/last character in string
  3. Rigid file manipulation functions for VBA/VBS